From a3c4e15556caa0d2d1eff2c015c130e3f0b8eaa8 Mon Sep 17 00:00:00 2001 From: Ronald Brill Date: Thu, 15 Aug 2024 13:37:55 +0200 Subject: [PATCH] DOMTokenList toggle() method got some fixes --- src/changes/changes.xml | 3 + .../javascript/host/dom/DOMTokenList.java | 31 +- .../javascript/host/dom/DOMTokenListTest.java | 375 +++++++++++++++--- 3 files changed, 345 insertions(+), 64 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index e385ffaa4b..531918b252 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -15,6 +15,9 @@ core-js: Symbol.unscopables for arrays implemented. + + DOMTokenList toggle() method got some fixes. + DOMTokenList value property added. diff --git a/src/main/java/org/htmlunit/javascript/host/dom/DOMTokenList.java b/src/main/java/org/htmlunit/javascript/host/dom/DOMTokenList.java index b33c7ff98d..5eb63d6788 100644 --- a/src/main/java/org/htmlunit/javascript/host/dom/DOMTokenList.java +++ b/src/main/java/org/htmlunit/javascript/host/dom/DOMTokenList.java @@ -167,7 +167,11 @@ public void remove(final String token) { throw JavaScriptEngine.reportRuntimeError("Empty input not allowed"); } - final List parts = split(getValue()); + final String value = getValue(); + if (value == null) { + return; + } + final List parts = split(value); parts.remove(token); updateAttribute(String.join(" ", parts)); } @@ -195,7 +199,11 @@ public boolean replace(final String oldToken, final String newToken) { throw JavaScriptEngine.reportRuntimeError("newToken contains whitespace"); } - final List parts = split(getValue()); + final String value = getValue(); + if (value == null) { + return false; + } + final List parts = split(value); final int pos = parts.indexOf(oldToken); while (pos == -1) { return false; @@ -213,11 +221,22 @@ public boolean replace(final String oldToken, final String newToken) { */ @JsxFunction public boolean toggle(final String token) { - if (contains(token)) { - remove(token); + if (StringUtils.isEmpty(token)) { + throw JavaScriptEngine.reportRuntimeError("Empty input not allowed"); + } + if (StringUtils.containsAny(token, WHITESPACE_CHARS)) { + throw JavaScriptEngine.reportRuntimeError("token contains whitespace"); + } + + final List parts = split(getValue()); + if (parts.contains(token)) { + parts.remove(token); + updateAttribute(String.join(" ", parts)); return false; } - add(token); + + parts.add(token); + updateAttribute(String.join(" ", parts)); return true; } @@ -236,7 +255,7 @@ public boolean contains(final String token) { throw JavaScriptEngine.reportRuntimeError("Empty input not allowed"); } if (StringUtils.containsAny(token, WHITESPACE_CHARS)) { - throw JavaScriptEngine.reportRuntimeError("Empty input not allowed"); + throw JavaScriptEngine.reportRuntimeError("token contains whitespace"); } final List parts = split(getValue()); diff --git a/src/test/java/org/htmlunit/javascript/host/dom/DOMTokenListTest.java b/src/test/java/org/htmlunit/javascript/host/dom/DOMTokenListTest.java index 3eda6cfaf0..de5dd6abe7 100644 --- a/src/test/java/org/htmlunit/javascript/host/dom/DOMTokenListTest.java +++ b/src/test/java/org/htmlunit/javascript/host/dom/DOMTokenListTest.java @@ -38,7 +38,7 @@ public class DOMTokenListTest extends WebDriverTestCase { * @throws Exception if the test fails */ @Test - @Alerts({"3", "b", "b", "true", "false", "c d"}) + @Alerts({"3", "b", "b", "true", "false", "c d", " "}) public void various() throws Exception { final String html = "\n" + + "\n" + + "\n" + ""; loadPageVerifyTitle2(html); @@ -64,7 +68,7 @@ public void various() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"0", "null", "false", "# removed", ""}) + @Alerts({"0", "null", "false", "# removed", "", " "}) public void noAttribute() throws Exception { final String html = "\n" + + "\n" + + "\n" + ""; loadPageVerifyTitle2(html); @@ -87,7 +94,7 @@ public void noAttribute() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"0", "undefined", "1", "#"}) + @Alerts({"0", "undefined", "1", "#", " "}) public void noAttributeAdd() throws Exception { final String html = "\n" + ""; @@ -958,7 +966,7 @@ public void addStyleCheck() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void removeEmpty() throws Exception { remove("a b", ""); } @@ -967,7 +975,7 @@ public void removeEmpty() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void removeBlank() throws Exception { remove("a b", " "); } @@ -976,7 +984,7 @@ public void removeBlank() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void removeTab() throws Exception { remove("a b", "\t"); } @@ -985,7 +993,7 @@ public void removeTab() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void removeCr() throws Exception { remove("a b", "\\r"); } @@ -994,7 +1002,7 @@ public void removeCr() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void removeNl() throws Exception { remove("a b", "\\n"); } @@ -1003,7 +1011,7 @@ public void removeNl() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "2", "a\\sb", "class\\schanged\\sold:\\sa\\sb"}) + @Alerts({"a\\sb", "2", "2", "a\\sb", "", "class\\schanged\\sold:\\sa\\sb"}) public void removeVt() throws Exception { remove("a b", "\u000B"); } @@ -1012,7 +1020,7 @@ public void removeVt() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"", "0", "0", "", "class\\schanged\\sold:\\s"}) + @Alerts({"", "0", "0", "", "", "class\\schanged\\sold:\\s"}) public void removeFromEmpty() throws Exception { remove("", "a"); } @@ -1021,7 +1029,9 @@ public void removeFromEmpty() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"\\s\\t\\s\\n\\s\\s", "0", "0", "", "class\\schanged\\sold:\\s\\s\\t\\s\\n\\s\\s"}) + @Alerts({"\\s\\t\\s\\n\\s\\s", "0", "0", "", + "", + "class\\schanged\\sold:\\s\\s\\t\\s\\n\\s\\s"}) public void removeFromWhitespace() throws Exception { remove(" \t \r ", "a"); } @@ -1030,7 +1040,7 @@ public void removeFromWhitespace() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "2", "a\\sb", "class\\schanged\\sold:\\sa\\sb"}) + @Alerts({"a\\sb", "2", "2", "a\\sb", "", "class\\schanged\\sold:\\sa\\sb"}) public void removeNotExisting() throws Exception { remove("a b", "c"); } @@ -1039,7 +1049,7 @@ public void removeNotExisting() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb\\sa", "2", "1", "b", "class\\schanged\\sold:\\sa\\sb\\sa"}) + @Alerts({"a\\sb\\sa", "2", "1", "b", "", "class\\schanged\\sold:\\sa\\sb\\sa"}) public void removeDuplicated() throws Exception { remove("a b a", "a"); } @@ -1048,7 +1058,7 @@ public void removeDuplicated() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb\\sa", "2", "exception", "2", "a\\sb\\sa"}) + @Alerts({"a\\sb\\sa", "2", "exception", "2", "a\\sb\\sa", ""}) public void removeElementWithBlank() throws Exception { remove("a b a", "a b"); } @@ -1057,7 +1067,8 @@ public void removeElementWithBlank() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb\\sa\\tb", "2", "exception", "2", "a\\sb\\sa\\tb"}) + @Alerts({"a\\sb\\sa\\tb", "2", "exception", "2", "a\\sb\\sa\\tb", + ""}) public void removeElementWithTab() throws Exception { remove("a b a\tb", "a\tb"); } @@ -1066,7 +1077,7 @@ public void removeElementWithTab() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a", "1", "0", "", "class\\schanged\\sold:\\sa"}) + @Alerts({"a", "1", "0", "", "", "class\\schanged\\sold:\\sa"}) public void removeLast() throws Exception { remove("a", "a"); } @@ -1076,6 +1087,7 @@ public void removeLast() throws Exception { */ @Test @Alerts({"a\\s\\t\\sc\\s\\n\\sd\\s\\se", "4", "3", "a\\sd\\se", + "", "class\\schanged\\sold:\\sa\\s\\t\\sc\\s\\n\\sd\\s\\se"}) public void removeWhitespace() throws Exception { remove("a \t c \n d e", "c"); @@ -1086,13 +1098,46 @@ public void removeWhitespace() throws Exception { */ @Test @Alerts({"a\\sc\\sa\\sc", "2", "1", "a", + "", "class\\schanged\\sold:\\sa\\sc\\sa\\sc"}) public void removeNormalizes() throws Exception { remove("a c a c", "c"); } + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"c", "1", "0", "", + "", + "class\\schanged\\sold:\\sc"}) + public void removeAll() throws Exception { + remove("c", "c"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "0", "", + "", + "class\\schanged\\sold:\\s"}) + public void removeAllFromEmpty() throws Exception { + remove("", "c"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "0", "", + ""}) + public void removeAllNotDefined() throws Exception { + remove(null, "c"); + } + private void remove(final String in, final String toRemove) throws Exception { - final String html + String html = "\n" + "\n" - + "\n" - + "
\n" - + ""; + + "\n"; + if (in == null) { + html += "
\n"; + } + else { + html += "
\n"; + } + + html += ""; loadPageVerifyTitle2(html); } @@ -1130,7 +1182,7 @@ private void remove(final String in, final String toRemove) throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a", "1", "exception", "1", "a"}) + @Alerts({"a", "1", "exception", "1", "a", ""}) public void replaceEmptyOldToken() throws Exception { replace("a", "", "abc"); } @@ -1139,7 +1191,7 @@ public void replaceEmptyOldToken() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void replaceOldTokenContainingWhiteSpace() throws Exception { replace("a b", " a x", "abc"); } @@ -1148,7 +1200,7 @@ public void replaceOldTokenContainingWhiteSpace() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a", "1", "exception", "1", "a"}) + @Alerts({"a", "1", "exception", "1", "a", ""}) public void replaceEmptyNewToken() throws Exception { replace("a", "abc", ""); } @@ -1157,7 +1209,7 @@ public void replaceEmptyNewToken() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "exception", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "exception", "2", "a\\sb", ""}) public void replaceNewTokenContainingWhiteSpace() throws Exception { replace("a b", "abc", " a x"); } @@ -1166,7 +1218,9 @@ public void replaceNewTokenContainingWhiteSpace() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "true", "2", "a\\sax", "class\\schanged\\sold:\\sa\\sb"}) + @Alerts({"a\\sb", "2", "true", "2", "a\\sax", + "", + "class\\schanged\\sold:\\sa\\sb"}) public void replace() throws Exception { replace("a b", "b", "ax"); } @@ -1176,6 +1230,7 @@ public void replace() throws Exception { */ @Test @Alerts({"a\\sb\\sc\\sb\\su", "4", "true", "4", "a\\sax\\sc\\su", + "", "class\\schanged\\sold:\\sa\\sb\\sc\\sb\\su"}) public void replaceOnce() throws Exception { replace("a b c b u", "b", "ax"); @@ -1185,7 +1240,7 @@ public void replaceOnce() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"a\\sb", "2", "false", "2", "a\\sb"}) + @Alerts({"a\\sb", "2", "false", "2", "a\\sb", ""}) public void replaceNotFound() throws Exception { replace("a b", "ab", "ax"); } @@ -1194,13 +1249,33 @@ public void replaceNotFound() throws Exception { * @throws Exception if the test fails */ @Test - @Alerts({"", "0", "false", "0", ""}) + @Alerts({"", "0", "false", "0", "", ""}) public void replaceInEmpty() throws Exception { replace("", "ab", "ax"); } + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "false", "0", "", + ""}) + public void replaceFromEmpty() throws Exception { + replace("", "a", "c"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "false", "0", "", + ""}) + public void replaceNotDefined() throws Exception { + replace(null, "a", "c"); + } + private void replace(final String in, final String oldToken, final String newToken) throws Exception { - final String html + String html = "\n" + "\n" - + "\n" - + "
\n" - + ""; + + "\n"; + if (in == null) { + html += "
\n"; + } + else { + html += "
\n"; + } + + html += ""; loadPageVerifyTitle2(html); } @@ -1265,6 +1347,30 @@ public void removeStyleCheck() throws Exception { loadPageVerifyTitle2(html); } + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"2", "false", "true", "false", "false"}) + public void in() throws Exception { + final String html + = "\n" + + "
\n" + + ""; + + loadPageVerifyTitle2(html); + } + /** * @throws Exception if the test fails */ @@ -1309,30 +1415,6 @@ public void toggle() throws Exception { loadPageVerifyTitle2(html); } - /** - * @throws Exception if the test fails - */ - @Test - @Alerts({"2", "false", "true", "false", "false"}) - public void in() throws Exception { - final String html - = "\n" - + "
\n" - + ""; - - loadPageVerifyTitle2(html); - } - /** * @throws Exception if the test fails */ @@ -1366,6 +1448,135 @@ public void toggleStyleCheck() throws Exception { loadPageVerifyTitle2(html); } + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"a", "1", "exception", "1", "a", ""}) + public void toggleEmptyToken() throws Exception { + toggle("a", ""); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"a\\sb", "2", "false", "1", "a", + "", + "class\\schanged\\sold:\\sa\\sb"}) + public void toggleStd() throws Exception { + toggle("a b", "b"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"a\\sb\\sc\\sb\\su", "4", "false", "3", "a\\sc\\su", + "", + "class\\schanged\\sold:\\sa\\sb\\sc\\sb\\su"}) + public void toggleOnce() throws Exception { + toggle("a b c b u", "b"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"a\\sb", "2", "true", "3", "a\\sb\\sab", + "", + "class\\schanged\\sold:\\sa\\sb"}) + public void toggleNotFound() throws Exception { + toggle("a b", "ab"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"a", "1", "false", "0", "", + "", + "class\\schanged\\sold:\\sa"}) + public void toggleTheOnly() throws Exception { + toggle("a", "a"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "true", "1", "a", + "", + "class\\schanged\\sold:\\s"}) + public void toggleInEmpty() throws Exception { + toggle("", "a"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "true", "1", "a", + "", + "class\\schanged\\sold:\\s"}) + public void toggleFromEmpty() throws Exception { + toggle("", "a"); + } + + /** + * @throws Exception if the test fails + */ + @Test + @Alerts({"", "0", "true", "1", "a", + "", + "class\\schanged\\sold:\\snull"}) + public void toggleNotDefined() throws Exception { + toggle(null, "a"); + } + + private void toggle(final String in, final String token) throws Exception { + String html + = "\n" + + "\n" + + "\n"; + if (in == null) { + html += "
\n"; + } + else { + html += "
\n"; + } + + html += ""; + + loadPageVerifyTitle2(html); + } + /** * @throws Exception if an error occurs */ @@ -1626,4 +1837,52 @@ public void setValue() throws Exception { loadPageVerifyTitle2(html); } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts({"a b", "
", "", "
", + "undefined", "
", + "null", "
", + "17", "
"}) + public void setValueEmpty() throws Exception { + final String html = "\n" + + "\n" + + "\n" + + "
\n" + + "\n"; + + loadPageVerifyTitle2(html); + } }