#@selector

    CSS-style queries against a DOM tree. Supports tag, class, id, attribute, compound, descendant/child combinators, selector lists, and the common pseudo-classes.

    The examples below are mbt check blocks and run as part of moon test selector.

    #Query vs match vs root

    query and query_one return matching descendants of the node you pass — the root itself is not considered. To test the root, use matches.

    ///|
    test "readme selector descendants only" {
    let div = @dom.element("div", attrs={ "id": Some("r") }, children=[
    @dom.element("p", attrs={ "class": Some("hit") }),
    @dom.element("p"),
    ])
    debug_inspect(
    (
    @selector.query(div, "p").length(), // descendants
    @selector.query(div, "#r").length(), // root excluded
    @selector.matches(div, "#r"), // root included
    ),
    content=(
    #|(2, 0, true)
    ),
    )
    }

    #Selector grammar at a glance

    ///|
    test "readme selector grammar" {
    let div = @dom.element("div", children=[
    @dom.element("p", attrs={ "class": Some("intro lede") }, children=[
    @dom.text("first"),
    ]),
    @dom.element("p", attrs={ "class": Some("intro") }, children=[
    @dom.text("second"),
    ]),
    @dom.element("p", children=[@dom.text("third")]),
    ])
    // Tag, class, attribute presence, compound (tag+class), and list.
    debug_inspect(
    (
    @selector.query(div, "p").length(),
    @selector.query(div, ".intro").length(),
    @selector.query(div, "[class]").length(),
    @selector.query(div, "p.intro.lede").length(),
    @selector.query(div, "p.lede, p:not(.intro)").length(),
    ),
    content=(
    #|(3, 2, 2, 1, 2)
    ),
    )
    }

    #Validating a selector before using it

    is_valid runs the parser without touching any DOM — useful for sanitizing user-supplied selectors.

    ///|
    test "readme is_valid" {
    debug_inspect(
    (@selector.is_valid("p.intro"), @selector.is_valid("p..bad")),
    content=(
    #|(true, false)
    ),
    )
    }

    #Budgeted matching

    matches_with_limits raises SelectorError when a selector or its match work exceeds the budget you pass — useful when the selector comes from untrusted input.

    match @selector.matches_with_limits(node, sel, @selector.SelectorLimits())
    catch {
    err => log("rejected: \{err}")
    }

    SelectorLimits

    pub(all) struct SelectorLimits {
    max_match_depth : Int
    max_length : Int
    max_list_items : Int
    max_compound_simple_selectors : Int
    max_complex_selector_parts : Int
    max_parse_depth : Int
    max_match_steps : Int
    max_match_bytes : Int
    } derive(Eq,
    Debug
    )

    Resource limits used while parsing and matching CSS selectors.

    Limits are defensive bounds for selector length, nesting, list size, and match cost. Negative match budgets are treated as exhausted.

    SelectorLimits::SelectorLimits

    fn SelectorLimits::SelectorLimits(max_match_depth? : Int, max_length? : Int, max_list_items? : Int, max_compound_simple_selectors? : Int, max_complex_selector_parts? : Int, max_parse_depth? : Int, max_match_steps? : Int, max_match_bytes? : Int) -> SelectorLimits

    Construct selector limits, using conservative defaults for omitted values.

    SelectorLimits::equal

    #deprecated("implicit derived-impl promotion; call the trait method directly")
    fn SelectorLimits::equal(SelectorLimits, SelectorLimits) -> Bool

    SelectorLimits::not_equal

    #deprecated("implicit derived-impl promotion; call the trait method directly")
    fn SelectorLimits::not_equal(x : SelectorLimits, y : SelectorLimits) -> Bool

    SelectorLimits::to_repr

    #deprecated("implicit derived-impl promotion; call the trait method directly")
    fn SelectorLimits::to_repr(SelectorLimits) ->
    Repr

    is_valid

    fn is_valid(selector : StringView) -> Bool

    Return whether a CSS selector parses as a non-empty selector list.

    matches

    fn matches(node :
    Node
    , selector : StringView) -> Bool

    Return whether node itself matches a CSS selector.

    matches_with_limits

    fn matches_with_limits(node :
    Node
    , selector : StringView, limits : SelectorLimits) -> Bool raise
    HtmlError

    Test whether node matches a selector under explicit resource limits.

    The selector is validated against limits before matching. Invalid selectors return false; selectors that exceed configured depth, length, or match-budget limits raise HtmlError.

    query

    Return all descendants of root that match a CSS selector.

    query_one

    fn query_one(root :
    Node
    , selector : StringView) ->
    Node
    ?

    Return the first descendant of root that matches a CSS selector.