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