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