Beispiel #1
0
def compile_attribute_selector(selector: parser.AttributeSelector):
    name = selector.lower_name
    operator = selector.operator
    value = selector.value and selector.value.lower()

    if operator is None:
        return lambda el: bool(el.attribute(name))
    elif operator == "=":
        return lambda el: el.attribute(name) == value
    elif operator == "~=":
        return lambda el: value in split_whitespace(el.attribute(name))
    elif operator == "^=":
        return lambda el: value and el.attribute(name).startswith(value)
    elif operator == "$=":
        return lambda el: value and el.attribute(name).endswith(value)
    elif operator == "*=":
        return lambda el: value and value in el.attribute(name)
    elif operator == "|=":

        def pipe_equal_matcher(el):
            v = el.attribute(name)
            return v == value or (v and v.startswith(value + "-"))

        return pipe_equal_matcher
    else:
        raise parser.SelectorError("Unknown attribute operator", operator)
Beispiel #2
0
def compile_node(selector):
    """
    Dynamic dispatch selector nodes.

    Default behavior is a deny (no match).
    """
    parser.SelectorError("Unknown selector", selector)
Beispiel #3
0
def compile_pseudo_class_selector(selector: parser.PseudoClassSelector):
    name = selector.name
    if name == "empty":
        return lambda el: not next(el.children(), 0)
    elif name in ("root", "hover", "focus", "active", "drop"):
        return lambda el: name in el.state()
    else:
        raise parser.SelectorError("Unknown pseudo-class", name)
Beispiel #4
0
def compile_functional_pseudo_class_selector(
    selector: parser.FunctionalPseudoClassSelector, ):
    name = selector.name
    if name not in ("has", "is", "not"):
        raise parser.SelectorError("Unknown pseudo-class", name)

    sub_selectors = compile_selector_list(selector.arguments)
    selector.specificity = max(spec for _, spec in sub_selectors)
    if name == "has":
        return lambda el: any(
            any(sel(c) for sel, _ in sub_selectors) for c in descendants(el))
    elif name == "is":
        return lambda el: any(sel(el) for sel, _ in sub_selectors)
    elif name == "not":
        return lambda el: not any(sel(el) for sel, _ in sub_selectors)
Beispiel #5
0
def compile_combined_selector(selector: parser.CombinedSelector):
    left_inside = compile_node(selector.left)
    if selector.combinator == " ":

        def left(el):
            return any(left_inside(e) for e in ancestors(el))

    elif selector.combinator == ">":

        def left(el):
            p = el.parent()
            return p is not None and left_inside(p)

    else:
        raise parser.SelectorError("Unknown combinator", selector.combinator)

    right = compile_node(selector.right)
    return lambda el: right(el) and left(el)