From: <rb...@us...> - 2017-12-31 11:20:03
|
Revision: 15052 http://sourceforge.net/p/htmlunit/code/15052 Author: rbri Date: 2017-12-31 11:20:00 +0000 (Sun, 31 Dec 2017) Log Message: ----------- CSSStyleSheet#addRule fixed return value when simulating ie CSSStyleSheet#insertRule improved error handling 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/css/CSSStyleSheet.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheetTest.java Modified: trunk/htmlunit/src/changes/changes.xml =================================================================== --- trunk/htmlunit/src/changes/changes.xml 2017-12-30 20:13:13 UTC (rev 15051) +++ trunk/htmlunit/src/changes/changes.xml 2017-12-31 11:20:00 UTC (rev 15052) @@ -12,6 +12,12 @@ JavaScript: CSSStyleSheet#addRule fixed error handling </action> <action type="fix" dev="rbri"> + JavaScript: CSSStyleSheet#addRule fixed return value when simulating ie + </action> + <action type="fix" dev="rbri"> + JavaScript: CSSStyleSheet#insertRule improved error handling + </action> + <action type="fix" dev="rbri"> JavaScript: CSSStyleDeclaration#cssText throws an NPE when in stylesheet mode </action> <action type="fix" dev="rbri"> Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2017-12-30 20:13:13 UTC (rev 15051) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java 2017-12-31 11:20:00 UTC (rev 15052) @@ -1509,6 +1509,13 @@ STRING_TRIM_LEFT_RIGHT, /** + * Method addRule returns the rule position instead of -1. + * (href empty) is null. + */ + @BrowserFeature(IE) + STYLESHEET_ADD_RULE_RETURNS_POS, + + /** * Indicates that the href property for a <link rel="stylesheet" type="text/css" href="" /> * (href empty) is null. */ 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-12-30 20:13:13 UTC (rev 15051) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java 2017-12-31 11:20:00 UTC (rev 15052) @@ -18,6 +18,7 @@ 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; +import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STYLESHEET_ADD_RULE_RETURNS_POS; import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STYLESHEET_HREF_EMPTY_IS_NULL; import static com.gargoylesoftware.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED; import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME; @@ -1106,6 +1107,19 @@ return result; } catch (final DOMException e) { + // in case of error try with an empty rule + final int pos = rule.indexOf('{'); + if (pos > -1) { + final String newRule = rule.substring(0, pos) + "{}"; + try { + final int result = wrapped_.insertRule(newRule, fixIndex(position)); + refreshCssRules(); + return result; + } + catch (final DOMException ex) { + throw Context.throwAsScriptRuntimeEx(ex); + } + } throw Context.throwAsScriptRuntimeEx(e); } } @@ -1186,7 +1200,6 @@ // in case of error try with an empty rule completeRule = selector + " {}"; try { - initCssRules(); wrapped_.insertRule(completeRule, wrapped_.getCssRules().getLength()); refreshCssRules(); } @@ -1194,6 +1207,9 @@ throw Context.throwAsScriptRuntimeEx(ex); } } + if (getBrowserVersion().hasFeature(STYLESHEET_ADD_RULE_RETURNS_POS)) { + return wrapped_.getCssRules().getLength() - 1; + } return -1; } Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheetTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheetTest.java 2017-12-30 20:13:13 UTC (rev 15051) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheetTest.java 2017-12-31 11:20:00 UTC (rev 15052) @@ -191,27 +191,30 @@ * @throws Exception if an error occurs */ @Test - @Alerts(DEFAULT = {"1", "false", "false", "0", "2", "p", "vertical-align: top;"}, - FF = {"1", "false", "true", "0", "2", "p", "vertical-align: top;"}) - public void addRule_insertRule() throws Exception { - final String html = "<html><head><title>foo</title><script>\n" - + "function doTest() {\n" - + " var f = document.getElementById('myStyle');\n" - + " var s = f.sheet ? f.sheet : f.styleSheet;\n" - + " var rules = s.cssRules || s.rules;\n" - + " alert(rules.length);\n" - + " alert(s.insertRule == undefined);\n" - + " alert(s.addRule == undefined);\n" - + " if (s.insertRule)\n" - + " alert(s.insertRule('div { color: red; }', 0));\n" - + " else\n" - + " alert(s.addRule('div', 'color: red;'));\n" - + " alert(rules.length);\n" - + " alert(rules[1].selectorText);\n" - + " alert(rules[1].style.cssText);\n" - + "}</script>\n" + @Alerts(DEFAULT = {"1", "false", "-1", "div", "color: red;", "2"}, + IE = {"1", "false", "1", "div", "color: red;", "2"}, + FF = {"1", "true", "1"}) + public void addRule() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + "<script>\n" + + " function doTest() {\n" + + " var f = document.getElementById('myStyle');\n" + + " var s = f.sheet ? f.sheet : f.styleSheet;\n" + + " var rules = s.cssRules || s.rules;\n" + + " alert(rules.length);\n" + + " alert(s.addRule == undefined);\n" + + " if (s.addRule) {\n" + + " alert(s.addRule('div', 'color: red;'));\n" + + " alert(rules[rules.length - 1].selectorText);\n" + + " alert(rules[rules.length - 1].style.cssText);\n" + + " }\n" + + " alert(rules.length);\n" + + " }\n" + + "</script>\n" + "<style id='myStyle'>p { vertical-align:top }</style>\n" - + "</head><body onload='doTest()'>\n" + + "</head>\n" + + "<body onload='doTest()'>\n" + "</body></html>"; loadPageWithAlerts2(html); @@ -218,13 +221,12 @@ } /** - * Minimal test for addRule / insertRule. * @throws Exception if an error occurs */ @Test - @Alerts(DEFAULT = {"1", "-1", "div", "", "2"}, - IE = {"1", "1", "div", "", "2"}, - FF = {"1", "1"}) + @Alerts(DEFAULT = {"2", "-1", "div", "", "3"}, + IE = {"2", "2", "div", "", "3"}, + FF = {"2", "2"}) public void addRuleInvalidRule() throws Exception { final String html = "<html>\n" + "<head>\n" @@ -242,7 +244,7 @@ + " alert(rules.length);\n" + " }\n" + " </script>\n" - + " <style id='myStyle'>p { vertical-align:top }</style>\n" + + " <style id='myStyle'>p { vertical-align: top } h1 { color: blue; }</style>\n" + "</head>\n" + "<body onload='doTest()'>\n" + "</body></html>"; @@ -251,6 +253,120 @@ } /** + * Test that exception handling in addRule. + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = "exception", + FF = "added") + public void addInvalidRule() throws Exception { + final String html = "<html><head><title>foo</title><script>\n" + + "function doTest() {\n" + + " var f = document.getElementById('myStyle');\n" + + " var s = f.sheet ? f.sheet : f.styleSheet;\n" + + " var rules = s.cssRules || s.rules;\n" + + " try {\n" + + " if (s.addRule)\n" + + " s.addRule('.testStyle1;', '', 1);\n" + + " alert('added');\n" + + " } catch(err) { alert('exception'); }\n" + + "}</script>\n" + + "<style id='myStyle'></style>\n" + + "</head><body onload='doTest()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Minimal test for insertRule. + * @throws Exception if an error occurs + */ + @Test + @Alerts({"1", "false", "0", "div", "color: red;", "2"}) + public void insertRule() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + "<script>\n" + + " function doTest() {\n" + + " var f = document.getElementById('myStyle');\n" + + " var s = f.sheet ? f.sheet : f.styleSheet;\n" + + " var rules = s.cssRules || s.rules;\n" + + " alert(rules.length);\n" + + " alert(s.insertRule == undefined);\n" + + " if (s.insertRule) {\n" + + " alert(s.insertRule('div { color: red; }', 0));\n" + + " alert(rules[0].selectorText);\n" + + " alert(rules[0].style.cssText);\n" + + " }\n" + + " alert(rules.length);\n" + + " }\n" + + "</script>\n" + + "<style id='myStyle'>p { vertical-align:top }</style>\n" + + "</head>\n" + + "<body onload='doTest()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"1", "false", "0", "div", "", "2"}) + public void insertRuleInvalidRule() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + "<script>\n" + + " function doTest() {\n" + + " var f = document.getElementById('myStyle');\n" + + " var s = f.sheet ? f.sheet : f.styleSheet;\n" + + " var rules = s.cssRules || s.rules;\n" + + " alert(rules.length);\n" + + " alert(s.insertRule == undefined);\n" + + " if (s.insertRule) {\n" + + " alert(s.insertRule('div {invalid}', 0));\n" + + " alert(rules[0].selectorText);\n" + + " alert(rules[0].style.cssText);\n" + + " }\n" + + " alert(rules.length);\n" + + " }\n" + + "</script>\n" + + "<style id='myStyle'>p { vertical-align:top }</style>\n" + + "</head>\n" + + "<body onload='doTest()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** + * Test that exception handling in insertRule. + * @throws Exception if an error occurs + */ + @Test + @Alerts("exception") + public void insertInvalidRule() throws Exception { + final String html = "<html><head><title>foo</title><script>\n" + + "function doTest() {\n" + + " var f = document.getElementById('myStyle');\n" + + " var s = f.sheet ? f.sheet : f.styleSheet;\n" + + " var rules = s.cssRules || s.rules;\n" + + " try {\n" + + " if (s.insertRule)\n" + + " s.insertRule('.testStyle1', 0);\n" + + " alert('inserted');\n" + + " } catch(err) { alert('exception'); }\n" + + "}</script>\n" + + "<style id='myStyle'></style>\n" + + "</head><body onload='doTest()'>\n" + + "</body></html>"; + + loadPageWithAlerts2(html); + } + + /** * Minimal test for removeRule / deleteRule. * @throws Exception if an error occurs */ @@ -406,33 +522,6 @@ } /** - * Test that exception handling in insertRule. - * @throws Exception if an error occurs - */ - @Test - @Alerts("exception") - public void insertInvalidRule() throws Exception { - final String html = "<html><head><title>foo</title><script>\n" - + "function doTest() {\n" - + " var f = document.getElementById('myStyle');\n" - + " var s = f.sheet ? f.sheet : f.styleSheet;\n" - + " var rules = s.cssRules || s.rules;\n" - + " try {\n" - + " if (s.insertRule)\n" - + " s.insertRule('.testStyle1', 0);\n" - + " else\n" - + " s.addRule('.testStyle1;', '', 1);\n" - + " alert('inserted');\n" - + " } catch(err) { alert('exception'); }\n" - + "}</script>\n" - + "<style id='myStyle'></style>\n" - + "</head><body onload='doTest()'>\n" - + "</body></html>"; - - loadPageWithAlerts2(html); - } - - /** * @throws Exception on test failure */ @Test |