From: <rb...@us...> - 2017-10-12 18:51:44
|
Revision: 14870 http://sourceforge.net/p/htmlunit/code/14870 Author: rbri Date: 2017-10-12 18:51:42 +0000 (Thu, 12 Oct 2017) Log Message: ----------- selector specificity calculation fixed for selectors using the general sibling combinator (~) Issue 1925 Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet2.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/SelectorSpecificityTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2017-10-10 15:22:04 UTC (rev 14869) +++ trunk/htmlunit/src/changes/changes.xml 2017-10-12 18:51:42 UTC (rev 14870) @@ -8,6 +8,9 @@ <body> <release version="2.28" date="???" description="Bugfixes, Chrome 61, improved Promise impl"> + <action type="fix" dev="rbri" issue="1925"> + Selector specificity calculation fixed for selectors using the general sibling combinator (~). + </action> <action type="fix" dev="rbri" issue="1924" due-to="Colin Alworth"> JavaScript: window.onerror provides now a valid error object. </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java 2017-10-10 15:22:04 UTC (rev 14869) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java 2017-10-12 18:51:42 UTC (rev 14870) @@ -417,22 +417,6 @@ final DomElement element, final String pseudoElement, final boolean fromQuerySelectorAll) { switch (selector.getSelectorType()) { case Selector.SAC_ANY_NODE_SELECTOR: - if (selector instanceof GeneralAdjacentSelectorImpl) { - final SiblingSelector ss = (SiblingSelector) selector; - final Selector ssSelector = ss.getSelector(); - final SimpleSelector ssSiblingSelector = ss.getSiblingSelector(); - for (DomNode prev = element.getPreviousSibling(); prev != null; prev = prev.getPreviousSibling()) { - if (prev instanceof HtmlElement - && selects(browserVersion, ssSelector, (HtmlElement) prev, - pseudoElement, fromQuerySelectorAll) - && selects(browserVersion, ssSiblingSelector, element, - pseudoElement, fromQuerySelectorAll)) { - return true; - } - } - return false; - } - return true; case Selector.SAC_CHILD_SELECTOR: final DomNode parentNode = element.getParentNode(); @@ -478,6 +462,21 @@ return HtmlHtml.TAG_NAME.equalsIgnoreCase(element.getTagName()); case Selector.SAC_DIRECT_ADJACENT_SELECTOR: final SiblingSelector ss = (SiblingSelector) selector; + + if (selector instanceof GeneralAdjacentSelectorImpl) { + final SimpleSelector ssSiblingSelector = ss.getSiblingSelector(); + for (DomNode prev = element.getPreviousSibling(); prev != null; prev = prev.getPreviousSibling()) { + if (prev instanceof HtmlElement + && selects(browserVersion, ss.getSelector(), (HtmlElement) prev, + pseudoElement, fromQuerySelectorAll) + && selects(browserVersion, ssSiblingSelector, element, + pseudoElement, fromQuerySelectorAll)) { + return true; + } + } + return false; + } + DomNode prev = element.getPreviousSibling(); while (prev != null && !(prev instanceof HtmlElement)) { prev = prev.getPreviousSibling(); @@ -1482,11 +1481,6 @@ return isValidSelector(ss.getSelector(), documentMode, domNode) && isValidSelector(ss.getSiblingSelector(), documentMode, domNode); case Selector.SAC_ANY_NODE_SELECTOR: - if (selector instanceof SiblingSelector) { - final SiblingSelector sibling = (SiblingSelector) selector; - return isValidSelector(sibling.getSelector(), documentMode, domNode) - && isValidSelector(sibling.getSiblingSelector(), documentMode, domNode); - } //$FALL-THROUGH$ default: LOG.warn("Unhandled CSS selector type '" + selector.getSelectorType() + "'. Accepting it silently."); Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet2.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet2.java 2017-10-10 15:22:04 UTC (rev 14869) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet2.java 2017-10-12 18:51:42 UTC (rev 14870) @@ -14,6 +14,7 @@ */ package com.gargoylesoftware.htmlunit.javascript.host.css; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLLINK_CHECK_TYPE_FOR_STYLESHEET; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NOT_IN_QUIRKS; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NO_TARGET; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTOR_CSS3_PSEUDO_REQUIRE_ATTACHED_NODE; @@ -538,6 +539,15 @@ if (link != null) { // Use link. request = link.getWebRequest(); + + if (element.getBrowserVersion().hasFeature(HTMLLINK_CHECK_TYPE_FOR_STYLESHEET)) { + final String type = link.getTypeAttribute(); + if (StringUtils.isNotBlank(type) && !"text/css".equals(type)) { + final InputSource source = new InputSource(new StringReader("")); + return new CSSStyleSheet2(element, source, uri); + } + } + // our cache is a bit strange; // loadWebResponse check the cache for the web response // AND also fixes the request url for the following cache lookups @@ -665,20 +675,6 @@ final DomElement element, final String pseudoElement) { switch (selector.getSelectorType()) { case Selector.SAC_ANY_NODE_SELECTOR: - if (selector instanceof GeneralAdjacentSelectorImpl) { - final SiblingSelector ss = (SiblingSelector) selector; - final Selector ssSelector = ss.getSelector(); - final SimpleSelector ssSiblingSelector = ss.getSiblingSelector(); - for (DomNode prev = element.getPreviousSibling(); prev != null; prev = prev.getPreviousSibling()) { - if (prev instanceof HtmlElement - && selects(browserVersion, ssSelector, (HtmlElement) prev) - && selects(browserVersion, ssSiblingSelector, element)) { - return true; - } - } - return false; - } - return true; case Selector.SAC_CHILD_SELECTOR: final DomNode parentNode = element.getParentNode(); @@ -721,6 +717,20 @@ return HtmlHtml.TAG_NAME.equalsIgnoreCase(element.getTagName()); case Selector.SAC_DIRECT_ADJACENT_SELECTOR: final SiblingSelector ss = (SiblingSelector) selector; + + if (selector instanceof GeneralAdjacentSelectorImpl) { + final Selector ssSelector = ss.getSelector(); + final SimpleSelector ssSiblingSelector = ss.getSiblingSelector(); + for (DomNode prev = element.getPreviousSibling(); prev != null; prev = prev.getPreviousSibling()) { + if (prev instanceof HtmlElement + && selects(browserVersion, ssSelector, (HtmlElement) prev) + && selects(browserVersion, ssSiblingSelector, element)) { + return true; + } + } + return false; + } + DomNode prev = element.getPreviousSibling(); while (prev != null && !(prev instanceof HtmlElement)) { prev = prev.getPreviousSibling(); @@ -1136,11 +1146,6 @@ return isValidSelector(ss.getSelector(), documentMode, domNode) && isValidSelector(ss.getSiblingSelector(), documentMode, domNode); case Selector.SAC_ANY_NODE_SELECTOR: - if (selector instanceof SiblingSelector) { - final SiblingSelector sibling = (SiblingSelector) selector; - return isValidSelector(sibling.getSelector(), documentMode, domNode) - && isValidSelector(sibling.getSiblingSelector(), documentMode, domNode); - } default: LOG.warn("Unhandled CSS selector type '" + selector.getSelectorType() + "'. Accepting it silently."); return true; // at least in a first time to break less stuff Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/SelectorSpecificityTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/SelectorSpecificityTest.java 2017-10-10 15:22:04 UTC (rev 14869) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/SelectorSpecificityTest.java 2017-10-12 18:51:42 UTC (rev 14870) @@ -76,6 +76,13 @@ assertTrue(specificy11.compareTo(specificy21) < 0); assertTrue(specificy11.compareTo(specificy100) < 0); } + /** + * @throws Exception if the test fails + */ + @Test + public void selectorSpecifitySiblingCombinator() throws Exception { + selectorSpecifity(".cls ~ p", "0,0,1,1"); + } private SelectorSpecificity selectorSpecifity(final String selector, final String expectedSpecificity) throws Exception { |