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 @RunWith(BrowserRunner.class)
32 public class SelectionTest extends WebDriverTestCase {
33
34
35
36
37 @Test
38 @Alerts("true")
39 public void equality_selection() throws Exception {
40 final String html = DOCTYPE_HTML
41 + "<html>\n"
42 + "<body>\n"
43 + "<script>"
44 + LOG_TITLE_FUNCTION
45 + "log(document.selection==document.selection);\n"
46 + "</script>\n"
47 + "</body></html>";
48 loadPageVerifyTitle2(html);
49 }
50
51
52
53
54 @Test
55 @Alerts("true")
56 public void equality_getSelection() throws Exception {
57 final String html = DOCTYPE_HTML
58 + "<html><body>\n"
59 + "<script>\n"
60 + LOG_TITLE_FUNCTION
61 + "try {\n"
62 + " log(window.getSelection()==window.getSelection());\n"
63 + "} catch(e) { logEx(e) }\n"
64 + "</script>\n"
65 + "</body></html>";
66 loadPageVerifyTitle2(html);
67 }
68
69
70
71
72 @Test
73 @Alerts({"0", "0", "0", "cdefg"})
74 public void inputSelectionsAreIndependent() throws Exception {
75 final String html = DOCTYPE_HTML
76 + "<html><body onload='test()'>\n"
77 + "<input id='i' value='abcdefghi'/>\n"
78 + "<script>\n"
79 + LOG_TITLE_FUNCTION
80 + " function test() {\n"
81 + " var i = document.getElementById('i');\n"
82 + " var s = window.getSelection();\n"
83 + " log(s.rangeCount);\n"
84 + " i.selectionStart = 2;\n"
85 + " log(s.rangeCount);\n"
86 + " i.selectionEnd = 7;\n"
87 + " log(s.rangeCount);\n"
88 + " log(i.value.substring(i.selectionStart, i.selectionEnd));\n"
89 + " }\n"
90 + "</script>\n"
91 + "</body></html>";
92 loadPageVerifyTitle2(html);
93 }
94
95
96
97
98 @Test
99 @Alerts({"1:null/0/null/0/true/None/0/",
100 "2:s2/0/s2/1/false/Range/1/xyz[xyz"})
101 public void selectAllChildren() throws Exception {
102 final String jsSnippet = ""
103 + " alertSelection(selection);\n"
104 + " selection.selectAllChildren(s2);\n"
105 + " alertSelection(selection);\n";
106
107 tester(jsSnippet);
108 }
109
110
111
112
113 @Test
114 @Alerts({"1:s2/0/s2/1/false/Range/1/xyz[xyz",
115 "2:s2/0/s3/1/false/Range/1/xyzfoo[xyzfoo",
116 "3:s2/0/s3/2/false/Range/1/xyzfoo---[xyzfoo---",
117 "4:s2/0/s3/3/false/Range/1/xyzfoo---foo[xyzfoo---foo"})
118 public void extend() throws Exception {
119 final String jsSnippet = ""
120 + " selection.selectAllChildren(s2);\n"
121 + " alertSelection(selection);\n"
122 + " if (selection.extend) {\n"
123 + " selection.extend(s3, 1);\n"
124 + " alertSelection(selection);\n"
125 + " selection.extend(s3, 2);\n"
126 + " alertSelection(selection);\n"
127 + " selection.extend(s3, 3);\n"
128 + " alertSelection(selection);\n"
129 + " } else { log('selection.extend not available'); }\n";
130
131 tester(jsSnippet);
132 }
133
134
135
136
137 @Test
138 @Alerts({"1:s2/0/s2/1/false/Range/1/xyz[xyz",
139 "2:s2/0/s2/0/true/Caret/1/["})
140 public void collapseToStart() throws Exception {
141 final String jsSnippet = ""
142 + " selection.selectAllChildren(s2);\n"
143 + " alertSelection(selection);\n"
144 + " selection.collapseToStart();\n"
145 + " alertSelection(selection);\n";
146
147 tester(jsSnippet);
148 }
149
150
151
152
153 @Test
154 @Alerts({"1:s2/0/s2/1/false/Range/1/xyz[xyz",
155 "2:s2/1/s2/1/true/Caret/1/["})
156 public void collapseToEnd() throws Exception {
157 final String jsSnippet = ""
158 + " selection.selectAllChildren(s2);\n"
159 + " alertSelection(selection);\n"
160 + " selection.collapseToEnd();\n"
161 + " alertSelection(selection);\n";
162
163 tester(jsSnippet);
164 }
165
166
167
168
169 @Test
170 @Alerts({"1:s2/0/s2/1/false/Range/1/xyz[xyz",
171 "2:null/0/null/0/true/None/0/"})
172 public void empty() throws Exception {
173 final String jsSnippet = ""
174 + " selection.selectAllChildren(s2);\n"
175 + " alertSelection(selection);\n"
176 + " selection.empty();\n"
177 + " alertSelection(selection);\n";
178
179 tester(jsSnippet);
180 }
181
182
183
184
185 @Test
186 @Alerts({"1:null/0/null/0/true/None/0/",
187 "2:null/0/null/0/true/None/0/",
188 "3:s2/1/s3/1/false/Range/1/foo[foo"})
189 public void addRange() throws Exception {
190 final String jsSnippet = ""
191 + " alertSelection(selection);\n"
192
193 + " var range = document.createRange();\n"
194 + " range.setStart(s2, 1);\n"
195 + " range.setEnd(s3, 1);\n"
196 + " alertSelection(selection);\n"
197
198 + " selection.addRange(range);\n"
199 + " alertSelection(selection);\n";
200
201 tester(jsSnippet);
202 }
203
204
205
206
207 @Test
208 @Alerts({"1:null/0/null/0/true/None/0/",
209 "2:s1/1/s3/1/false/Range/1/xyzfoo[xyzfoo",
210 "3:null/0/null/0/true/None/0/"})
211 public void removeAllRanges() throws Exception {
212 final String jsSnippet = ""
213 + " alertSelection(selection);\n"
214
215 + " var range = document.createRange();\n"
216 + " range.setStart(s1, 1);\n"
217 + " range.setEnd(s3, 1);\n"
218 + " selection.addRange(range);\n"
219 + " alertSelection(selection);\n"
220
221 + " selection.removeAllRanges();\n"
222 + " alertSelection(selection);\n";
223
224 tester(jsSnippet);
225 }
226
227
228
229
230 @Test
231 @Alerts({"1:s1/1/s3/1/false/Range/1/xyzfoo[xyzfoo",
232 "2:null/0/null/0/true/None/0/"})
233 public void removeAllRanges2() throws Exception {
234 final String jsSnippet = ""
235 + " var range = document.createRange();\n"
236 + " range.setStart(s1, 1);\n"
237 + " range.setEnd(s3, 1);\n"
238 + " selection.addRange(range);\n"
239 + " alertSelection(selection);\n"
240
241 + " selection.removeAllRanges();\n"
242 + " alertSelection(selection);\n";
243
244 tester(jsSnippet);
245 }
246
247
248
249
250 @Test
251 @Alerts(DEFAULT = {"1:null/0/null/0/true/None/0/",
252 "2:s1/0/s1/1/false/Range/1/abc[abc",
253 "3:null/0/null/0/true/None/0/"},
254 FF = {"1:null/0/null/0/true/None/0/",
255 "2:s1/1/s3/1/false/Range/2/abcxyzfoo[abc[xyzfoo",
256 "3:null/0/null/0/true/None/0/"},
257 FF_ESR = {"1:null/0/null/0/true/None/0/",
258 "2:s1/1/s3/1/false/Range/2/abcxyzfoo[abc[xyzfoo",
259 "3:null/0/null/0/true/None/0/"})
260 @HtmlUnitNYI(CHROME = {"1:null/0/null/0/true/None/0/",
261 "2:s1/0/s1/1/false/Range/2/abcxyzfoo[abc[xyzfoo",
262 "3:null/0/null/0/true/None/0/"},
263 EDGE = {"1:null/0/null/0/true/None/0/",
264 "2:s1/0/s1/1/false/Range/2/abcxyzfoo[abc[xyzfoo",
265 "3:null/0/null/0/true/None/0/"},
266 FF = {"1:null/0/null/0/true/None/0/",
267 "2:s1/0/s1/1/false/Range/2/abcxyzfoo[abc[xyzfoo",
268 "3:null/0/null/0/true/None/0/"},
269 FF_ESR = {"1:null/0/null/0/true/None/0/",
270 "2:s1/0/s1/1/false/Range/2/abcxyzfoo[abc[xyzfoo",
271 "3:null/0/null/0/true/None/0/"})
272 public void selectAllChildrenAddRange() throws Exception {
273 final String jsSnippet = ""
274 + " alertSelection(selection);\n"
275
276 + " selection.selectAllChildren(s1);\n"
277 + " var range = document.createRange();\n"
278 + " range.setStart(s1, 1);\n"
279 + " range.setEnd(s3, 1);\n"
280 + " selection.addRange(range);\n"
281 + " alertSelection(selection);\n"
282
283 + " selection.removeAllRanges();\n"
284 + " alertSelection(selection);\n";
285
286 tester(jsSnippet);
287 }
288
289
290
291
292 @Test
293 @Alerts({"1:null/0/null/0/true/None/0/",
294 "2:s1/0/s1/1/false/Range/1/abc[abc",
295 "3:null/0/null/0/true/None/0/"})
296 public void addRangeSelectAllChildren() throws Exception {
297 final String jsSnippet = ""
298 + " alertSelection(selection);\n"
299
300 + " var range = document.createRange();\n"
301 + " range.setStart(s1, 1);\n"
302 + " range.setEnd(s3, 1);\n"
303 + " selection.addRange(range);\n"
304 + " selection.selectAllChildren(s1);\n"
305 + " alertSelection(selection);\n"
306
307 + " selection.removeAllRanges();\n"
308 + " alertSelection(selection);\n";
309
310 tester(jsSnippet);
311 }
312
313
314
315
316 @Test
317 @Alerts(DEFAULT = {"1:null/0/null/0/true/None/0/",
318 "2:s1/0/s1/1/false/Range/1/abc[abc",
319 "3:s1/0/s1/1/false/Range/1/abc[abc",
320 "4:null/0/null/0/true/None/0/"},
321 FF = {"1:null/0/null/0/true/None/0/",
322 "2:s1/1/s2/1/false/Range/2/abcxyz[abc[xyz",
323 "3:s2/1/s3/3/false/Range/3/abcxyzfoo---foo[abc[xyz[foo---foo",
324 "4:null/0/null/0/true/None/0/"},
325 FF_ESR = {"1:null/0/null/0/true/None/0/",
326 "2:s1/1/s2/1/false/Range/2/abcxyz[abc[xyz",
327 "3:s2/1/s3/3/false/Range/3/abcxyzfoo---foo[abc[xyz[foo---foo",
328 "4:null/0/null/0/true/None/0/"})
329 @HtmlUnitNYI(CHROME = {"1:null/0/null/0/true/None/0/",
330 "2:s1/0/s1/1/false/Range/2/abcxyz[abc[xyz",
331 "3:s2/1/s3/3/false/Range/3/abcxyzfoo---foo[abc[xyz[foo---foo",
332 "4:null/0/null/0/true/None/0/"},
333 EDGE = {"1:null/0/null/0/true/None/0/",
334 "2:s1/0/s1/1/false/Range/2/abcxyz[abc[xyz",
335 "3:s2/1/s3/3/false/Range/3/abcxyzfoo---foo[abc[xyz[foo---foo",
336 "4:null/0/null/0/true/None/0/"},
337 FF = {"1:null/0/null/0/true/None/0/",
338 "2:s1/0/s1/1/false/Range/2/abcxyz[abc[xyz",
339 "3:s2/1/s3/3/false/Range/3/abcxyzfoo---foo[abc[xyz[foo---foo",
340 "4:null/0/null/0/true/None/0/"},
341 FF_ESR = {"1:null/0/null/0/true/None/0/",
342 "2:s1/0/s1/1/false/Range/2/abcxyz[abc[xyz",
343 "3:s2/1/s3/3/false/Range/3/abcxyzfoo---foo[abc[xyz[foo---foo",
344 "4:null/0/null/0/true/None/0/"})
345 public void addRangeAddRange() throws Exception {
346 final String jsSnippet = ""
347 + " alertSelection(selection);\n"
348
349 + " selection.selectAllChildren(s1);\n"
350 + " var range = document.createRange();\n"
351 + " range.setStart(s1, 1);\n"
352 + " range.setEnd(s2, 1);\n"
353 + " selection.addRange(range);\n"
354 + " alertSelection(selection);\n"
355
356 + " var range = document.createRange();\n"
357 + " range.setStart(s2, 1);\n"
358 + " range.setEnd(s3, 3);\n"
359 + " selection.addRange(range);\n"
360 + " alertSelection(selection);\n"
361
362 + " selection.removeAllRanges();\n"
363 + " alertSelection(selection);\n";
364
365 tester(jsSnippet);
366 }
367
368
369
370
371
372
373 @Test
374 @Alerts({"1:[object Text]/1/[object Text]/2/false/Range/1/yzfo[yzfo",
375 "2:null/0/null/0/true/None/0/",
376 "false", "true"})
377 public void aLittleBitOfEverything_removeRange() throws Exception {
378 final String jsSnippet = ""
379 + " var range = document.createRange();\n"
380 + " range.setStart(s2.firstChild, 1);\n"
381 + " range.setEnd(s3.firstChild, 2);\n"
382 + " selection.addRange(range);\n"
383 + " alertSelection(selection);\n"
384 + " selection.removeRange(range);\n"
385 + " alertSelection(selection);\n"
386 + " log(range.collapsed);\n"
387 + " selection.addRange(range);\n"
388 + " log(selection.getRangeAt(0) == selection.getRangeAt(0));\n";
389
390 tester(jsSnippet);
391 }
392
393 private void tester(final String jsSnippet) throws Exception {
394 final String html = DOCTYPE_HTML
395 + "<html>\n"
396 + "<body onload='test()'>\n"
397 + " <span id='s1'>abc</span><span id='s2'>xyz</span><span id='s3'>foo<span>---</span>foo</span>\n"
398
399 + "<script>\n"
400 + LOG_TITLE_FUNCTION
401 + " var x = 1;\n"
402 + " function test() {\n"
403 + " var selection = window.getSelection();\n"
404 + " var s1 = document.getElementById('s1');\n"
405 + " var s2 = document.getElementById('s2');\n"
406 + " var s3 = document.getElementById('s3');\n"
407 + " try {\n"
408 + jsSnippet
409 + " } catch(e) { logEx(e); }\n"
410 + " }\n"
411
412 + " function alertSelection(s) {\n"
413 + " var anchorNode = (s.anchorNode && s.anchorNode.id ? s.anchorNode.id : s.anchorNode);\n"
414 + " var focusNode = (s.focusNode && s.focusNode.id ? s.focusNode.id : s.focusNode);\n"
415 + " var msg = (x++) + ':' + anchorNode + '/' + s.anchorOffset + '/' + focusNode + '/' +\n"
416 + " s.focusOffset + '/' + s.isCollapsed + '/' + s.type + '/' + s.rangeCount + '/' + s;\n"
417 + " for(var i = 0; i < s.rangeCount; i++) {\n"
418 + " msg += '[' + s.getRangeAt(i);\n"
419 + " }\n"
420 + " log(msg);\n"
421 + " }\n"
422 + "</script>\n"
423 + "</body></html>";
424 loadPageVerifyTitle2(html);
425 }
426
427
428
429
430 @Test
431 @Alerts(DEFAULT = {"", "null-0", "", "null-0", "", "null-0", "", "null-0"},
432 FF = {"", "null-0", "", "null-0", "null", "null"},
433 FF_ESR = {"", "null-0", "", "null-0", "null", "null"})
434 public void getSelection_display() throws Exception {
435 final String html = DOCTYPE_HTML
436 + "<html>\n"
437 + "<body onload='test()'>\n"
438 + " <iframe id='frame1' src='about:blank'></iframe>\n"
439 + " <iframe id='frame2' src='about:blank' style='display: none'></iframe>\n"
440 + " <div style='display: none'>\n"
441 + " <iframe id='frame3' src='about:blank'></iframe>\n"
442 + " </div>\n"
443
444 + " <script>\n"
445 + LOG_TITLE_FUNCTION
446 + " function sel(win) {\n"
447 + " if (win.getSelection) {\n"
448 + " var range = win.getSelection();\n"
449 + " log(range);\n"
450 + " if (range) {\n"
451 + " log(range.anchorNode + '-' + range.rangeCount);\n"
452 + " }\n"
453 + " }\n"
454 + " }\n"
455
456 + " function test() {\n"
457 + " sel(window);\n"
458 + " sel(document.getElementById('frame1').contentWindow);\n"
459 + " sel(document.getElementById('frame2').contentWindow);\n"
460 + " sel(document.getElementById('frame3').contentWindow);\n"
461 + " }\n"
462 + " </script>\n"
463 + "</body></html>";
464 loadPageVerifyTitle2(html);
465 }
466
467
468
469
470 @Test
471 @Alerts({"", "", ""})
472 public void testToString() throws Exception {
473 final String html = DOCTYPE_HTML
474 + "<html>\n"
475 + "<body onload='test()'>\n"
476 + "<input id='i' value='abcdefghi'/>\n"
477 + "<script>\n"
478 + LOG_TITLE_FUNCTION
479 + " function test() {\n"
480 + " var i = document.getElementById('i');\n"
481 + " var s = window.getSelection();\n"
482 + " log(s);\n"
483 + " log('' + s);\n"
484 + " log(s.toString());\n"
485 + " }\n"
486 + "</script>\n"
487 + "</body></html>";
488 loadPageVerifyTitle2(html);
489 }
490 }