From: <rb...@us...> - 2017-06-27 16:29:39
|
Revision: 14636 http://sourceforge.net/p/htmlunit/code/14636 Author: rbri Date: 2017-06-27 16:29:37 +0000 (Tue, 27 Jun 2017) Log Message: ----------- fix window.getComputedStyle() pseudo handling if pseudo param starts with double colon Modified Paths: -------------- trunk/htmlunit/src/changes/changes.xml trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclarationTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2017-06-25 11:24:59 UTC (rev 14635) +++ trunk/htmlunit/src/changes/changes.xml 2017-06-27 16:29:37 UTC (rev 14636) @@ -8,6 +8,9 @@ <body> <release version="2.28" date="???" description="Bugfixes"> + <action type="fix" dev="rbri"> + JavaScript: fix window.getComputedStyle() pseudo handling if pseudo param starts with double colon. + </action> <action type="update" dev="rbri"> We are simulating the 64 bit version of Firefox 52 ESR and CHROME now. </action> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2017-06-25 11:24:59 UTC (rev 14635) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2017-06-27 16:29:37 UTC (rev 14636) @@ -1335,6 +1335,10 @@ @BrowserFeature(IE) JS_WINDOW_CHANGE_OPENER_ONLY_WINDOW_OBJECT, + /** window.getComputedStyle works with pseudo selectors without colon in front. */ + @BrowserFeature(CHROME) + JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON, + /** <code>window.name</code> returns also form fields (e.g. input, textarea). */ @BrowserFeature(IE) JS_WINDOW_FORMFIELDS_ACCESSIBLE_BY_NAME, Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2017-06-25 11:24:59 UTC (rev 14635) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java 2017-06-27 16:29:37 UTC (rev 14636) @@ -15,6 +15,7 @@ package com.gargoylesoftware.htmlunit.javascript.host; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_CHANGE_OPENER_ONLY_WINDOW_OBJECT; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_FORMFIELDS_ACCESSIBLE_BY_NAME; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_FRAMES_ACCESSIBLE_BY_ID; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_FRAME_BY_ID_RETURNS_WINDOW; @@ -1608,7 +1609,8 @@ * that of <tt>element.style</tt>, but the value returned by this method is read-only. * * @param element the element - * @param pseudoElement a string specifying the pseudo-element to match (may be {@code null}) + * @param pseudoElement a string specifying the pseudo-element to match (may be {@code null}); + * e.g. ':before' * @return the computed style */ @JsxFunction @@ -1617,10 +1619,20 @@ throw ScriptRuntime.typeError("parameter 1 is not of type 'Element'"); } final Element e = (Element) element; + + String normalizedPseudo = pseudoElement; + if (normalizedPseudo != null && normalizedPseudo.startsWith("::")) { + normalizedPseudo = normalizedPseudo.substring(1); + } + if (getBrowserVersion().hasFeature(JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON) + && !normalizedPseudo.startsWith(":")) { + normalizedPseudo = ":" + normalizedPseudo; + } + synchronized (computedStyles_) { final Map<String, CSS2Properties> elementMap = computedStyles_.get(e); if (elementMap != null) { - final CSS2Properties style = elementMap.get(pseudoElement); + final CSS2Properties style = elementMap.get(normalizedPseudo); if (style != null) { return style; } @@ -1639,7 +1651,7 @@ if (trace) { LOG.trace("modifyIfNecessary: " + sheet + ", " + style + ", " + e); } - sheet.modifyIfNecessary(style, e, pseudoElement); + sheet.modifyIfNecessary(style, e, normalizedPseudo); } } @@ -1649,7 +1661,7 @@ elementMap = new WeakHashMap<>(); computedStyles_.put(e, elementMap); } - elementMap.put(pseudoElement, style); + elementMap.put(normalizedPseudo, style); } } return style; Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclarationTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclarationTest.java 2017-06-25 11:24:59 UTC (rev 14635) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclarationTest.java 2017-06-27 16:29:37 UTC (rev 14636) @@ -2060,4 +2060,46 @@ + "</body></html>"; loadPageWithAlerts2(html); } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = {"\"@\"", "none", "\"@\"", "\"#\"", "none", "\"#\""}, + CHROME = {"\"@\"", "\"@\"", "\"@\"", "\"#\"", "\"#\"", "\"#\""}, + IE = {"\"@\"", "normal", "\"@\"", "\"#\"", "normal", "\"#\""}) + public void pseudoBefore() throws Exception { + final String html = "<html><head>\n" + + "<style type='text/css'>\n" + + " /* <![CDATA[ */\n" + + " #myDiv:before { content: '@' }\n" + + " #myDiv2::before { content: '#' }\n" + + " /* ]]> */\n" + + "</style>\n" + + "<script>\n" + + " function test() {\n" + + " var node = document.getElementById('myDiv');\n" + + " var style = window.getComputedStyle(node, ':before');\n" + + " alert(style.content);\n" + + " var style = window.getComputedStyle(node, 'before');\n" + + " alert(style.content);\n" + + " var style = window.getComputedStyle(node, '::before');\n" + + " alert(style.content);\n" + + + " node = document.getElementById('myDiv2');\n" + + " var style = window.getComputedStyle(node, ':before');\n" + + " alert(style.content);\n" + + " var style = window.getComputedStyle(node, 'before');\n" + + " alert(style.content);\n" + + " var style = window.getComputedStyle(node, '::before');\n" + + " alert(style.content);\n" + + " }\n" + + "</script>\n" + + "</head>\n" + + "<body onload='test()'>\n" + + " <div id='myDiv' >Test</div>\n" + + " <div id='myDiv2' >Test</div>\n" + + "</body></html>"; + loadPageWithAlerts2(html); + } } |