Search in sources :

Example 1 with Selector

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

the class DomNode method closest.

/**
 * @param selectorString the selector to test
 * @return true if the element would be selected by the specified selector string; otherwise, returns false.
 */
public DomElement closest(final String selectorString) {
    try {
        final BrowserVersion browserVersion = getPage().getWebClient().getBrowserVersion();
        final SelectorList selectorList = getSelectorList(selectorString, browserVersion);
        DomNode current = this;
        if (selectorList != null) {
            do {
                for (final Selector selector : selectorList) {
                    final DomElement elem = (DomElement) current;
                    if (CSSStyleSheet.selects(browserVersion, selector, elem, null, true)) {
                        return elem;
                    }
                }
                do {
                    current = current.getParentNode();
                } while (current != null && !(current instanceof DomElement));
            } while (current != null);
        }
        return null;
    } catch (final IOException e) {
        throw new CSSException("Error parsing CSS selectors from '" + selectorString + "': " + e.getMessage());
    }
}
Also used : SelectorList(com.gargoylesoftware.css.parser.selector.SelectorList) CSSException(com.gargoylesoftware.css.parser.CSSException) IOException(java.io.IOException) BrowserVersion(com.gargoylesoftware.htmlunit.BrowserVersion) Selector(com.gargoylesoftware.css.parser.selector.Selector)

Example 2 with Selector

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

the class CSSStyleSheet2Test method selects_miscSelectors.

/**
 * @throws Exception if the test fails
 */
@Test
public void selects_miscSelectors() throws Exception {
    final String html = "<html><head><title>test</title>\n" + "</head><body><style></style>\n" + "<form name='f1' action='foo' class='yui-log'>\n" + "<div><div><input name='i1' id='m1'></div></div>\n" + "<input name='i2' class='yui-log'>\n" + "<button name='b1' class='yui-log'>\n" + "<button name='b2'>\n" + "</form>\n" + "</body></html>";
    final HtmlPage page = loadPage(html);
    final HtmlElement body = page.getBody();
    final HtmlForm form = page.getFormByName("f1");
    final HtmlInput input1 = (HtmlInput) page.getElementsByName("i1").get(0);
    final HtmlInput input2 = (HtmlInput) page.getElementsByName("i2").get(0);
    final DomElement button1 = page.getElementsByName("b1").get(0);
    final DomElement button2 = page.getElementsByName("b2").get(0);
    final BrowserVersion browserVersion = getBrowserVersion();
    final HtmlStyle node = (HtmlStyle) page.getElementsByTagName("style").item(0);
    final HTMLStyleElement host = (HTMLStyleElement) node.getScriptableObject();
    final CSSStyleSheet sheet = host.getSheet();
    Selector selector = parseSelector(sheet, "*.yui-log input");
    assertFalse(CSSStyleSheet.selects(browserVersion, selector, body, null, false));
    assertFalse(CSSStyleSheet.selects(browserVersion, selector, form, null, false));
    assertTrue(CSSStyleSheet.selects(browserVersion, selector, input1, null, false));
    assertTrue(CSSStyleSheet.selects(browserVersion, selector, input2, null, false));
    assertFalse(CSSStyleSheet.selects(browserVersion, selector, button1, null, false));
    assertFalse(CSSStyleSheet.selects(browserVersion, selector, button2, null, false));
    selector = parseSelector(sheet, "#m1");
    assertTrue(CSSStyleSheet.selects(browserVersion, selector, input1, null, false));
    assertFalse(CSSStyleSheet.selects(browserVersion, selector, input2, null, false));
}
Also used : DomElement(com.gargoylesoftware.htmlunit.html.DomElement) HtmlForm(com.gargoylesoftware.htmlunit.html.HtmlForm) HtmlStyle(com.gargoylesoftware.htmlunit.html.HtmlStyle) HTMLStyleElement(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLStyleElement) HtmlPage(com.gargoylesoftware.htmlunit.html.HtmlPage) HtmlElement(com.gargoylesoftware.htmlunit.html.HtmlElement) HtmlInput(com.gargoylesoftware.htmlunit.html.HtmlInput) BrowserVersion(com.gargoylesoftware.htmlunit.BrowserVersion) Selector(com.gargoylesoftware.css.parser.selector.Selector) Test(org.junit.Test)

Example 3 with Selector

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

the class CSSStyleSheet method index.

private void index(final CSSStyleSheetImpl.CSSStyleSheetRuleIndex index, final CSSRuleListImpl ruleList, final Set<String> alreadyProcessing) {
    for (final AbstractCSSRuleImpl rule : ruleList.getRules()) {
        if (rule instanceof CSSStyleRuleImpl) {
            final CSSStyleRuleImpl styleRule = (CSSStyleRuleImpl) rule;
            final SelectorList selectors = styleRule.getSelectors();
            for (final Selector selector : selectors) {
                final SimpleSelector simpleSel = selector.getSimpleSelector();
                if (SelectorType.ELEMENT_NODE_SELECTOR == simpleSel.getSelectorType()) {
                    final ElementSelector es = (ElementSelector) simpleSel;
                    boolean wasClass = false;
                    final List<Condition> conds = es.getConditions();
                    if (conds != null && conds.size() == 1) {
                        final Condition c = conds.get(0);
                        if (ConditionType.CLASS_CONDITION == c.getConditionType()) {
                            index.addClassSelector(es, c.getValue(), selector, styleRule);
                            wasClass = true;
                        }
                    }
                    if (!wasClass) {
                        index.addElementSelector(es, selector, styleRule);
                    }
                } else {
                    index.addOtherSelector(selector, styleRule);
                }
            }
        } else if (rule instanceof CSSImportRuleImpl) {
            final CSSImportRuleImpl importRule = (CSSImportRuleImpl) rule;
            final CSSStyleSheet sheet = getImportedStyleSheet(importRule);
            if (!alreadyProcessing.contains(sheet.getUri())) {
                final CSSRuleListImpl sheetRuleList = sheet.getWrappedSheet().getCssRules();
                alreadyProcessing.add(sheet.getUri());
                final MediaListImpl mediaList = importRule.getMedia();
                if (mediaList.getLength() == 0 && index.getMediaList().getLength() == 0) {
                    index(index, sheetRuleList, alreadyProcessing);
                } else {
                    index(index.addMedia(mediaList), sheetRuleList, alreadyProcessing);
                }
            }
        } else if (rule instanceof CSSMediaRuleImpl) {
            final CSSMediaRuleImpl mediaRule = (CSSMediaRuleImpl) rule;
            final MediaListImpl mediaList = mediaRule.getMediaList();
            if (mediaList.getLength() == 0 && index.getMediaList().getLength() == 0) {
                index(index, mediaRule.getCssRules(), alreadyProcessing);
            } else {
                index(index.addMedia(mediaList), mediaRule.getCssRules(), alreadyProcessing);
            }
        }
    }
}
Also used : AbstractCSSRuleImpl(com.gargoylesoftware.css.dom.AbstractCSSRuleImpl) Condition(com.gargoylesoftware.css.parser.condition.Condition) SimpleSelector(com.gargoylesoftware.css.parser.selector.SimpleSelector) PseudoElementSelector(com.gargoylesoftware.css.parser.selector.PseudoElementSelector) ElementSelector(com.gargoylesoftware.css.parser.selector.ElementSelector) MediaListImpl(com.gargoylesoftware.css.dom.MediaListImpl) CSSMediaRuleImpl(com.gargoylesoftware.css.dom.CSSMediaRuleImpl) CSSStyleRuleImpl(com.gargoylesoftware.css.dom.CSSStyleRuleImpl) SelectorList(com.gargoylesoftware.css.parser.selector.SelectorList) 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) CSSImportRuleImpl(com.gargoylesoftware.css.dom.CSSImportRuleImpl) CSSRuleListImpl(com.gargoylesoftware.css.dom.CSSRuleListImpl)

Example 4 with Selector

use of com.gargoylesoftware.css.parser.selector.Selector 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 5 with Selector

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

the class ElementImpl method querySelector.

/**
 * {@inheritDoc}
 */
@Override
public Element querySelector(String selectors) {
    SelectorList selectorList = CSSUtilities.getSelectorList(selectors);
    List<Element> elem = new ArrayList<>();
    if (selectorList != null) {
        NodeListImpl childNodes = (NodeListImpl) getDescendents(new ElementFilter(null), true);
        childNodes.forEach(child -> {
            for (Selector selector : selectorList) {
                if (child instanceof Element && StyleSheetAggregator.selects(selector, child, null)) {
                    elem.add((Element) child);
                }
            }
        });
    }
    return elem.size() > 0 ? elem.get(0) : null;
}
Also used : NodeListImpl(org.loboevolution.html.dom.nodeimpl.NodeListImpl) SelectorList(com.gargoylesoftware.css.parser.selector.SelectorList) HTMLBodyElement(org.loboevolution.html.dom.HTMLBodyElement) ElementFilter(org.loboevolution.html.dom.filter.ElementFilter) Selector(com.gargoylesoftware.css.parser.selector.Selector)

Aggregations

Selector (com.gargoylesoftware.css.parser.selector.Selector)14 SelectorList (com.gargoylesoftware.css.parser.selector.SelectorList)8 BrowserVersion (com.gargoylesoftware.htmlunit.BrowserVersion)6 ChildSelector (com.gargoylesoftware.css.parser.selector.ChildSelector)4 DescendantSelector (com.gargoylesoftware.css.parser.selector.DescendantSelector)4 DirectAdjacentSelector (com.gargoylesoftware.css.parser.selector.DirectAdjacentSelector)4 ElementSelector (com.gargoylesoftware.css.parser.selector.ElementSelector)4 GeneralAdjacentSelector (com.gargoylesoftware.css.parser.selector.GeneralAdjacentSelector)4 PseudoElementSelector (com.gargoylesoftware.css.parser.selector.PseudoElementSelector)4 SimpleSelector (com.gargoylesoftware.css.parser.selector.SimpleSelector)4 NodeListImpl (org.loboevolution.html.dom.nodeimpl.NodeListImpl)4 CSSException (com.gargoylesoftware.css.parser.CSSException)3 HtmlPage (com.gargoylesoftware.htmlunit.html.HtmlPage)3 HtmlStyle (com.gargoylesoftware.htmlunit.html.HtmlStyle)3 HTMLStyleElement (com.gargoylesoftware.htmlunit.javascript.host.html.HTMLStyleElement)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 DOMException (com.gargoylesoftware.css.dom.DOMException)2 Condition (com.gargoylesoftware.css.parser.condition.Condition)2 DomElement (com.gargoylesoftware.htmlunit.html.DomElement)2