1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.dom;
16
17 import org.htmlunit.WebDriverTestCase;
18 import org.htmlunit.junit.annotation.Alerts;
19 import org.htmlunit.junit.annotation.HtmlUnitNYI;
20 import org.junit.jupiter.api.Test;
21
22
23
24
25
26
27
28
29
30
31 public class DOMTokenListTest extends WebDriverTestCase {
32
33
34
35
36 @Test
37 @Alerts({"3", "b", "b", "true", "false", "c d", "<body onload=\"test()\" class=\"c d\"> </body>"})
38 public void various() throws Exception {
39 final String html = DOCTYPE_HTML
40 + "<html><head><script>\n"
41 + LOG_TITLE_FUNCTION
42 + "function test() {\n"
43 + " var list = document.body.classList;\n"
44 + " log(list.length);\n"
45 + " log(list.item(1));\n"
46 + " log(list[1]);\n"
47 + " log(list.contains('c'));\n"
48
49 + " list.add('d');\n"
50 + " list.remove('a');\n"
51 + " log(list.toggle('b'));\n"
52
53 + " log(list);\n"
54 + " log(document.body.outerHTML);\n"
55 + "}\n"
56 + "</script></head>\n"
57 + "<body onload='test()' class='a b c'>\n"
58 + "</body></html>";
59
60 loadPageVerifyTitle2(html);
61 }
62
63
64
65
66 @Test
67 @Alerts({"0", "null", "false", "# removed", "", "<body onload=\"test()\"> </body>"})
68 public void noAttribute() throws Exception {
69 final String html = DOCTYPE_HTML
70 + "<html><head><script>\n"
71 + LOG_TITLE_FUNCTION
72 + "function test() {\n"
73 + " var list = document.body.classList;\n"
74 + " log(list.length);\n"
75 + " log(list.item(0));\n"
76 + " log(list.contains('#'));\n"
77 + " list.remove('#');"
78 + " log('# removed');\n"
79 + " log(document.body.className);\n"
80 + " log(document.body.outerHTML);\n"
81 + "}\n"
82 + "</script></head>\n"
83 + "<body onload='test()'>\n"
84 + "</body></html>";
85
86 loadPageVerifyTitle2(html);
87 }
88
89
90
91
92 @Test
93 @Alerts({"0", "undefined", "1", "#", "<body onload=\"test()\" class=\"#\"> </body>"})
94 public void noAttributeAdd() throws Exception {
95 final String html = DOCTYPE_HTML
96 + "<html><head><script>\n"
97 + LOG_TITLE_FUNCTION
98 + "function test() {\n"
99 + " var list = document.body.classList;\n"
100 + " log(list.length);\n"
101 + " log(list.add('#'));\n"
102 + " log(list.length);\n"
103 + " log(document.body.className);\n"
104 + " log(document.body.outerHTML);\n"
105 + "}\n"
106 + "</script></head><body onload='test()'>\n"
107 + "</body></html>";
108
109 loadPageVerifyTitle2(html);
110 }
111
112
113
114
115 @Test
116 @Alerts({"0", "true", "1", "#"})
117 public void noAttributeToggle() throws Exception {
118 final String html = DOCTYPE_HTML
119 + "<html><head><script>\n"
120 + LOG_TITLE_FUNCTION
121 + "function test() {\n"
122 + " var list = document.body.classList;\n"
123 + " log(list.length);\n"
124 + " log(list.toggle('#'));\n"
125 + " log(list.length);\n"
126 + " log(document.body.className);\n"
127 + "}\n"
128 + "</script></head><body onload='test()'>\n"
129 + "</body></html>";
130
131 loadPageVerifyTitle2(html);
132 }
133
134
135
136
137 @Test
138 @Alerts({"3", "0", "2", "8"})
139 public void length() throws Exception {
140 final String html = DOCTYPE_HTML
141 + "<html><head><script>\n"
142 + LOG_TITLE_FUNCTION
143 + "function test() {\n"
144 + " var list = document.getElementById('d1').classList;\n"
145 + " log(list.length);\n"
146 + " list = document.getElementById('d2').classList;\n"
147 + " log(list.length);\n"
148 + " list = document.getElementById('d3').classList;\n"
149 + " log(list.length);\n"
150 + " list = document.getElementById('d4').classList;\n"
151 + " log(list.length);\n"
152 + "}\n"
153 + "</script></head><body onload='test()'>\n"
154 + " <div id='d1' class=' a b c '></div>\n"
155 + " <div id='d2' class=''></div>\n"
156 + " <div id='d3' class=' a b a'></div>\n"
157 + " <div id='d4' class=' a b \t c \n d \u000B e \u000C f \r g'></div>\n"
158 + "</body></html>";
159
160 loadPageVerifyTitle2(html);
161 }
162
163
164
165
166 @Test
167 @Alerts({"a", "b", "c", "d", "\u000B", "e", "f", "g", "null", "null", "null"})
168 public void item() throws Exception {
169 final String html = DOCTYPE_HTML
170 + "<html><head><script>\n"
171 + LOG_TITLE_FUNCTION
172 + "function test() {\n"
173 + " var list = document.getElementById('d1').classList;\n"
174 + " for (var i = 0; i < list.length; i++) {\n"
175 + " log(list.item(i));\n"
176 + " }\n"
177 + " log(list.item(-1));\n"
178 + " log(list.item(list.length));\n"
179 + " log(list.item(100));\n"
180 + "}\n"
181 + "</script></head><body onload='test()'>\n"
182 + " <div id='d1' class=' a b \t c \n d \u000B e \u000C f \r g'></div>\n"
183 + "</body></html>";
184
185 loadPageVerifyTitle2(html);
186 }
187
188
189
190
191 @Test
192 @Alerts({"a", "b", "c", "d", "\u000B", "e", "f", "g"})
193 public void forEach() throws Exception {
194 final String html = DOCTYPE_HTML
195 + "<html><head><script>\n"
196 + LOG_TITLE_FUNCTION
197 + "function test() {\n"
198 + " var list = document.getElementById('d1').classList;\n"
199 + " list.forEach((i) => {\n"
200 + " log(i);\n"
201 + " });\n"
202 + "}\n"
203 + "</script></head><body onload='test()'>\n"
204 + " <div id='d1' class=' a b \t c \n d \u000B e \u000C f \r g'></div>\n"
205 + "</body></html>";
206
207 loadPageVerifyTitle2(html);
208 }
209
210
211
212
213 @Test
214 @Alerts({"4", "a", "b", "c", "d",
215 "7", "a", "b", "c", "d", "new-a", "new-b", "new-c"})
216 public void forEachAdd() throws Exception {
217 final String html = DOCTYPE_HTML
218 + "<html><head><script>\n"
219 + LOG_TITLE_FUNCTION
220 + "function test() {\n"
221 + " var list = document.getElementById('d1').classList;\n"
222 + " log(list.length);\n"
223
224 + " list.forEach((i) => {\n"
225 + " log(i);\n"
226 + " if (list.length < 7) { list.add('new-' + i); }\n"
227 + " });\n"
228
229 + " log(list.length);\n"
230 + " list.forEach((i) => {\n"
231 + " log(i);\n"
232 + " });\n"
233 + "}\n"
234 + "</script></head><body onload='test()'>\n"
235 + " <div id='d1' class='a b c d'></div>\n"
236 + "</body></html>";
237
238 loadPageVerifyTitle2(html);
239 }
240
241
242
243
244 @Test
245 @Alerts({"4", "a", "c", "d", "3"})
246 public void forEachRemove() throws Exception {
247 final String html = DOCTYPE_HTML
248 + "<html><head><script>\n"
249 + LOG_TITLE_FUNCTION
250 + "function test() {\n"
251 + " var list = document.getElementById('d1').classList;\n"
252 + " log(list.length);\n"
253
254 + " list.forEach((i) => {\n"
255 + " log(i);\n"
256 + " list.remove('a');\n"
257 + " });\n"
258
259 + " log(list.length);\n"
260 + "}\n"
261 + "</script></head><body onload='test()'>\n"
262 + " <div id='d1' class='a b c d'></div>\n"
263 + "</body></html>";
264
265 loadPageVerifyTitle2(html);
266 }
267
268
269
270
271
272 @Test
273 @Alerts({"4", "a", "1"})
274 public void forEachRemove2() throws Exception {
275 final String html = DOCTYPE_HTML
276 + "<html><head><script>\n"
277 + LOG_TITLE_FUNCTION
278 + "function test() {\n"
279 + " var list = document.getElementById('d1').classList;\n"
280 + " log(list.length);\n"
281
282 + " list.forEach((i) => {\n"
283 + " log(i);\n"
284 + " list.remove('a');\n"
285 + " list.remove('c');\n"
286 + " list.remove('d');\n"
287 + " });\n"
288
289 + " log(list.length);\n"
290 + "}\n"
291 + "</script></head><body onload='test()'>\n"
292 + " <div id='d1' class='a b c d'></div>\n"
293 + "</body></html>";
294
295 loadPageVerifyTitle2(html);
296 }
297
298
299
300
301 @Test
302 @Alerts({"a", "b", "c"})
303 public void forEachDuplicates() throws Exception {
304 final String html = DOCTYPE_HTML
305 + "<html><head><script>\n"
306 + LOG_TITLE_FUNCTION
307 + "function test() {\n"
308 + " var list = document.getElementById('d1').classList;\n"
309 + " list.forEach((i) => {\n"
310 + " log(i);\n"
311 + " });\n"
312 + "}\n"
313 + "</script></head><body onload='test()'>\n"
314 + " <div id='d1' class=' a b a c'></div>\n"
315 + "</body></html>";
316
317 loadPageVerifyTitle2(html);
318 }
319
320
321
322
323 @Test
324 @Alerts({"a#0#true", "b#1#true"})
325 public void forEachAllParams() throws Exception {
326 final String html = DOCTYPE_HTML
327 + "<html><head><script>\n"
328 + LOG_TITLE_FUNCTION
329 + "function test() {\n"
330 + " var list = document.getElementById('d1').classList;\n"
331 + " list.forEach((val, idx, listObj) => {\n"
332 + " log(val + '#' + idx + '#' + (listObj === list));\n"
333 + " });\n"
334 + "}\n"
335 + "</script></head><body onload='test()'>\n"
336 + " <div id='d1' class=' a b '></div>\n"
337 + "</body></html>";
338
339 loadPageVerifyTitle2(html);
340 }
341
342
343
344
345 @Test
346 @Alerts({"TypeError", "TypeError"})
347 public void forEachWrongParam() throws Exception {
348 final String html = DOCTYPE_HTML
349 + "<html><head><script>\n"
350 + LOG_TITLE_FUNCTION
351 + "function test() {\n"
352 + " var list = document.getElementById('d1').classList;\n"
353 + " try {\n"
354 + " list.forEach();\n"
355 + " } catch(e) { logEx(e); }\n"
356 + " try {\n"
357 + " list.forEach('wrong');\n"
358 + " } catch(e) { logEx(e); }\n"
359 + "}\n"
360 + "</script></head><body onload='test()'>\n"
361 + " <div id='d1' class=' a b \t c \n d \u000B e \u000C f \r g'></div>\n"
362 + "</body></html>";
363
364 loadPageVerifyTitle2(html);
365 }
366
367
368
369
370 @Test
371 @Alerts({"value", "done", "object", "0", "a"})
372 public void entries() throws Exception {
373 final String html = DOCTYPE_HTML
374 + "<html><head>\n"
375 + "<script>\n"
376 + LOG_TITLE_FUNCTION
377 + " function test() {\n"
378 + " var list = document.getElementById('d1').classList;\n"
379 + " if (!list.entries) {\n"
380 + " log('not defined');\n"
381 + " return;\n"
382 + " }\n"
383 + " var i = list.entries().next();\n"
384 + " for (var x in i) {\n"
385 + " log(x);\n"
386 + " }\n"
387 + " var v = i.value;\n"
388 + " log(typeof v);\n"
389 + " log(v[0]);\n"
390 + " log(v[1]);\n"
391 + " }\n"
392 + "</script>\n"
393 + "</head><body onload='test()'>\n"
394 + " <div id='d1' class=' a x'></div>\n"
395 + "</body></html>\n";
396
397 loadPageVerifyTitle2(html);
398 }
399
400
401
402
403 @Test
404 @Alerts({"true", "undefined", "function", "undefined", "undefined", "true", "true", "true"})
405 public void entriesPropertyDescriptor() throws Exception {
406 final String html = DOCTYPE_HTML
407 + "<html><head>\n"
408 + "<script>\n"
409 + LOG_TITLE_FUNCTION
410 + " function test() {\n"
411 + " var list = document.getElementById('d1').classList;\n"
412
413 + " log('entries' in list);\n"
414 + " log(Object.getOwnPropertyDescriptor(list, 'entries'));\n"
415
416 + " var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(list), 'entries');\n"
417 + " if (desc === undefined) { log('no entries'); return; }\n"
418 + " log(typeof desc.value);\n"
419 + " log(desc.get);\n"
420 + " log(desc.set);\n"
421 + " log(desc.writable);\n"
422 + " log(desc.enumerable);\n"
423 + " log(desc.configurable);\n"
424 + " }\n"
425 + "</script>\n"
426 + "</head><body onload='test()'>\n"
427 + " <div id='d1' class=' a x'></div>\n"
428 + "</body></html>\n";
429
430 loadPageVerifyTitle2(html);
431 }
432
433
434
435
436 @Test
437 @Alerts({"0,a", "1,x"})
438 public void entriesForOf() throws Exception {
439 final String html = DOCTYPE_HTML
440 + "<html><head>\n"
441 + "<script>\n"
442 + LOG_TITLE_FUNCTION
443 + " function test() {\n"
444 + " var list = document.getElementById('d1').classList;\n"
445 + " if (!list.entries) {\n"
446 + " log('not defined');\n"
447 + " return;\n"
448 + " }\n"
449 + " for (var i of list.entries()) {\n"
450 + " log(i);\n"
451 + " }\n"
452 + " }\n"
453 + "</script>\n"
454 + "</head><body onload='test()'>\n"
455 + " <div id='d1' class=' a x'></div>\n"
456 + "</body></html>\n";
457
458 loadPageVerifyTitle2(html);
459 }
460
461
462
463
464 @Test
465 @Alerts("0,1,2,add,contains,entries,forEach,item,keys,length,remove,replace,supports,toggle,toString,value,values")
466 @HtmlUnitNYI(CHROME = "0,1,2,add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values",
467 EDGE = "0,1,2,add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values",
468 FF = "0,1,2,add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values",
469 FF_ESR = "0,1,2,add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values")
470 public void forIn() throws Exception {
471 final String html = DOCTYPE_HTML
472 + "<html><head>\n"
473 + "<script>\n"
474 + LOG_TITLE_FUNCTION
475 + " function test() {\n"
476 + " var all = [];\n"
477 + " for (var i in document.getElementById('d1').classList) {\n"
478 + " all.push(i);\n"
479 + " }\n"
480 + " all.sort(sortFunction);\n"
481 + " log(all);\n"
482 + " }\n"
483 + " function sortFunction(s1, s2) {\n"
484 + " return s1.toLowerCase() > s2.toLowerCase() ? 1 : -1;\n"
485 + " }\n"
486 + "</script>\n"
487 + "</head><body onload='test()'>\n"
488 + " <div id='d1' class=' a b g'></div>\n"
489 + "</body></html>";
490
491 loadPageVerifyTitle2(html);
492 }
493
494
495
496
497 @Test
498 @Alerts("add,contains,entries,forEach,item,keys,length,remove,replace,supports,toggle,toString,value,values")
499 @HtmlUnitNYI(CHROME = "add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values",
500 EDGE = "add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values",
501 FF = "add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values",
502 FF_ESR = "add,contains,entries,forEach,item,keys,length,remove,replace,toggle,value,values")
503 public void forInEmptyList() throws Exception {
504 final String html = DOCTYPE_HTML
505 + "<html><head>\n"
506 + "<script>\n"
507 + LOG_TITLE_FUNCTION
508 + " function test() {\n"
509 + " var all = [];\n"
510 + " for (var i in document.getElementById('d1').classList) {\n"
511 + " all.push(i);\n"
512 + " }\n"
513 + " all.sort(sortFunction);\n"
514 + " log(all);\n"
515 + " }\n"
516 + " function sortFunction(s1, s2) {\n"
517 + " return s1.toLowerCase() > s2.toLowerCase() ? 1 : -1;\n"
518 + " }\n"
519 + "</script>\n"
520 + "</head><body onload='test()'>\n"
521 + " <div id='d1'></div>\n"
522 + "</body></html>";
523
524 loadPageVerifyTitle2(html);
525 }
526
527
528
529
530 @Test
531 @Alerts({"true", "a", "b", "g"})
532 public void iterator() throws Exception {
533 final String html = DOCTYPE_HTML
534 + "<html><head>\n"
535 + "<script>\n"
536 + LOG_TITLE_FUNCTION
537 + " function test() {\n"
538 + " var list = document.getElementById('d1').classList;\n"
539
540 + " if (typeof Symbol != 'undefined') {\n"
541 + " log(list[Symbol.iterator] === list.values);\n"
542 + " }\n"
543
544 + " if (!list.forEach) {\n"
545 + " log('no for..of');\n"
546 + " return;\n"
547 + " }\n"
548
549 + " for (var i of list) {\n"
550 + " log(i);\n"
551 + " }\n"
552 + " }\n"
553 + "</script>\n"
554 + "</head><body onload='test()'>\n"
555 + " <div id='d1' class=' a b g'></div>\n"
556 + "</body></html>";
557
558 loadPageVerifyTitle2(html);
559 }
560
561
562
563
564 @Test
565 @Alerts({"a b", "2", "null", "undefined"})
566 public void itemNegative() throws Exception {
567 item("a b", -1);
568 }
569
570
571
572
573 @Test
574 @Alerts({"a b", "2", "null", "undefined"})
575 public void itemNegative2() throws Exception {
576 item("a b", -123);
577 }
578
579
580
581
582 @Test
583 @Alerts({"a b", "2", "a", "a"})
584 public void itemFirst() throws Exception {
585 item("a b", 0);
586 }
587
588
589
590
591 @Test
592 @Alerts({"a b", "2", "b", "b"})
593 public void itemLast() throws Exception {
594 item("a b", 1);
595 }
596
597
598
599
600 @Test
601 @Alerts({"a b", "2", "null", "undefined"})
602 public void itemOutside() throws Exception {
603 item("a b", 13);
604 }
605
606 private void item(final String in, final int pos) throws Exception {
607 final String html = DOCTYPE_HTML
608 + "<html><head>\n"
609 + "<script>\n"
610 + LOG_TITLE_FUNCTION
611 + " function test() {\n"
612 + " var elem = document.getElementById('d1');\n"
613
614 + " var config = { attributes: true, attributeOldValue: true };\n"
615 + " var observer = new MutationObserver(function(mutations) {\n"
616 + " mutations.forEach(function(mutation) {\n"
617 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
618 + " });\n"
619 + " });\n"
620 + " observer.observe(elem, config);"
621
622 + " var list = elem.classList;\n"
623 + " if (!list) { log('no list'); return; }\n"
624
625 + " log(elem.className);\n"
626 + " log(list.length);\n"
627 + " try {\n"
628 + " log(list.item(" + pos + "));\n"
629 + " log(list[" + pos + "]);\n"
630 + " } catch(e) { logEx(e);}\n"
631 + " }\n"
632 + "</script></head><body onload='test()'>\n"
633 + " <div id='d1' class='" + in + "'></div>\n"
634 + "</body></html>";
635
636 loadPageVerifyTitle2(html);
637 }
638
639
640
641
642 @Test
643 @Alerts({"a\\sb", "2", "false"})
644 public void containsEmpty() throws Exception {
645 contains("a b", "");
646 }
647
648
649
650
651 @Test
652 @Alerts({"a\\sb", "2", "false"})
653 public void containsBlank() throws Exception {
654 contains("a b", " ");
655 }
656
657
658
659
660 @Test
661 @Alerts({"a\\sb", "2", "false"})
662 public void containsTab() throws Exception {
663 contains("a b", "\t");
664 }
665
666
667
668
669 @Test
670 @Alerts({"a\\sb", "2", "false"})
671 public void containsCr() throws Exception {
672 contains("a b", "\\r");
673 }
674
675
676
677
678 @Test
679 @Alerts({"a\\sb", "2", "false"})
680 public void containsNl() throws Exception {
681 contains("a b", "\\n");
682 }
683
684
685
686
687 @Test
688 @Alerts({"a\\sb", "2", "false"})
689 public void containsVt() throws Exception {
690 contains("a b", "\u000B");
691 }
692
693
694
695
696 @Test
697 @Alerts({"", "0", "false"})
698 public void containsInsideEmpty() throws Exception {
699 contains("", "a");
700 }
701
702
703
704
705 @Test
706 @Alerts({"\\s\\t\\s\\n\\s\\s", "0", "false"})
707 public void containsInsideWhitespace() throws Exception {
708 contains(" \t \r ", "a");
709 }
710
711
712
713
714 @Test
715 @Alerts({"a\\sb", "2", "true"})
716 public void containsInsideAtStart() throws Exception {
717 contains("a b", "a");
718 }
719
720
721
722
723 @Test
724 @Alerts({"a\\sb", "2", "true"})
725 public void containsInsideAtEnd() throws Exception {
726 contains("a b", "b");
727 }
728
729
730
731
732 @Test
733 @Alerts({"abc\\sdef", "2", "false"})
734 public void containsInsideSubstringAtStart() throws Exception {
735 contains("abc def", "ab");
736 }
737
738
739
740
741 @Test
742 @Alerts({"abc\\sdef", "2", "false"})
743 public void containsInsideSubstringAtEnd() throws Exception {
744 contains("abc def", "bc");
745 }
746
747
748
749
750 @Test
751 @Alerts({"abcd\\sef", "2", "false"})
752 public void containsInsideSubstringInside() throws Exception {
753 contains("abcd ef", "bc");
754 }
755
756
757
758
759 @Test
760 @Alerts({"a\\s\\s", "1", "true"})
761 public void containsInsideWhitespaceAtEnd() throws Exception {
762 contains("a ", "a");
763 }
764
765
766
767
768 @Test
769 @Alerts({"\\s\\sa", "1", "true"})
770 public void containsInsideWhitespaceInFront() throws Exception {
771 contains(" a", "a");
772 }
773
774
775
776
777 @Test
778 @Alerts({"a\\s\\t\\sc\\s\\n\\sd\\s\\se", "4", "true"})
779 public void containsWhitespaceExisting() throws Exception {
780 contains("a \t c \n d e", "c");
781 }
782
783 private void contains(final String in, final String toAdd) throws Exception {
784 final String html = DOCTYPE_HTML
785 + "<html><head>\n"
786 + "<script>\n"
787 + LOG_TITLE_FUNCTION_NORMALIZE
788 + " function test() {\n"
789 + " var elem = document.getElementById('d1');\n"
790
791 + " var config = { attributes: true, attributeOldValue: true };\n"
792 + " var observer = new MutationObserver(function(mutations) {\n"
793 + " mutations.forEach(function(mutation) {\n"
794 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
795 + " });\n"
796 + " });\n"
797 + " observer.observe(elem, config);"
798
799 + " var list = elem.classList;\n"
800 + " if (!list) { log('no list'); return; }\n"
801
802 + " log(elem.className);\n"
803 + " log(list.length);\n"
804 + " try {\n"
805 + " log(list.contains('" + toAdd + "'));\n"
806 + " } catch(e) { logEx(e);}\n"
807 + " }\n"
808 + "</script></head><body onload='test()'>\n"
809 + " <div id='d1' class='" + in + "'></div>\n"
810 + "</body></html>";
811
812 loadPageVerifyTitle2(html);
813 }
814
815
816
817
818 @Test
819 @Alerts({"a\\sb", "2", "SyntaxError/DOMException", "2", "a\\sb"})
820 public void addEmpty() throws Exception {
821 add("a b", "''");
822 }
823
824
825
826
827 @Test
828 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException", "2", "a\\sb"})
829 public void addBlank() throws Exception {
830 add("a b", "' '");
831 }
832
833
834
835
836 @Test
837 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException", "2", "a\\sb"})
838 public void addTab() throws Exception {
839 add("a b", "'\t'");
840 }
841
842
843
844
845 @Test
846 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException", "2", "a\\sb"})
847 public void addCr() throws Exception {
848 add("a b", "'\\r'");
849 }
850
851
852
853
854 @Test
855 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException", "2", "a\\sb"})
856 public void addNl() throws Exception {
857 add("a b", "'\\n'");
858 }
859
860
861
862
863 @Test
864 @Alerts({"a\\sb", "2", "3", "a\\sb\\s\u000B", "class\\schanged\\sold:\\sa\\sb"})
865 public void addVt() throws Exception {
866 add("a b", "'\u000B'");
867 }
868
869
870
871
872 @Test
873 @Alerts({"", "0", "1", "a", "class\\schanged\\sold:\\s"})
874 public void addToEmpty() throws Exception {
875 add("", "'a'");
876 }
877
878
879
880
881 @Test
882 @Alerts({"\\s\\t\\s\\n\\s\\s", "0", "1", "a", "class\\schanged\\sold:\\s\\s\\t\\s\\n\\s\\s"})
883 public void addToWhitespace() throws Exception {
884 add(" \t \r ", "'a'");
885 }
886
887
888
889
890 @Test
891 @Alerts({"a\\s\\s", "1", "2", "a\\sb", "class\\schanged\\sold:\\sa\\s\\s"})
892 public void addToWhitespaceAtEnd() throws Exception {
893 add("a ", "'b'");
894 }
895
896
897
898
899 @Test
900 @Alerts({"a\\sb", "2", "3", "a\\sb\\sc", "class\\schanged\\sold:\\sa\\sb"})
901 public void addNotExisting() throws Exception {
902 add("a b", "'c'");
903 }
904
905
906
907
908 @Test
909 @Alerts({"a\\sb", "2", "2", "a\\sb", "class\\schanged\\sold:\\sa\\sb"})
910 public void addExisting() throws Exception {
911 add("a b", "'a'");
912 }
913
914
915
916
917 @Test
918 @Alerts({"b\\sa", "2", "2", "b\\sa", "class\\schanged\\sold:\\sb\\sa"})
919 public void addExisting2() throws Exception {
920 add("b a", "'a'");
921 }
922
923
924
925
926 @Test
927 @Alerts({"b\\sa\\sb", "2", "3", "b\\sa\\sc", "class\\schanged\\sold:\\sb\\sa\\sb"})
928 public void addNormalizes() throws Exception {
929 add("b a b", "'c'");
930 }
931
932
933
934
935 @Test
936 @Alerts({"a\\sb\\sa", "2", "InvalidCharacterError/DOMException", "2", "a\\sb\\sa"})
937 public void addElementWithBlank() throws Exception {
938 add("a b a", "'a b'");
939 }
940
941
942
943
944 @Test
945 @Alerts({"a\\sb\\sa\\tb", "2", "InvalidCharacterError/DOMException", "2", "a\\sb\\sa\\tb"})
946 public void addElementWithTab() throws Exception {
947 add("a b a\tb", "'a\tb'");
948 }
949
950
951
952
953 @Test
954 @Alerts({"a\\s\\t\\sc\\s\\n\\sd\\s\\se", "4", "4", "a\\sc\\sd\\se",
955 "class\\schanged\\sold:\\sa\\s\\t\\sc\\s\\n\\sd\\s\\se"})
956 public void addToWhitespaceExisting() throws Exception {
957 add("a \t c \n d e", "'c'");
958 }
959
960
961
962
963 @Test
964 @Alerts({"a\\se", "2", "4", "a\\se\\sc\\sb", "class\\schanged\\sold:\\sa\\se"})
965 public void addTwoValues() throws Exception {
966 add("a e", "'c', 'b'");
967 }
968
969
970
971
972 @Test
973 @Alerts({"a\\se", "2", "3", "a\\se\\sc", "class\\schanged\\sold:\\sa\\se"})
974 public void addTwoValuesExisting() throws Exception {
975 add("a e", "'c', 'e'");
976 }
977
978
979
980
981 @Test
982 @Alerts({"a\\se", "2", "4", "a\\se\\sc\\s7", "class\\schanged\\sold:\\sa\\se"})
983 public void addTwoValuesNumber() throws Exception {
984 add("a e", "'c', 7");
985 }
986
987
988
989
990 @Test
991 @Alerts({"a\\se", "2", "4", "a\\se\\strue\\sfalse", "class\\schanged\\sold:\\sa\\se"})
992 public void addTwoValuesBoolean() throws Exception {
993 add("a e", "true, false");
994 }
995
996
997
998
999 @Test
1000 @Alerts({"a\\se", "2", "InvalidCharacterError/DOMException", "2", "a\\se"})
1001 public void addTwoValuesObject() throws Exception {
1002 add("a e", "'c', { color: 'blue' }");
1003 }
1004
1005
1006
1007
1008 @Test
1009 @Alerts({"a\\se", "2", "4", "a\\se\\sc\\sundefined", "class\\schanged\\sold:\\sa\\se"})
1010 public void addTwoValuesUndefined() throws Exception {
1011 add("a e", "'c', undefined");
1012 }
1013
1014
1015
1016
1017 @Test
1018 @Alerts({"a\\se", "2", "4", "a\\se\\sc\\snull", "class\\schanged\\sold:\\sa\\se"})
1019 public void addTwoValuesNull() throws Exception {
1020 add("a e", "'c', null");
1021 }
1022
1023 private void add(final String in, final String toAdd) throws Exception {
1024 final String html = DOCTYPE_HTML
1025 + "<html><head>\n"
1026 + "<script>\n"
1027 + LOG_TITLE_FUNCTION_NORMALIZE
1028 + " function test() {\n"
1029 + " var elem = document.getElementById('d1');\n"
1030
1031 + " var config = { attributes: true, attributeOldValue: true };\n"
1032 + " var observer = new MutationObserver(function(mutations) {\n"
1033 + " mutations.forEach(function(mutation) {\n"
1034 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
1035 + " });\n"
1036 + " });\n"
1037 + " observer.observe(elem, config);"
1038
1039 + " var list = elem.classList;\n"
1040 + " if (!list) { log('no list'); return; }\n"
1041
1042 + " log(elem.className);\n"
1043 + " log(list.length);\n"
1044 + " try {\n"
1045 + " list.add(" + toAdd + ");\n"
1046 + " } catch(e) { logEx(e);}\n"
1047 + " log(list.length);\n"
1048 + " log(elem.className);\n"
1049 + " }\n"
1050 + "</script></head>\n"
1051 + "<body onload='test()'>\n"
1052 + " <div id='d1' class='" + in + "'></div>\n"
1053 + "</body></html>";
1054
1055 loadPageVerifyTitle2(html);
1056 }
1057
1058
1059
1060
1061 @Test
1062 @Alerts({"2", "3"})
1063 public void addSvg() throws Exception {
1064 final String html = DOCTYPE_HTML
1065 + "<html><head>\n"
1066 + "<script>\n"
1067 + LOG_TITLE_FUNCTION
1068 + " function test() {\n"
1069 + " var elem = document.getElementById('myId');\n"
1070 + " var list = elem.classList;\n"
1071 + " if (!list) { log('no list'); return; }\n"
1072
1073 + " log(list.length);\n"
1074 + " try {\n"
1075 + " list.add('new');\n"
1076 + " } catch(e) { logEx(e);}\n"
1077 + " log(list.length);\n"
1078 + " }\n"
1079 + "</script></head><body onload='test()'>\n"
1080 + " <svg xmlns='http://www.w3.org/2000/svg' version='1.1'>\n"
1081 + " <text id='myId' class='cls1, cls2'/>\n"
1082 + " </svg>\n"
1083 + "</body></html>";
1084
1085 loadPageVerifyTitle2(html);
1086 }
1087
1088
1089
1090
1091 @Test
1092 @Alerts({"block", "none"})
1093 public void addStyleCheck() throws Exception {
1094 final String html = DOCTYPE_HTML
1095 + "<html><head>\n"
1096 + "<style>\n"
1097 + " #d1.hidden { display: none; }\n"
1098 + "</style>\n"
1099 + "<script>\n"
1100 + LOG_TITLE_FUNCTION
1101 + "function test() {\n"
1102 + " var div1 = document.getElementById('d1');\n"
1103 + " var list = div1.classList;\n"
1104
1105 + " log(getComputedStyle(div1, null).display);\n"
1106 + " list.add('hidden');\n"
1107 + " log(getComputedStyle(div1, null).display);\n"
1108 + "}\n"
1109 + "</script>"
1110 + "</head>\n"
1111 + "<body onload='test()'>\n"
1112 + " <div id='d1' class='nice'></div>\n"
1113 + "</body></html>";
1114
1115 loadPageVerifyTitle2(html);
1116 }
1117
1118
1119
1120
1121 @Test
1122 @Alerts({"a\\sb", "2", "SyntaxError/DOMException", "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1123 public void removeEmpty() throws Exception {
1124 remove("a b", "''");
1125 }
1126
1127
1128
1129
1130 @Test
1131 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException",
1132 "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1133 public void removeBlank() throws Exception {
1134 remove("a b", "' '");
1135 }
1136
1137
1138
1139
1140 @Test
1141 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException",
1142 "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1143 public void removeTab() throws Exception {
1144 remove("a b", "'\t'");
1145 }
1146
1147
1148
1149
1150 @Test
1151 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException",
1152 "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1153 public void removeCr() throws Exception {
1154 remove("a b", "'\\r'");
1155 }
1156
1157
1158
1159
1160 @Test
1161 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException",
1162 "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1163 public void removeNl() throws Exception {
1164 remove("a b", "'\\n'");
1165 }
1166
1167
1168
1169
1170 @Test
1171 @Alerts({"a\\sb", "2", "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>", "class\\schanged\\sold:\\sa\\sb"})
1172 public void removeVt() throws Exception {
1173 remove("a b", "'\u000B'");
1174 }
1175
1176
1177
1178
1179 @Test
1180 @Alerts({"", "0", "0", "", "<div\\sid=\"d1\"\\sclass=\"\"></div>", "class\\schanged\\sold:\\s"})
1181 public void removeFromEmpty() throws Exception {
1182 remove("", "'a'");
1183 }
1184
1185
1186
1187
1188 @Test
1189 @Alerts({"\\s\\t\\s\\n\\s\\s", "0", "0", "",
1190 "<div\\sid=\"d1\"\\sclass=\"\"></div>",
1191 "class\\schanged\\sold:\\s\\s\\t\\s\\n\\s\\s"})
1192 public void removeFromWhitespace() throws Exception {
1193 remove(" \t \r ", "'a'");
1194 }
1195
1196
1197
1198
1199 @Test
1200 @Alerts({"a\\sb", "2", "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>", "class\\schanged\\sold:\\sa\\sb"})
1201 public void removeNotExisting() throws Exception {
1202 remove("a b", "'c'");
1203 }
1204
1205
1206
1207
1208 @Test
1209 @Alerts({"a\\sb\\sa", "2", "1", "b", "<div\\sid=\"d1\"\\sclass=\"b\"></div>", "class\\schanged\\sold:\\sa\\sb\\sa"})
1210 public void removeDuplicated() throws Exception {
1211 remove("a b a", "'a'");
1212 }
1213
1214
1215
1216
1217 @Test
1218 @Alerts({"a\\sb\\sa", "2", "InvalidCharacterError/DOMException", "2", "a\\sb\\sa",
1219 "<div\\sid=\"d1\"\\sclass=\"a\\sb\\sa\"></div>"})
1220 public void removeElementWithBlank() throws Exception {
1221 remove("a b a", "'a b'");
1222 }
1223
1224
1225
1226
1227 @Test
1228 @Alerts({"a\\sb\\sa\\tb", "2", "InvalidCharacterError/DOMException", "2", "a\\sb\\sa\\tb",
1229 "<div\\sid=\"d1\"\\sclass=\"a\\sb\\sa\\tb\"></div>"})
1230 public void removeElementWithTab() throws Exception {
1231 remove("a b a\tb", "'a\tb'");
1232 }
1233
1234
1235
1236
1237 @Test
1238 @Alerts({"a", "1", "0", "", "<div\\sid=\"d1\"\\sclass=\"\"></div>", "class\\schanged\\sold:\\sa"})
1239 public void removeLast() throws Exception {
1240 remove("a", "'a'");
1241 }
1242
1243
1244
1245
1246 @Test
1247 @Alerts({"a\\s\\t\\sc\\s\\n\\sd\\s\\se", "4", "3", "a\\sd\\se",
1248 "<div\\sid=\"d1\"\\sclass=\"a\\sd\\se\"></div>",
1249 "class\\schanged\\sold:\\sa\\s\\t\\sc\\s\\n\\sd\\s\\se"})
1250 public void removeWhitespace() throws Exception {
1251 remove("a \t c \n d e", "'c'");
1252 }
1253
1254
1255
1256
1257 @Test
1258 @Alerts({"a\\sc\\sa\\sc", "2", "1", "a",
1259 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1260 "class\\schanged\\sold:\\sa\\sc\\sa\\sc"})
1261 public void removeNormalizes() throws Exception {
1262 remove("a c a c", "'c'");
1263 }
1264
1265
1266
1267
1268 @Test
1269 @Alerts({"c", "1", "0", "",
1270 "<div\\sid=\"d1\"\\sclass=\"\"></div>",
1271 "class\\schanged\\sold:\\sc"})
1272 public void removeAll() throws Exception {
1273 remove("c", "'c'");
1274 }
1275
1276
1277
1278
1279 @Test
1280 @Alerts({"", "0", "0", "",
1281 "<div\\sid=\"d1\"\\sclass=\"\"></div>",
1282 "class\\schanged\\sold:\\s"})
1283 public void removeAllFromEmpty() throws Exception {
1284 remove("", "'c'");
1285 }
1286
1287
1288
1289
1290 @Test
1291 @Alerts({"", "0", "0", "",
1292 "<div\\sid=\"d1\"></div>"})
1293 public void removeAllNotDefined() throws Exception {
1294 remove(null, "'c'");
1295 }
1296
1297
1298
1299
1300 @Test
1301 @Alerts({"a\\sb", "2", "1", "a",
1302 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1303 "class\\schanged\\sold:\\sa\\sb"})
1304 public void removeTwo() throws Exception {
1305 remove("a b", "'b', 'd'");
1306 }
1307
1308
1309
1310
1311 @Test
1312 @Alerts({"a\\sb\\s7", "3", "1", "a",
1313 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1314 "class\\schanged\\sold:\\sa\\sb\\s7"})
1315 public void removeTwoNumber() throws Exception {
1316 remove("a b 7", "'b', 7");
1317 }
1318
1319
1320
1321
1322 @Test
1323 @Alerts({"a\\sb\\strue", "3", "2", "a\\sb",
1324 "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>",
1325 "class\\schanged\\sold:\\sa\\sb\\strue"})
1326 public void removeTwoBoolean() throws Exception {
1327 remove("a b true", "true, false");
1328 }
1329
1330
1331
1332
1333 @Test
1334 @Alerts({"a\\sb\\sundefined", "3", "1", "a",
1335 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1336 "class\\schanged\\sold:\\sa\\sb\\sundefined"})
1337 public void removeTwoUndefined() throws Exception {
1338 remove("a b undefined", "'b', undefined");
1339 }
1340
1341
1342
1343
1344 @Test
1345 @Alerts({"a\\snull\\s7", "3", "2", "a\\s7",
1346 "<div\\sid=\"d1\"\\sclass=\"a\\s7\"></div>",
1347 "class\\schanged\\sold:\\sa\\snull\\s7"})
1348 public void removeTwoNull() throws Exception {
1349 remove("a null 7", "'b', null");
1350 }
1351
1352
1353
1354
1355 @Test
1356 @Alerts({"a\\sb\\s7", "3", "InvalidCharacterError/DOMException", "3", "a\\sb\\s7",
1357 "<div\\sid=\"d1\"\\sclass=\"a\\sb\\s7\"></div>"})
1358 public void removeTwoObject() throws Exception {
1359 remove("a b 7", "'b', { color: 'red' }");
1360 }
1361
1362 private void remove(final String in, final String toRemove) throws Exception {
1363 String html = DOCTYPE_HTML
1364 + "<html><head>\n"
1365 + "<script>\n"
1366 + LOG_TITLE_FUNCTION_NORMALIZE
1367 + " function test() {\n"
1368 + " var elem = document.getElementById('d1');\n"
1369
1370 + " var config = { attributes: true, attributeOldValue: true };\n"
1371 + " var observer = new MutationObserver(function(mutations) {\n"
1372 + " mutations.forEach(function(mutation) {\n"
1373 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
1374 + " });\n"
1375 + " });\n"
1376 + " observer.observe(elem, config);"
1377
1378 + " var list = elem.classList;\n"
1379 + " if (!list) { log('no list'); return; }\n"
1380
1381 + " log(elem.className);\n"
1382 + " log(list.length);\n"
1383 + " try {\n"
1384 + " list.remove(" + toRemove + ");\n"
1385 + " } catch(e) { logEx(e);}\n"
1386 + " log(list.length);\n"
1387 + " log(elem.className);\n"
1388 + " log(elem.outerHTML);\n"
1389 + " }\n"
1390 + "</script></head>\n"
1391 + "<body onload='test()'>\n";
1392 if (in == null) {
1393 html += " <div id='d1'></div>\n";
1394 }
1395 else {
1396 html += " <div id='d1' class='" + in + "'></div>\n";
1397 }
1398
1399 html += "</body></html>";
1400
1401 loadPageVerifyTitle2(html);
1402 }
1403
1404
1405
1406
1407 @Test
1408 @Alerts({"a", "1", "SyntaxError/DOMException", "1", "a", "<div\\sid=\"d1\"\\sclass=\"a\"></div>"})
1409 public void replaceEmptyOldToken() throws Exception {
1410 replace("a", "", "abc");
1411 }
1412
1413
1414
1415
1416 @Test
1417 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException",
1418 "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1419 public void replaceOldTokenContainingWhiteSpace() throws Exception {
1420 replace("a b", " a x", "abc");
1421 }
1422
1423
1424
1425
1426 @Test
1427 @Alerts({"a", "1", "SyntaxError/DOMException", "1", "a", "<div\\sid=\"d1\"\\sclass=\"a\"></div>"})
1428 public void replaceEmptyNewToken() throws Exception {
1429 replace("a", "abc", "");
1430 }
1431
1432
1433
1434
1435 @Test
1436 @Alerts({"a\\sb", "2", "InvalidCharacterError/DOMException",
1437 "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1438 public void replaceNewTokenContainingWhiteSpace() throws Exception {
1439 replace("a b", "abc", " a x");
1440 }
1441
1442
1443
1444
1445 @Test
1446 @Alerts({"a\\sb", "2", "true", "2", "a\\sax",
1447 "<div\\sid=\"d1\"\\sclass=\"a\\sax\"></div>",
1448 "class\\schanged\\sold:\\sa\\sb"})
1449 public void replace() throws Exception {
1450 replace("a b", "b", "ax");
1451 }
1452
1453
1454
1455
1456 @Test
1457 @Alerts({"a\\sb\\sc\\sb\\su", "4", "true", "4", "a\\sax\\sc\\su",
1458 "<div\\sid=\"d1\"\\sclass=\"a\\sax\\sc\\su\"></div>",
1459 "class\\schanged\\sold:\\sa\\sb\\sc\\sb\\su"})
1460 public void replaceOnce() throws Exception {
1461 replace("a b c b u", "b", "ax");
1462 }
1463
1464
1465
1466
1467 @Test
1468 @Alerts({"a\\sb", "2", "false", "2", "a\\sb", "<div\\sid=\"d1\"\\sclass=\"a\\sb\"></div>"})
1469 public void replaceNotFound() throws Exception {
1470 replace("a b", "ab", "ax");
1471 }
1472
1473
1474
1475
1476 @Test
1477 @Alerts({"", "0", "false", "0", "", "<div\\sid=\"d1\"\\sclass=\"\"></div>"})
1478 public void replaceInEmpty() throws Exception {
1479 replace("", "ab", "ax");
1480 }
1481
1482
1483
1484
1485 @Test
1486 @Alerts({"", "0", "false", "0", "",
1487 "<div\\sid=\"d1\"\\sclass=\"\"></div>"})
1488 public void replaceFromEmpty() throws Exception {
1489 replace("", "a", "c");
1490 }
1491
1492
1493
1494
1495 @Test
1496 @Alerts({"", "0", "false", "0", "",
1497 "<div\\sid=\"d1\"></div>"})
1498 public void replaceNotDefined() throws Exception {
1499 replace(null, "a", "c");
1500 }
1501
1502 private void replace(final String in, final String oldToken, final String newToken) throws Exception {
1503 String html = DOCTYPE_HTML
1504 + "<html><head>\n"
1505 + "<script>\n"
1506 + LOG_TITLE_FUNCTION_NORMALIZE
1507 + " function test() {\n"
1508 + " var elem = document.getElementById('d1');\n"
1509
1510 + " var config = { attributes: true, attributeOldValue: true };\n"
1511 + " var observer = new MutationObserver(function(mutations) {\n"
1512 + " mutations.forEach(function(mutation) {\n"
1513 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
1514 + " });\n"
1515 + " });\n"
1516 + " observer.observe(elem, config);"
1517
1518 + " var list = elem.classList;\n"
1519 + " if (!list) { log('no list'); return; }\n"
1520
1521 + " log(elem.className);\n"
1522 + " log(list.length);\n"
1523 + " try {\n"
1524 + " var res = list.replace('" + oldToken + "', '" + newToken + "');\n"
1525 + " log(res);\n"
1526 + " } catch(e) { logEx(e);}\n"
1527 + " log(list.length);\n"
1528 + " log(elem.className);\n"
1529 + " log(elem.outerHTML);\n"
1530 + " }\n"
1531 + "</script></head>\n"
1532 + "<body onload='test()'>\n";
1533 if (in == null) {
1534 html += " <div id='d1'></div>\n";
1535 }
1536 else {
1537 html += " <div id='d1' class='" + in + "'></div>\n";
1538 }
1539
1540 html += "</body></html>";
1541
1542 loadPageVerifyTitle2(html);
1543 }
1544
1545
1546
1547
1548 @Test
1549 @Alerts({ "none", "block"})
1550 public void removeStyleCheck() throws Exception {
1551 final String html = DOCTYPE_HTML
1552 + "<html><head>\n"
1553 + "<style>\n"
1554 + " #d1.hidden { display: none; }\n"
1555 + "</style>\n"
1556 + "<script>\n"
1557 + LOG_TITLE_FUNCTION
1558 + "function test() {\n"
1559 + " var div1 = document.getElementById('d1');\n"
1560 + " var list = div1.classList;\n"
1561
1562 + " log(getComputedStyle(div1, null).display);\n"
1563 + " list.remove('hidden');\n"
1564 + " log(getComputedStyle(div1, null).display);\n"
1565 + "}\n"
1566 + "</script>"
1567 + "</head>\n"
1568 + "<body onload='test()'>\n"
1569 + " <div id='d1' class='hidden'></div>\n"
1570 + "</body></html>";
1571
1572 loadPageVerifyTitle2(html);
1573 }
1574
1575
1576
1577
1578 @Test
1579 @Alerts({"2", "false", "true", "false", "false"})
1580 public void in() throws Exception {
1581 final String html = DOCTYPE_HTML
1582 + "<html><head><script>\n"
1583 + LOG_TITLE_FUNCTION
1584 + "function test() {\n"
1585 + " var list = document.getElementById('d1').classList;\n"
1586 + " log(list.length);\n"
1587 + " log(-1 in list);\n"
1588 + " log(0 in list);\n"
1589 + " log(2 in list);\n"
1590 + " log(42 in list);\n"
1591 + "}\n"
1592 + "</script></head><body onload='test()'>\n"
1593 + " <div id='d1' class='a e'></div>\n"
1594 + "</body></html>";
1595
1596 loadPageVerifyTitle2(html);
1597 }
1598
1599
1600
1601
1602 @Test
1603 @Alerts({"InvalidCharacterError/DOMException", "SyntaxError/DOMException",
1604 "2", "true", "false", "1", "false", "true", "2", "true",
1605 "class changed old: a e", "class changed old: a"})
1606 public void toggle() throws Exception {
1607 final String html = DOCTYPE_HTML
1608 + "<html><head><script>\n"
1609 + LOG_TITLE_FUNCTION
1610 + "function test() {\n"
1611 + " var elem = document.getElementById('d1');\n"
1612
1613 + " var config = { attributes: true, attributeOldValue: true };\n"
1614 + " var observer = new MutationObserver(function(mutations) {\n"
1615 + " mutations.forEach(function(mutation) {\n"
1616 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
1617 + " });\n"
1618 + " });\n"
1619 + " observer.observe(elem, config);"
1620
1621 + " var list = elem.classList;\n"
1622 + " try {\n"
1623 + " list.toggle('ab e');\n"
1624 + " } catch(e) { logEx(e);}\n"
1625 + " try {\n"
1626 + " list.toggle('');\n"
1627 + " } catch(e) { logEx(e);}\n"
1628 + " log(list.length);\n"
1629 + " log(list.contains('e'));\n"
1630 + " log(list.toggle('e'));\n"
1631 + " log(list.length);\n"
1632 + " log(list.contains('e'));\n"
1633 + " log(list.toggle('e'));\n"
1634 + " log(list.length);\n"
1635 + " log(list.contains('e'));\n"
1636 + "}\n"
1637 + "</script></head><body onload='test()'>\n"
1638 + " <div id='d1' class='a e'></div>\n"
1639 + "</body></html>";
1640
1641 loadPageVerifyTitle2(html);
1642 }
1643
1644
1645
1646
1647 @Test
1648 @Alerts({"none", "block", "none"})
1649 public void toggleStyleCheck() throws Exception {
1650 final String html = DOCTYPE_HTML
1651 + "<html><head>\n"
1652 + "<style>\n"
1653 + " #d1.hidden { display: none; }\n"
1654 + "</style>\n"
1655 + "<script>\n"
1656 + LOG_TITLE_FUNCTION
1657 + "function test() {\n"
1658 + " var div1 = document.getElementById('d1');\n"
1659 + " var list = div1.classList;\n"
1660 + " log(getComputedStyle(div1, null).display);\n"
1661
1662 + " list.toggle('hidden');\n"
1663 + " log(getComputedStyle(div1, null).display);\n"
1664
1665 + " list.toggle('hidden');\n"
1666 + " log(getComputedStyle(div1, null).display);\n"
1667 + "}\n"
1668 + "</script>"
1669 + "</head>\n"
1670 + "<body onload='test()'>\n"
1671 + " <div id='d1' class='hidden'></div>\n"
1672 + "</body></html>";
1673
1674 loadPageVerifyTitle2(html);
1675 }
1676
1677
1678
1679
1680 @Test
1681 @Alerts({"a", "1", "SyntaxError/DOMException", "1", "a", "<div\\sid=\"d1\"\\sclass=\"a\"></div>"})
1682 public void toggleEmptyToken() throws Exception {
1683 toggle("a", "");
1684 }
1685
1686
1687
1688
1689 @Test
1690 @Alerts({"a\\sb", "2", "false", "1", "a",
1691 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1692 "class\\schanged\\sold:\\sa\\sb"})
1693 public void toggleStd() throws Exception {
1694 toggle("a b", "b");
1695 }
1696
1697
1698
1699
1700 @Test
1701 @Alerts({"a\\sb\\sc\\sb\\su", "4", "false", "3", "a\\sc\\su",
1702 "<div\\sid=\"d1\"\\sclass=\"a\\sc\\su\"></div>",
1703 "class\\schanged\\sold:\\sa\\sb\\sc\\sb\\su"})
1704 public void toggleOnce() throws Exception {
1705 toggle("a b c b u", "b");
1706 }
1707
1708
1709
1710
1711 @Test
1712 @Alerts({"a\\sb", "2", "true", "3", "a\\sb\\sab",
1713 "<div\\sid=\"d1\"\\sclass=\"a\\sb\\sab\"></div>",
1714 "class\\schanged\\sold:\\sa\\sb"})
1715 public void toggleNotFound() throws Exception {
1716 toggle("a b", "ab");
1717 }
1718
1719
1720
1721
1722 @Test
1723 @Alerts({"a", "1", "false", "0", "",
1724 "<div\\sid=\"d1\"\\sclass=\"\"></div>",
1725 "class\\schanged\\sold:\\sa"})
1726 public void toggleTheOnly() throws Exception {
1727 toggle("a", "a");
1728 }
1729
1730
1731
1732
1733 @Test
1734 @Alerts({"", "0", "true", "1", "a",
1735 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1736 "class\\schanged\\sold:\\s"})
1737 public void toggleInEmpty() throws Exception {
1738 toggle("", "a");
1739 }
1740
1741
1742
1743
1744 @Test
1745 @Alerts({"", "0", "true", "1", "a",
1746 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1747 "class\\schanged\\sold:\\s"})
1748 public void toggleFromEmpty() throws Exception {
1749 toggle("", "a");
1750 }
1751
1752
1753
1754
1755 @Test
1756 @Alerts({"", "0", "true", "1", "a",
1757 "<div\\sid=\"d1\"\\sclass=\"a\"></div>",
1758 "class\\schanged\\sold:\\snull"})
1759 public void toggleNotDefined() throws Exception {
1760 toggle(null, "a");
1761 }
1762
1763 private void toggle(final String in, final String token) throws Exception {
1764 String html = DOCTYPE_HTML
1765 + "<html><head>\n"
1766 + "<script>\n"
1767 + LOG_TITLE_FUNCTION_NORMALIZE
1768 + " function test() {\n"
1769 + " var elem = document.getElementById('d1');\n"
1770
1771 + " var config = { attributes: true, attributeOldValue: true };\n"
1772 + " var observer = new MutationObserver(function(mutations) {\n"
1773 + " mutations.forEach(function(mutation) {\n"
1774 + " log(mutation.attributeName + ' changed old: ' + mutation.oldValue);\n"
1775 + " });\n"
1776 + " });\n"
1777 + " observer.observe(elem, config);"
1778
1779 + " var list = elem.classList;\n"
1780 + " if (!list) { log('no list'); return; }\n"
1781
1782 + " log(elem.className);\n"
1783 + " log(list.length);\n"
1784 + " try {\n"
1785 + " var res = list.toggle('" + token + "');\n"
1786 + " log(res);\n"
1787 + " } catch(e) { logEx(e);}\n"
1788 + " log(list.length);\n"
1789 + " log(elem.className);\n"
1790 + " log(elem.outerHTML);\n"
1791 + " }\n"
1792 + "</script></head>\n"
1793 + "<body onload='test()'>\n";
1794 if (in == null) {
1795 html += " <div id='d1'></div>\n";
1796 }
1797 else {
1798 html += " <div id='d1' class='" + in + "'></div>\n";
1799 }
1800
1801 html += "</body></html>";
1802
1803 loadPageVerifyTitle2(html);
1804 }
1805
1806
1807
1808
1809 @Test
1810 @Alerts({"value", "done", "number", "0"})
1811 public void keys() throws Exception {
1812 final String html = DOCTYPE_HTML
1813 + "<html><head>\n"
1814 + "<script>\n"
1815 + LOG_TITLE_FUNCTION
1816 + " function test() {\n"
1817 + " var list = document.getElementById('d1').classList;\n"
1818 + " if (!list.keys) {\n"
1819 + " log('not defined');\n"
1820 + " return;\n"
1821 + " }\n"
1822 + " var i = list.keys().next();\n"
1823 + " for (var x in i) {\n"
1824 + " log(x);\n"
1825 + " }\n"
1826 + " var v = i.value;\n"
1827 + " log(typeof v);\n"
1828 + " log(v);\n"
1829 + " }\n"
1830 + "</script>\n"
1831 + "</head><body onload='test()'>\n"
1832 + " <div id='d1' class=' a b g'></div>\n"
1833 + "</body></html>\n";
1834
1835 loadPageVerifyTitle2(html);
1836 }
1837
1838
1839
1840
1841 @Test
1842 @Alerts({"true", "undefined", "function", "undefined", "undefined", "true", "true", "true"})
1843 public void keysPropertyDescriptor() throws Exception {
1844 final String html = DOCTYPE_HTML
1845 + "<html><head>\n"
1846 + "<script>\n"
1847 + LOG_TITLE_FUNCTION
1848 + " function test() {\n"
1849 + " var list = document.getElementById('d1').classList;\n"
1850
1851 + " log('keys' in list);\n"
1852 + " log(Object.getOwnPropertyDescriptor(list, 'keys'));\n"
1853
1854 + " var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(list), 'keys');\n"
1855 + " if (desc === undefined) { log('no keys'); return; }\n"
1856 + " log(typeof desc.value);\n"
1857 + " log(desc.get);\n"
1858 + " log(desc.set);\n"
1859 + " log(desc.writable);\n"
1860 + " log(desc.enumerable);\n"
1861 + " log(desc.configurable);\n"
1862 + " }\n"
1863 + "</script>\n"
1864 + "</head><body onload='test()'>\n"
1865 + " <div id='d1' class=' a b g'></div>\n"
1866 + "</body></html>\n";
1867
1868 loadPageVerifyTitle2(html);
1869 }
1870
1871
1872
1873
1874 @Test
1875 @Alerts({"0", "1", "2"})
1876 public void keysForOf() throws Exception {
1877 final String html = DOCTYPE_HTML
1878 + "<html><head>\n"
1879 + "<script>\n"
1880 + LOG_TITLE_FUNCTION
1881 + " function test() {\n"
1882 + " var list = document.getElementById('d1').classList;\n"
1883 + " if (!list.keys) {\n"
1884 + " log('not defined');\n"
1885 + " return;\n"
1886 + " }\n"
1887 + " for (var i of list.keys()) {\n"
1888 + " log(i);\n"
1889 + " }\n"
1890 + " }\n"
1891 + "</script>\n"
1892 + "</head><body onload='test()'>\n"
1893 + " <div id='d1' class=' a b g'></div>\n"
1894 + "</body></html>\n";
1895
1896 loadPageVerifyTitle2(html);
1897 }
1898
1899
1900
1901
1902 @Test
1903 @Alerts({"0,1,2", ""})
1904 public void objectKeys() throws Exception {
1905 final String html = DOCTYPE_HTML
1906 + "<html><head>\n"
1907 + "<script>\n"
1908 + LOG_TITLE_FUNCTION
1909 + " function test() {\n"
1910 + " var list = document.getElementById('d1').classList;\n"
1911 + " log(Object.keys(list));\n"
1912
1913 + " var list = document.getElementById('b1').classList;\n"
1914 + " log(Object.keys(list));\n"
1915 + " }\n"
1916 + "</script>\n"
1917 + "</head><body onload='test()' id='b1'>\n"
1918 + " <div id='d1' class=' a b g'></div>\n"
1919 + "</body></html>\n";
1920
1921 loadPageVerifyTitle2(html);
1922 }
1923
1924
1925
1926
1927 @Test
1928 @Alerts({"value", "done", "string", "a"})
1929 public void values() throws Exception {
1930 final String html = DOCTYPE_HTML
1931 + "<html><head>\n"
1932 + "<script>\n"
1933 + LOG_TITLE_FUNCTION
1934 + " function test() {\n"
1935 + " var list = document.getElementById('d1').classList;\n"
1936 + " if (!list.values) {\n"
1937 + " log('not defined');\n"
1938 + " return;\n"
1939 + " }\n"
1940 + " var i = list.values().next();\n"
1941 + " for (var x in i) {\n"
1942 + " log(x);\n"
1943 + " }\n"
1944 + " var v = i.value;\n"
1945 + " log(typeof v);\n"
1946 + " log(v);\n"
1947 + " }\n"
1948 + "</script>\n"
1949 + "</head><body onload='test()'>\n"
1950 + " <div id='d1' class=' a b g'></div>\n"
1951 + "</body></html>\n";
1952
1953 loadPageVerifyTitle2(html);
1954 }
1955
1956
1957
1958
1959 @Test
1960 @Alerts({"true", "undefined", "function", "undefined", "undefined", "true", "true", "true"})
1961 public void valuesPropertyDescriptor() throws Exception {
1962 final String html = DOCTYPE_HTML
1963 + "<html><head>\n"
1964 + "<script>\n"
1965 + LOG_TITLE_FUNCTION
1966 + " function test() {\n"
1967 + " var list = document.getElementById('d1').classList;\n"
1968
1969 + " log('values' in list);\n"
1970 + " log(Object.getOwnPropertyDescriptor(list, 'values'));\n"
1971
1972 + " var desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(list), 'values');\n"
1973 + " if (desc === undefined) { log('no values'); return; }\n"
1974 + " log(typeof desc.value);\n"
1975 + " log(desc.get);\n"
1976 + " log(desc.set);\n"
1977 + " log(desc.writable);\n"
1978 + " log(desc.enumerable);\n"
1979 + " log(desc.configurable);\n"
1980 + " }\n"
1981 + "</script>\n"
1982 + "</head><body onload='test()'>\n"
1983 + " <div id='d1' class=' a b g'></div>\n"
1984 + "</body></html>\n";
1985
1986 loadPageVerifyTitle2(html);
1987 }
1988
1989
1990
1991
1992 @Test
1993 @Alerts({"a", "b", "g"})
1994 public void valuesForOf() throws Exception {
1995 final String html = DOCTYPE_HTML
1996 + "<html><head>\n"
1997 + "<script>\n"
1998 + LOG_TITLE_FUNCTION
1999 + " function test() {\n"
2000 + " var list = document.getElementById('d1').classList;\n"
2001 + " if (!list.values) {\n"
2002 + " log('not defined');\n"
2003 + " return;\n"
2004 + " }\n"
2005 + " for (var i of list.values()) {\n"
2006 + " log(i);\n"
2007 + " }\n"
2008 + " }\n"
2009 + "</script>\n"
2010 + "</head><body onload='test()'>\n"
2011 + " <div id='d1' class=' a b g'></div>\n"
2012 + "</body></html>\n";
2013
2014 loadPageVerifyTitle2(html);
2015 }
2016
2017
2018
2019
2020 @Test
2021 @Alerts("\\sa\\sb\\sa\\s\\s\\s\\sa\\sg\\s\\s")
2022 public void getValue() throws Exception {
2023 final String html = DOCTYPE_HTML
2024 + "<html><head>\n"
2025 + "<script>\n"
2026 + LOG_TITLE_FUNCTION_NORMALIZE
2027 + " function test() {\n"
2028 + " var list = document.getElementById('d1').classList;\n"
2029 + " if (!list.values) {\n"
2030 + " log('not defined');\n"
2031 + " return;\n"
2032 + " }\n"
2033 + " log(list.value);\n"
2034 + " }\n"
2035 + "</script>\n"
2036 + "</head><body onload='test()'>\n"
2037 + " <div id='d1' class=' a b a a g '></div>\n"
2038 + "</body></html>\n";
2039
2040 loadPageVerifyTitle2(html);
2041 }
2042
2043
2044
2045
2046 @Test
2047 @Alerts({"\\sa\\sb\\sa\\s\\s\\s\\sa\\sg\\s\\s", "x\\sy", "z\\sz\\s\\s\\s\\s\\sx\\sz\\s\\s"})
2048 public void setValue() throws Exception {
2049 final String html = DOCTYPE_HTML
2050 + "<html><head>\n"
2051 + "<script>\n"
2052 + LOG_TITLE_FUNCTION_NORMALIZE
2053 + " function test() {\n"
2054 + " var list = document.getElementById('d1').classList;\n"
2055 + " if (!list.values) {\n"
2056 + " log('not defined');\n"
2057 + " return;\n"
2058 + " }\n"
2059 + " log(list.value);\n"
2060
2061 + " list.value = 'x y';\n"
2062 + " log(list.value);\n"
2063
2064 + " list.value = 'z z x z ';\n"
2065 + " log(list.value);\n"
2066
2067 + " }\n"
2068 + "</script>\n"
2069 + "</head><body onload='test()'>\n"
2070 + " <div id='d1' class=' a b a a g '></div>\n"
2071 + "</body></html>\n";
2072
2073 loadPageVerifyTitle2(html);
2074 }
2075
2076
2077
2078
2079 @Test
2080 @Alerts({"a b", "<div id=\"d1\" class=\"a b\"></div>", "", "<div id=\"d1\" class=\"\"></div>",
2081 "undefined", "<div id=\"d1\" class=\"undefined\"></div>",
2082 "null", "<div id=\"d1\" class=\"null\"></div>",
2083 "17", "<div id=\"d1\" class=\"17\"></div>"})
2084 public void setValueEmpty() throws Exception {
2085 final String html = DOCTYPE_HTML
2086 + "<html><head>\n"
2087 + "<script>\n"
2088 + LOG_TITLE_FUNCTION
2089 + " function test() {\n"
2090 + " var div = document.getElementById('d1');\n"
2091 + " var list = div.classList;\n"
2092 + " if (!list.values) {\n"
2093 + " log('not defined');\n"
2094 + " return;\n"
2095 + " }\n"
2096 + " log(list.value);\n"
2097 + " log(div.outerHTML);\n"
2098
2099 + " list.value = '';\n"
2100 + " log(list.value);\n"
2101 + " log(div.outerHTML);\n"
2102
2103 + " list.value = undefined;\n"
2104 + " log(list.value);\n"
2105 + " log(div.outerHTML);\n"
2106
2107 + " list.value = null;\n"
2108 + " log(list.value);\n"
2109 + " log(div.outerHTML);\n"
2110
2111
2112 + " list.value = 17;\n"
2113 + " log(list.value);\n"
2114 + " log(div.outerHTML);\n"
2115
2116 + " }\n"
2117 + "</script>\n"
2118 + "</head><body onload='test()'>\n"
2119 + " <div id='d1' class='a b'></div>\n"
2120 + "</body></html>\n";
2121
2122 loadPageVerifyTitle2(html);
2123 }
2124 }