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.junit.jupiter.api.Test;
20
21
22
23
24
25
26
27
28
29
30 public class RangeTest extends WebDriverTestCase {
31
32 private static final String CONTENT_START = DOCTYPE_HTML
33 + "<html><head><title></title>\n"
34 + "<script>\n"
35 + LOG_TITLE_FUNCTION
36 + "function safeTagName(o) {\n"
37 + " return o ? (o.tagName ? o.tagName : o) : undefined;\n"
38 + "}\n"
39 + "function alertRange(r) {\n"
40 + " log(r.collapsed);\n"
41 + " log(safeTagName(r.commonAncestorContainer));\n"
42 + " log(safeTagName(r.startContainer));\n"
43 + " log(r.startOffset);\n"
44 + " log(safeTagName(r.endContainer));\n"
45 + " log(r.endOffset);\n"
46 + "}\n"
47 + "function test() {\n"
48 + " var r = document.createRange();\n";
49
50 private static final String CONTENT_END = "\n}\n</script></head>\n"
51 + "<body onload='test()'>\n"
52 + "<div id='theDiv'>Hello, <span id='theSpan'>this is a test for"
53 + "<a id='theA' href='http://htmlunit.sf.net'>HtmlUnit</a> support"
54 + "</div>\n"
55 + "<p id='theP'>for Range</p>\n"
56 + "</body></html>";
57
58
59
60
61 @Test
62 @Alerts({"true", "[object HTMLDocument]", "[object HTMLDocument]", "0", "[object HTMLDocument]", "0"})
63 public void emptyRange() throws Exception {
64 loadPageVerifyTitle2(CONTENT_START + "alertRange(r);" + CONTENT_END);
65 }
66
67
68
69
70 @Test
71 @Alerts({"false", "BODY", "BODY", "1", "BODY", "2"})
72 public void selectNode() throws Exception {
73 final String script = "r.selectNode(document.getElementById('theDiv'));"
74 + "alertRange(r);";
75
76 loadPageVerifyTitle2(CONTENT_START + script + CONTENT_END);
77 }
78
79
80
81
82 @Test
83 @Alerts({"false", "DIV", "DIV", "0", "DIV", "2"})
84 public void selectNodeContents() throws Exception {
85 final String script = "r.selectNodeContents(document.getElementById('theDiv'));"
86 + "alertRange(r);";
87
88 loadPageVerifyTitle2(CONTENT_START + script + CONTENT_END);
89 }
90
91
92
93
94 @Test
95 @Alerts("<div id=\"myDiv2\"></div><div>harhar</div><div id=\"myDiv3\"></div>")
96 public void createContextualFragment() throws Exception {
97 final String html = DOCTYPE_HTML
98 + "<html><head>\n"
99 + "<script>\n"
100 + LOG_TITLE_FUNCTION
101 + " function test() {\n"
102 + " var element = document.getElementById('myDiv2');\n"
103 + " var range = element.ownerDocument.createRange();\n"
104 + " range.setStartAfter(element);\n"
105 + " var fragment = range.createContextualFragment('<div>harhar</div>');\n"
106 + " element.parentNode.insertBefore(fragment, element.nextSibling);\n"
107 + " log(element.parentNode.innerHTML);\n"
108 + " }\n"
109 + "</script></head><body onload='test()'>\n"
110 + " <div id='myDiv'><div id='myDiv2'></div><div id='myDiv3'></div></div>\n"
111 + "</body></html>";
112
113 loadPageVerifyTitle2(html);
114 }
115
116
117
118
119
120 @Test
121 @Alerts({"[object Text]", "[object HTMLTableRowElement]"})
122 public void createContextualFragment2() throws Exception {
123 final String html = DOCTYPE_HTML
124 + "<html><body>\n"
125 + "<div id ='d'></div>\n"
126 + "<table><tr id='t'><td>old</td></tr></table>\n"
127 + "<script>\n"
128 + LOG_TITLE_FUNCTION
129 + "function test(id) {\n"
130 + " var element = document.getElementById(id);\n"
131 + " var range = element.ownerDocument.createRange();\n"
132 + " range.selectNode(element);\n"
133 + " var str = '<tr> <td>new</td></tr>';\n"
134 + " var fragment = range.createContextualFragment(str);\n"
135 + " log(fragment.firstChild);\n"
136 + "}\n"
137 + "try {\n"
138 + " test('d');\n"
139 + " test('t');\n"
140 + "} catch(e) { logEx(e); }\n"
141 + "</script>\n"
142 + "</body></html>";
143
144 loadPageVerifyTitle2(html);
145 }
146
147
148
149
150 @Test
151 @Alerts("<div id=\"myDiv2\"></div>hello:<div id=\"myDiv3\"></div>")
152 public void createContextualStrangeCode() throws Exception {
153 final String html = DOCTYPE_HTML
154 + "<html><head>\n"
155 + "<script>\n"
156 + LOG_TITLE_FUNCTION
157 + " function test() {\n"
158 + " var element = document.getElementById('myDiv2');\n"
159 + " var range = element.ownerDocument.createRange();\n"
160 + " range.setStartAfter(element);\n"
161 + " var fragment = range.createContextualFragment('hello:<world');\n"
162 + " element.parentNode.insertBefore(fragment, element.nextSibling);\n"
163 + " log(element.parentNode.innerHTML);\n"
164 + " }\n"
165 + "</script></head><body onload='test()'>\n"
166 + " <div id='myDiv'><div id='myDiv2'></div><div id='myDiv3'></div></div>\n"
167 + "</body></html>";
168
169 loadPageVerifyTitle2(html);
170 }
171
172
173
174
175 @Test
176 @Alerts({"qwerty", "tyxy", "[object DocumentFragment]", "[object HTMLSpanElement] [object Text]", "qwer",
177 "[object HTMLSpanElement]"})
178 public void extractContents() throws Exception {
179 final String html = DOCTYPE_HTML
180 + "<html><body><div id='d'>abc<span id='s'>qwerty</span>xyz</div>\n"
181 + "<script>\n"
182 + LOG_TITLE_FUNCTION
183 + " var d = document.getElementById('d');\n"
184 + " var s = document.getElementById('s');\n"
185 + " var r = document.createRange();\n"
186 + " r.setStart(s.firstChild, 4);\n"
187 + " r.setEnd(d.childNodes[2], 2);\n"
188 + " log(s.innerHTML);\n"
189 + " log(r);\n"
190 + " var fragment = r.extractContents();\n"
191 + " log(fragment);\n"
192 + " log(fragment.childNodes[0] + ' ' + fragment.childNodes[1]);\n"
193 + " log(s.innerHTML);\n"
194 + " log(document.getElementById('s'));\n"
195 + "</script></body></html>";
196 loadPageVerifyTitle2(html);
197 }
198
199
200
201
202 @Test
203 @Alerts({"1 <p><b id=\"b\">text1<span id=\"s\">inner</span>text2</b></p>",
204 "2 text1",
205 "3 [object DocumentFragment]",
206 "4 1: [object HTMLParagraphElement]: <b id=\"b\">text1</b>",
207 "5 <p><b id=\"b\"><span id=\"s\">inner</span>text2</b></p>",
208 "6 1: [object HTMLParagraphElement]: <b id=\"b\"><span id=\"s\"></span>text2</b>",
209 "7 <p><b id=\"b\"><span id=\"s\">inner</span></b></p>"})
210 public void extractContents2() throws Exception {
211 final String html = DOCTYPE_HTML
212 + "<html><body><div id='d'><p><b id='b'>text1<span id='s'>inner</span>text2</b></p></div>\n"
213 + "<script>\n"
214 + LOG_TITLE_FUNCTION
215 + " var d = document.getElementById('d');\n"
216 + " var b = document.getElementById('b');\n"
217 + " var s = document.getElementById('s');\n"
218 + " var r = document.createRange();\n"
219 + " r.setStart(d, 0);\n"
220 + " r.setEnd(b, 1);\n"
221 + " log('1 ' + d.innerHTML);\n"
222 + " log('2 ' + r);\n"
223 + " var f = r.extractContents();\n"
224 + " log('3 ' + f);\n"
225 + " log('4 ' + f.childNodes.length + ': ' + f.childNodes[0] + ': ' + f.childNodes[0].innerHTML);\n"
226 + " log('5 ' + d.innerHTML);\n"
227 + " var r2 = document.createRange();\n"
228 + " r2.setStart(s, 1);\n"
229 + " r2.setEnd(d, 1);\n"
230 + " var f2 = r2.extractContents();\n"
231 + " log('6 ' + f2.childNodes.length + ': ' + f2.childNodes[0] + ': ' + f2.childNodes[0].innerHTML);\n"
232 + " log('7 ' + d.innerHTML);\n"
233 + "</script></body></html>";
234 loadPageVerifyTitle2(html);
235 }
236
237
238
239
240 @Test
241 @Alerts({"0", "1", "2", "3"})
242 public void constants() throws Exception {
243 final String html = DOCTYPE_HTML
244 + "<html><body>\n"
245 + "<script>\n"
246 + LOG_TITLE_FUNCTION
247 + " log(Range.START_TO_START);\n"
248 + " log(Range.START_TO_END);\n"
249 + " log(Range.END_TO_END);\n"
250 + " log(Range.END_TO_START);\n"
251 + "</script></body></html>";
252 loadPageVerifyTitle2(html);
253 }
254
255
256
257
258 @Test
259 @Alerts({"-1", "1", "1", "-1", "0"})
260 public void compareBoundaryPoints() throws Exception {
261 final String html = DOCTYPE_HTML
262 + "<html><body>\n"
263 + "<div id='d1'><div id='d2'></div></div>\n"
264 + "<script>\n"
265 + LOG_TITLE_FUNCTION
266 + " var range = document.createRange();\n"
267 + " range.selectNode(document.getElementById('d1'));\n"
268 + " var sourceRange = document.createRange();\n"
269 + " sourceRange.selectNode(document.getElementById('d2'));\n"
270 + " log(range.compareBoundaryPoints(Range.START_TO_START, sourceRange));\n"
271 + " log(range.compareBoundaryPoints(Range.START_TO_END, sourceRange));\n"
272 + " log(range.compareBoundaryPoints(Range.END_TO_END, sourceRange));\n"
273 + " log(range.compareBoundaryPoints(Range.END_TO_START, sourceRange));\n"
274 + " log(range.compareBoundaryPoints(Range.START_TO_START, range));\n"
275 + "</script></body></html>";
276 loadPageVerifyTitle2(html);
277 }
278
279
280
281
282 @Test
283 @Alerts({"abcd", "bc", "null", "null", "ad", "bc"})
284 public void extractContents3() throws Exception {
285 final String html = DOCTYPE_HTML
286 + "<html><body><div id='d'><span id='a'>a</span><span id='b'>b</span>"
287 + "<span id='c'>c</span><span id='d'>d</span></div>\n"
288 + "<script>\n"
289 + LOG_TITLE_FUNCTION
290 + " var d = document.getElementById('d');\n"
291 + " var s = document.getElementById('s');\n"
292 + " var r = document.createRange();\n"
293 + " r.setStart(d, 1);\n"
294 + " r.setEnd(d, 3);\n"
295 + " log(d.textContent);\n"
296 + " log(r.toString());\n"
297 + " var x = r.extractContents();\n"
298 + " log(document.getElementById('b'));\n"
299 + " log(document.getElementById('c'));\n"
300 + " log(d.textContent);\n"
301 + " log(x.textContent);\n"
302 + "</script></body></html>";
303 loadPageVerifyTitle2(html);
304 }
305
306
307
308
309 @Test
310 @Alerts({"qwerty", "tyxy", "[object DocumentFragment]", "[object HTMLSpanElement] [object Text]",
311 "qwerty", "[object HTMLSpanElement]"})
312 public void cloneContents() throws Exception {
313 final String html = DOCTYPE_HTML
314 + "<html><body><div id='d'>abc<span id='s'>qwerty</span>xyz</div>\n"
315 + "<script>\n"
316 + LOG_TITLE_FUNCTION
317 + " var d = document.getElementById('d');\n"
318 + " var s = document.getElementById('s');\n"
319 + " var r = document.createRange();\n"
320 + " r.setStart(s.firstChild, 4);\n"
321 + " r.setEnd(d.childNodes[2], 2);\n"
322 + " log(s.innerHTML);\n"
323 + " log(r);\n"
324 + " var fragment = r.cloneContents();\n"
325 + " log(fragment);\n"
326 + " log(fragment.childNodes[0] + ' ' + fragment.childNodes[1]);\n"
327 + " log(s.innerHTML);\n"
328 + " log(document.getElementById('s'));\n"
329 + "</script></body></html>";
330 loadPageVerifyTitle2(html);
331 }
332
333
334
335
336 @Test
337 @Alerts({"qwerty", "bcqwertyxy", "null", "az"})
338 public void deleteContents() throws Exception {
339 final String html = DOCTYPE_HTML
340 + "<html><body><div id='d'>abc<span id='s'>qwerty</span>xyz</div>\n"
341 + "<script>\n"
342 + LOG_TITLE_FUNCTION
343 + " var d = document.getElementById('d');\n"
344 + " var s = document.getElementById('s');\n"
345 + " var r = document.createRange();\n"
346 + " r.setStart(d.firstChild, 1);\n"
347 + " r.setEnd(d.childNodes[2], 2);\n"
348 + " log(s.innerHTML);\n"
349 + " log(r.toString());\n"
350 + " r.deleteContents();\n"
351 + " log(document.getElementById('s'));\n"
352 + " log(d.textContent);\n"
353 + "</script></body></html>";
354 loadPageVerifyTitle2(html);
355 }
356
357
358
359
360 @Test
361 @Alerts({"abcd", "bc", "null", "null", "ad"})
362 public void deleteContents2() throws Exception {
363 final String html = DOCTYPE_HTML
364 + "<html><body><div id='d'><span id='a'>a</span><span id='b'>b</span><span id='c'>c</span>"
365 + "<span id='d'>d</span></div>\n"
366 + "<script>\n"
367 + LOG_TITLE_FUNCTION
368 + " var d = document.getElementById('d');\n"
369 + " var s = document.getElementById('s');\n"
370 + " var r = document.createRange();\n"
371 + " r.setStart(d, 1);\n"
372 + " r.setEnd(d, 3);\n"
373 + " log(d.textContent);\n"
374 + " log(r.toString());\n"
375 + " r.deleteContents();\n"
376 + " log(document.getElementById('b'));\n"
377 + " log(document.getElementById('c'));\n"
378 + " log(d.textContent);\n"
379 + "</script></body></html>";
380 loadPageVerifyTitle2(html);
381 }
382
383
384
385
386 @Test
387 @Alerts("0")
388 public void getClientRectsEmpty() throws Exception {
389 final String html = DOCTYPE_HTML
390 + "<html>\n"
391 + "<body>\n"
392 + " <div id='d'>a</div>\n"
393 + "<script>\n"
394 + LOG_TITLE_FUNCTION
395 + " var d = document.getElementById('d');\n"
396 + " var r = document.createRange();\n"
397 + " log(r.getClientRects().length);\n"
398 + "</script>\n"
399 + "</body>\n"
400 + "</html>\n";
401 loadPageVerifyTitle2(html);
402 }
403
404
405
406
407 @Test
408 @Alerts("true")
409 public void getClientRectsMany() throws Exception {
410 final String html = DOCTYPE_HTML
411 + "<html><body><div id='d'><span id='a'>a</span><span id='b'>b</span><span id='c'>c</span>"
412 + "<span id='d'>d</span></div>\n"
413 + "<script>\n"
414 + LOG_TITLE_FUNCTION
415 + " var d = document.getElementById('d');\n"
416 + " var s = document.getElementById('s');\n"
417 + " var r = document.createRange();\n"
418 + " r.setStart(d, 1);\n"
419 + " r.setEnd(d, 3);\n"
420 + " log(r.getClientRects().length > 1);\n"
421 + "</script></body></html>";
422 loadPageVerifyTitle2(html);
423 }
424
425
426
427
428
429
430 @Test
431 @Alerts("[object HTMLBodyElement]")
432 public void getBoundingClientRectDoesNotChangeTheParent() throws Exception {
433 final String html = DOCTYPE_HTML
434 + "<html><head>\n"
435 + "<script>\n"
436 + LOG_TITLE_FUNCTION
437 + "function doTest() {\n"
438 + " var range = document.createRange();\n"
439
440 + " var elem = document.createElement('boundtest');\n"
441 + " document.body.appendChild(elem);\n"
442
443 + " range.selectNode(elem);\n"
444 + " range.getBoundingClientRect();\n"
445
446 + " log(elem.parentNode);\n"
447 + "}\n"
448 + "</script>\n"
449 + "</head>\n"
450 + "<body onload='doTest()'>\n"
451 + "</body></html>";
452
453 loadPageVerifyTitle2(html);
454 }
455
456
457
458
459
460
461 @Test
462 @Alerts("[object HTMLBodyElement]")
463 public void getClientRectsDoesNotChangeTheParent() throws Exception {
464 final String html = DOCTYPE_HTML
465 + "<html><head>\n"
466 + "<script>\n"
467 + LOG_TITLE_FUNCTION
468 + "function doTest() {\n"
469 + " var range = document.createRange();\n"
470
471 + " var elem = document.createElement('boundtest');\n"
472 + " document.body.appendChild(elem);\n"
473
474 + " range.selectNode(elem);\n"
475 + " range.getClientRects();\n"
476
477 + " log(elem.parentNode);\n"
478 + "}\n"
479 + "</script>\n"
480 + "</head>\n"
481 + "<body onload='doTest()'>\n"
482 + "</body></html>";
483
484 loadPageVerifyTitle2(html);
485 }
486
487
488
489
490 @Test
491 @Alerts({"tyxy", "tyxy", "tyxy"})
492 public void testToString() throws Exception {
493 final String html = DOCTYPE_HTML
494 + "<html><body><div id='d'>abc<span id='s'>qwerty</span>xyz</div>\n"
495 + "<script>\n"
496 + LOG_TITLE_FUNCTION
497 + " var d = document.getElementById('d');\n"
498 + " var s = document.getElementById('s');\n"
499 + " var r = document.createRange();\n"
500 + " r.setStart(s.firstChild, 4);\n"
501 + " r.setEnd(d.childNodes[2], 2);\n"
502 + " log(r);\n"
503 + " log('' + r);\n"
504 + " log(r.toString());\n"
505 + "</script></body></html>";
506 loadPageVerifyTitle2(html);
507 }
508 }