Search in sources :

Example 1 with PseudoElementSelector

use of com.gargoylesoftware.css.parser.selector.PseudoElementSelector in project htmlunit by HtmlUnit.

the class CSSStyleSheet method selects.

/**
 * Returns {@code true} if the specified selector selects the specified element.
 *
 * @param browserVersion the browser version
 * @param selector the selector to test
 * @param element the element to test
 * @param pseudoElement the pseudo element to match, (can be {@code null})
 * @param fromQuerySelectorAll whether this is called from {@link DomNode#querySelectorAll(String)}
 * @return {@code true} if it does apply, {@code false} if it doesn't apply
 */
public static boolean selects(final BrowserVersion browserVersion, final Selector selector, final DomElement element, final String pseudoElement, final boolean fromQuerySelectorAll) {
    switch(selector.getSelectorType()) {
        case ELEMENT_NODE_SELECTOR:
            final ElementSelector es = (ElementSelector) selector;
            final String name;
            final String elementName;
            if (element.getPage().hasCaseSensitiveTagNames()) {
                name = es.getLocalName();
                elementName = element.getLocalName();
            } else {
                name = es.getLocalNameLowerCase();
                elementName = element.getLowercaseName();
            }
            if (name == null || name.equals(elementName)) {
                final List<Condition> conditions = es.getConditions();
                if (conditions != null) {
                    for (final Condition condition : conditions) {
                        if (!selects(browserVersion, condition, element, fromQuerySelectorAll)) {
                            return false;
                        }
                    }
                }
                return true;
            }
            return false;
        case CHILD_SELECTOR:
            final DomNode parentNode = element.getParentNode();
            if (parentNode == element.getPage()) {
                return false;
            }
            if (!(parentNode instanceof DomElement)) {
                // for instance parent is a DocumentFragment
                return false;
            }
            final ChildSelector cs = (ChildSelector) selector;
            return selects(browserVersion, cs.getSimpleSelector(), element, pseudoElement, fromQuerySelectorAll) && selects(browserVersion, cs.getAncestorSelector(), (DomElement) parentNode, pseudoElement, fromQuerySelectorAll);
        case DESCENDANT_SELECTOR:
            final DescendantSelector ds = (DescendantSelector) selector;
            final SimpleSelector simpleSelector = ds.getSimpleSelector();
            if (selects(browserVersion, simpleSelector, element, pseudoElement, fromQuerySelectorAll)) {
                DomNode ancestor = element;
                if (simpleSelector.getSelectorType() != SelectorType.PSEUDO_ELEMENT_SELECTOR) {
                    ancestor = ancestor.getParentNode();
                }
                final Selector dsAncestorSelector = ds.getAncestorSelector();
                while (ancestor instanceof DomElement) {
                    if (selects(browserVersion, dsAncestorSelector, (DomElement) ancestor, pseudoElement, fromQuerySelectorAll)) {
                        return true;
                    }
                    ancestor = ancestor.getParentNode();
                }
            }
            return false;
        case DIRECT_ADJACENT_SELECTOR:
            final DirectAdjacentSelector das = (DirectAdjacentSelector) selector;
            if (selects(browserVersion, das.getSimpleSelector(), element, pseudoElement, fromQuerySelectorAll)) {
                DomNode prev = element.getPreviousSibling();
                while (prev != null && !(prev instanceof DomElement)) {
                    prev = prev.getPreviousSibling();
                }
                return prev != null && selects(browserVersion, das.getSelector(), (DomElement) prev, pseudoElement, fromQuerySelectorAll);
            }
            return false;
        case GENERAL_ADJACENT_SELECTOR:
            final GeneralAdjacentSelector gas = (GeneralAdjacentSelector) selector;
            if (selects(browserVersion, gas.getSimpleSelector(), element, pseudoElement, fromQuerySelectorAll)) {
                for (DomNode prev1 = element.getPreviousSibling(); prev1 != null; prev1 = prev1.getPreviousSibling()) {
                    if (prev1 instanceof DomElement && selects(browserVersion, gas.getSelector(), (DomElement) prev1, pseudoElement, fromQuerySelectorAll)) {
                        return true;
                    }
                }
            }
            return false;
        case PSEUDO_ELEMENT_SELECTOR:
            if (pseudoElement != null && pseudoElement.length() != 0 && pseudoElement.charAt(0) == ':') {
                final String pseudoName = ((PseudoElementSelector) selector).getLocalName();
                return pseudoName.equals(pseudoElement.substring(1));
            }
            return false;
        default:
            if (LOG.isErrorEnabled()) {
                LOG.error("Unknown CSS selector type '" + selector.getSelectorType() + "'.");
            }
            return false;
    }
}
Also used : Condition(com.gargoylesoftware.css.parser.condition.Condition) ChildSelector(com.gargoylesoftware.css.parser.selector.ChildSelector) SimpleSelector(com.gargoylesoftware.css.parser.selector.SimpleSelector) PseudoElementSelector(com.gargoylesoftware.css.parser.selector.PseudoElementSelector) DescendantSelector(com.gargoylesoftware.css.parser.selector.DescendantSelector) DirectAdjacentSelector(com.gargoylesoftware.css.parser.selector.DirectAdjacentSelector) PseudoElementSelector(com.gargoylesoftware.css.parser.selector.PseudoElementSelector) ElementSelector(com.gargoylesoftware.css.parser.selector.ElementSelector) DomNode(com.gargoylesoftware.htmlunit.html.DomNode) DomElement(com.gargoylesoftware.htmlunit.html.DomElement) GeneralAdjacentSelector(com.gargoylesoftware.css.parser.selector.GeneralAdjacentSelector) DirectAdjacentSelector(com.gargoylesoftware.css.parser.selector.DirectAdjacentSelector) GeneralAdjacentSelector(com.gargoylesoftware.css.parser.selector.GeneralAdjacentSelector) PseudoElementSelector(com.gargoylesoftware.css.parser.selector.PseudoElementSelector) DescendantSelector(com.gargoylesoftware.css.parser.selector.DescendantSelector) SimpleSelector(com.gargoylesoftware.css.parser.selector.SimpleSelector) Selector(com.gargoylesoftware.css.parser.selector.Selector) ElementSelector(com.gargoylesoftware.css.parser.selector.ElementSelector) ChildSelector(com.gargoylesoftware.css.parser.selector.ChildSelector)

Example 2 with PseudoElementSelector

use of com.gargoylesoftware.css.parser.selector.PseudoElementSelector in project LoboEvolution by LoboEvolution.

the class CSS3Parser method pseudo.

// 
// pseudo
// : ':' (':')?
// [ IDENT
// | FUNCTION_NOT S* selector() S* ')'
// | FUNCTION_LANG S* IDENT S* ')'
// | FUNCTION S* ((PLUS | MINUS | DIMENSION | NUMBER | STRING | IDENT)? S*)+ ')'
// ]
// ;
// 
public final Object pseudo(boolean pseudoElementFound) throws ParseException {
    Token t;
    String function;
    String arg;
    boolean doubleColon = false;
    Locator locator;
    try {
        jj_consume_token(COLON);
        locator = createLocator(token);
        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
            case COLON:
                {
                    jj_consume_token(COLON);
                    doubleColon = true;
                    break;
                }
            default:
                jj_la1[81] = jj_gen;
                ;
        }
        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
            case IDENT:
                {
                    t = jj_consume_token(IDENT);
                    String s = unescape(t.image, false);
                    if (pseudoElementFound) {
                        throw toCSSParseException("duplicatePseudo", new String[] { s }, locator);
                    }
                    if ("first-line".equals(s) || "first-letter".equals(s) || "before".equals(s) || "after".equals(s)) {
                        return new PseudoElementSelector(s, locator, doubleColon);
                    }
                    return new PseudoClassCondition(s, locator, doubleColon);
                }
            case FUNCTION_NOT:
                {
                    t = jj_consume_token(FUNCTION_NOT);
                    function = unescape(t.image, false);
                    label_52: while (true) {
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case S:
                                {
                                    ;
                                    break;
                                }
                            default:
                                jj_la1[82] = jj_gen;
                                break label_52;
                        }
                        jj_consume_token(S);
                    }
                    arg = negation_arg();
                    if ("".equals(arg)) {
                        arg = "*";
                    }
                    label_53: while (true) {
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case S:
                                {
                                    ;
                                    break;
                                }
                            default:
                                jj_la1[83] = jj_gen;
                                break label_53;
                        }
                        jj_consume_token(S);
                    }
                    jj_consume_token(RROUND);
                    if (pseudoElementFound) {
                        throw toCSSParseException("duplicatePseudo", new String[] { function + arg + ")" }, locator);
                    }
                    return new PseudoClassCondition(function + arg + ")", locator, doubleColon);
                }
            case FUNCTION_LANG:
                {
                    t = jj_consume_token(FUNCTION_LANG);
                    function = unescape(t.image, false);
                    label_54: while (true) {
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case S:
                                {
                                    ;
                                    break;
                                }
                            default:
                                jj_la1[84] = jj_gen;
                                break label_54;
                        }
                        jj_consume_token(S);
                    }
                    t = jj_consume_token(IDENT);
                    String lang = unescape(t.image, false);
                    label_55: while (true) {
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case S:
                                {
                                    ;
                                    break;
                                }
                            default:
                                jj_la1[85] = jj_gen;
                                break label_55;
                        }
                        jj_consume_token(S);
                    }
                    jj_consume_token(RROUND);
                    if (pseudoElementFound) {
                        throw toCSSParseException("duplicatePseudo", new String[] { "lang(" + lang + ")" }, locator);
                    }
                    return new LangCondition(lang, locator);
                }
            case FUNCTION:
                {
                    t = jj_consume_token(FUNCTION);
                    function = unescape(t.image, false);
                    StringBuilder args = new StringBuilder();
                    label_56: while (true) {
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case S:
                                {
                                    ;
                                    break;
                                }
                            default:
                                jj_la1[86] = jj_gen;
                                break label_56;
                        }
                        jj_consume_token(S);
                    }
                    label_57: while (true) {
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case PLUS:
                                {
                                    t = jj_consume_token(PLUS);
                                    break;
                                }
                            case MINUS:
                                {
                                    t = jj_consume_token(MINUS);
                                    break;
                                }
                            case DIMENSION:
                                {
                                    t = jj_consume_token(DIMENSION);
                                    break;
                                }
                            case NUMBER:
                                {
                                    t = jj_consume_token(NUMBER);
                                    break;
                                }
                            case STRING:
                                {
                                    t = jj_consume_token(STRING);
                                    break;
                                }
                            case IDENT:
                                {
                                    t = jj_consume_token(IDENT);
                                    break;
                                }
                            default:
                                jj_la1[87] = jj_gen;
                                jj_consume_token(-1);
                                throw new ParseException();
                        }
                        args.append(unescape(t.image, false));
                        label_58: while (true) {
                            switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                                case S:
                                    {
                                        ;
                                        break;
                                    }
                                default:
                                    jj_la1[88] = jj_gen;
                                    break label_58;
                            }
                            t = jj_consume_token(S);
                            args.append(unescape(t.image, false));
                        }
                        switch((jj_ntk == -1) ? jj_ntk_f() : jj_ntk) {
                            case NUMBER:
                            case IDENT:
                            case STRING:
                            case MINUS:
                            case PLUS:
                            case DIMENSION:
                                {
                                    ;
                                    break;
                                }
                            default:
                                jj_la1[89] = jj_gen;
                                break label_57;
                        }
                    }
                    jj_consume_token(RROUND);
                    if (pseudoElementFound) {
                        throw toCSSParseException("duplicatePseudo", new String[] { function + args.toString().trim() + ")" }, locator);
                    }
                    return new PseudoClassCondition(function + args.toString().trim() + ")", locator, doubleColon);
                }
            default:
                jj_la1[90] = jj_gen;
                jj_consume_token(-1);
                throw new ParseException();
        }
    } catch (ParseException e) {
        throw toCSSParseException("invalidPseudo", e);
    }
}
Also used : Locator(com.gargoylesoftware.css.parser.Locator) PseudoClassCondition(com.gargoylesoftware.css.parser.condition.PseudoClassCondition) PseudoElementSelector(com.gargoylesoftware.css.parser.selector.PseudoElementSelector) CSSParseException(com.gargoylesoftware.css.parser.CSSParseException) LangCondition(com.gargoylesoftware.css.parser.condition.LangCondition)

Aggregations

PseudoElementSelector (com.gargoylesoftware.css.parser.selector.PseudoElementSelector)2 CSSParseException (com.gargoylesoftware.css.parser.CSSParseException)1 Locator (com.gargoylesoftware.css.parser.Locator)1 Condition (com.gargoylesoftware.css.parser.condition.Condition)1 LangCondition (com.gargoylesoftware.css.parser.condition.LangCondition)1 PseudoClassCondition (com.gargoylesoftware.css.parser.condition.PseudoClassCondition)1 ChildSelector (com.gargoylesoftware.css.parser.selector.ChildSelector)1 DescendantSelector (com.gargoylesoftware.css.parser.selector.DescendantSelector)1 DirectAdjacentSelector (com.gargoylesoftware.css.parser.selector.DirectAdjacentSelector)1 ElementSelector (com.gargoylesoftware.css.parser.selector.ElementSelector)1 GeneralAdjacentSelector (com.gargoylesoftware.css.parser.selector.GeneralAdjacentSelector)1 Selector (com.gargoylesoftware.css.parser.selector.Selector)1 SimpleSelector (com.gargoylesoftware.css.parser.selector.SimpleSelector)1 DomElement (com.gargoylesoftware.htmlunit.html.DomElement)1 DomNode (com.gargoylesoftware.htmlunit.html.DomNode)1