|
1 <!DOCTYPE> |
|
2 <html> |
|
3 <head> |
|
4 <title>selection expanding test</title> |
|
5 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
6 <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> |
|
7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
8 |
|
9 <style type="text/css"> |
|
10 .testingDiv { |
|
11 font-size: 16px; |
|
12 width: 300px; |
|
13 height: 140px; |
|
14 background-color: white; |
|
15 } |
|
16 #fixedDiv1, #fixedDiv2 { |
|
17 position: fixed; |
|
18 right: 0; |
|
19 overflow: scroll; |
|
20 width: 200px; |
|
21 } |
|
22 #fixedDiv1 { |
|
23 top: 0; |
|
24 } |
|
25 #fixedDiv2 { |
|
26 top: 150px; |
|
27 } |
|
28 iframe, input, textarea { |
|
29 font-size: 16px; |
|
30 height: 16px; |
|
31 width: 80px; |
|
32 margin: 0; |
|
33 padding: 0; |
|
34 } |
|
35 #xbl { |
|
36 -moz-binding: url(selection_expanding_xbl.xml#binding); |
|
37 } |
|
38 </style> |
|
39 |
|
40 </head> |
|
41 <body> |
|
42 <div id="div1" class="testingDiv"> |
|
43 aaaaaaa |
|
44 <iframe id="iframe" src="data:text/html,<style type='text/css'>*{margin: 0; padding: 0; font-size: 16px;}</style><div>ffffff ffffff ffffff ffffff</div>"></iframe> |
|
45 aaaaaaa aaaaaaa<br>aaaaaaa aaaaaaa aaaaaaa aaaaaaa<br>aaaaaaa |
|
46 </div> |
|
47 <div id="div2" class="testingDiv"> |
|
48 bbbbbbb |
|
49 <input id="input" type="text" value="iiiiiiiii iiiiiiiii iiiiiiiii"> |
|
50 bbbbbbb bbbbbbb<br>bbbbbbb bbbbbbb bbbbbbb<br>bbbbbbb |
|
51 </div> |
|
52 <div id="div3" class="testingDiv"> |
|
53 ccccccc |
|
54 <textarea id="textarea">tttttt tttttt tttttt</textarea> |
|
55 ccccccc ccccccc<br>ccccccc ccccccc ccccccc ccccccc<br>ccccccc |
|
56 <div id="fixedDiv1" class="testingDiv"> |
|
57 dddddd dddddd dddddd |
|
58 </div> |
|
59 </div> |
|
60 <div id="xbl"> |
|
61 <p id="xbl_child">yyyyyyy yyyyyyy yyyyyyy</p> |
|
62 </div> |
|
63 <div id="fixedDiv2" class="testingDiv"> |
|
64 eeeeee eeeeee eeeeee |
|
65 </div> |
|
66 <pre id="test"> |
|
67 <script class="testbody" type="text/javascript"> |
|
68 |
|
69 var div1 = document.getElementById("div1"); |
|
70 var div2 = document.getElementById("div2"); |
|
71 var div3 = document.getElementById("div3"); |
|
72 var xbl = document.getElementById("xbl"); |
|
73 var xbl_child = document.getElementById("xbl_child"); |
|
74 var fixedDiv1 = document.getElementById("fixedDiv1"); |
|
75 var fixedDiv2 = document.getElementById("fixedDiv2"); |
|
76 var iframe = document.getElementById("iframe"); |
|
77 var input = document.getElementById("input"); |
|
78 var textarea = SpecialPowers.wrap(document.getElementById("textarea")); |
|
79 |
|
80 function test() |
|
81 { |
|
82 function getSelectionForEditor(aEditorElement) |
|
83 { |
|
84 const nsIDOMNSEditableElement = SpecialPowers.Ci.nsIDOMNSEditableElement; |
|
85 return SpecialPowers.wrap(aEditorElement).editor.selection; |
|
86 } |
|
87 |
|
88 function clear() |
|
89 { |
|
90 synthesizeMouse(div1, 10, 5, { type: "mouseup" }); |
|
91 var sel = window.getSelection(); |
|
92 if (sel.rangeCount > 0) |
|
93 sel.collapseToEnd(); |
|
94 sel = iframe.contentWindow.getSelection(); |
|
95 if (sel.rangeCount > 0) |
|
96 sel.collapseToEnd(); |
|
97 sel = getSelectionForEditor(input); |
|
98 if (sel.rangeCount > 0) |
|
99 sel.collapseToEnd(); |
|
100 sel = getSelectionForEditor(textarea); |
|
101 if (sel.rangeCount > 0) |
|
102 sel.collapseToEnd(); |
|
103 |
|
104 div1.scrollTop = 0; |
|
105 div1.scrollLeft = 0; |
|
106 div2.scrollTop = 0; |
|
107 div2.scrollLeft = 0; |
|
108 div3.scrollTop = 0; |
|
109 div3.scrollLeft = 0; |
|
110 } |
|
111 |
|
112 const kFalse = 0; |
|
113 const kTrue = 1; |
|
114 const kToDo = 2; |
|
115 |
|
116 function check(aDiv1ShouldBeSelected, |
|
117 aDiv2ShouldBeSelected, |
|
118 aDiv3ShouldBeSelected, |
|
119 aFixedDiv1ShouldBeSelected, |
|
120 aXBLChildShouldBeSelected, |
|
121 aFixedDiv2ShouldBeSelected, |
|
122 aIFrameShouldBeSelected, |
|
123 aInputShouldBeSelected, |
|
124 aTextareaShouldBeSelected, |
|
125 aTestingDescription) |
|
126 { |
|
127 function checkCharacter(aSelectedText, |
|
128 aShouldBeIncludedCharacter, |
|
129 aSouldBeSelected, |
|
130 aElementName) |
|
131 { |
|
132 var boolvalue = aSouldBeSelected & kTrue; |
|
133 var f = aSouldBeSelected & kToDo ? todo : ok; |
|
134 var str = aSelectedText.replace('\n', '\\n'); |
|
135 if (boolvalue) { |
|
136 f(aSelectedText.indexOf(aShouldBeIncludedCharacter) >= 0, |
|
137 "The contents of " + aElementName + |
|
138 " aren't selected (" + aTestingDescription + |
|
139 "): Selected String: \"" + str + "\""); |
|
140 } else { |
|
141 f(aSelectedText.indexOf(aShouldBeIncludedCharacter) < 0, |
|
142 "The contents of " + aElementName + |
|
143 " are selected (" + aTestingDescription + |
|
144 "): Selected String: \"" + str + "\""); |
|
145 } |
|
146 } |
|
147 |
|
148 var sel = window.getSelection().toString(); |
|
149 checkCharacter(sel, "a", aDiv1ShouldBeSelected, "div1"); |
|
150 checkCharacter(sel, "b", aDiv2ShouldBeSelected, "div2"); |
|
151 checkCharacter(sel, "c", aDiv3ShouldBeSelected, "div3"); |
|
152 checkCharacter(sel, "y", aXBLChildShouldBeSelected, "xbl_child"); |
|
153 checkCharacter(sel, "d", aFixedDiv1ShouldBeSelected, "fixedDiv1"); |
|
154 checkCharacter(sel, "e", aFixedDiv2ShouldBeSelected, "fixedDiv2"); |
|
155 |
|
156 // iframe/input/xbl-bound contents must not be included on the parent |
|
157 // selection. |
|
158 checkCharacter(sel, "f", false, "iframe (checking on parent)"); |
|
159 checkCharacter(sel, "i", false, "input (checking on parent)"); |
|
160 checkCharacter(sel, "x", false, "XBL bound contents (checking on parent)"); |
|
161 |
|
162 var selInIFrame = iframe.contentWindow.getSelection().toString(); |
|
163 checkCharacter(selInIFrame, "f", aIFrameShouldBeSelected, "iframe"); |
|
164 |
|
165 var selInput = getSelectionForEditor(input).toString(); |
|
166 checkCharacter(selInput, "i", aInputShouldBeSelected, "input"); |
|
167 var selTextarea = getSelectionForEditor(textarea).toString(); |
|
168 checkCharacter(selTextarea, "t", aTextareaShouldBeSelected, "textarea"); |
|
169 } |
|
170 |
|
171 // *********************************************************** |
|
172 // Set all divs to overflow: auto; |
|
173 const kOverflows = ["visible", "hidden", "scroll", "auto"]; |
|
174 for (var i = 0; i < kOverflows.length; i++) { |
|
175 div1.style.overflow = kOverflows[i]; |
|
176 div2.style.overflow = kOverflows[i]; |
|
177 div3.style.overflow = kOverflows[i]; |
|
178 |
|
179 // *********************************************************** |
|
180 // selection starting at div1 |
|
181 synthesizeMouse(div1, 30, 5, { type: "mousedown" }); |
|
182 |
|
183 // XXX if we move the mouse cursor to another document, the |
|
184 // nsFrameSelection::HandleDrag method is called on the another document's. |
|
185 |
|
186 // to iframe |
|
187 synthesizeMouse(iframe, 30, 5, { type: "mousemove" }); |
|
188 check(kTrue | kToDo, kFalse, kFalse, |
|
189 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
190 "div1-iframe, all boxes are overflow: " + kOverflows[i] + ";"); |
|
191 |
|
192 // XXX if the overflow is visible, synthesizeMouse with the input element |
|
193 // or textarea element doesn't work fine. |
|
194 var isVisibleTesting = kOverflows[i] == "visible"; |
|
195 var todoFlag = isVisibleTesting ? kToDo : 0; |
|
196 // to input |
|
197 synthesizeMouse(input, 30, 5, { type: "mousemove" }); |
|
198 check(kTrue | todoFlag, kTrue | todoFlag, kFalse, |
|
199 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
200 "div1-input, all boxes are overflow: " + kOverflows[i] + ";"); |
|
201 |
|
202 // to textarea |
|
203 synthesizeMouse(textarea, 30, 5, { type: "mousemove" }); |
|
204 check(kTrue | todoFlag, kTrue | todoFlag, kTrue | todoFlag, |
|
205 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
206 "div1-textarea, all boxes are overflow: " + kOverflows[i] + ";"); |
|
207 |
|
208 // to div2 |
|
209 synthesizeMouse(div2, 30, 5, { type: "mousemove" }); |
|
210 check(kTrue, kTrue, kFalse, |
|
211 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
212 "div1-div2, all boxes are overflow: " + kOverflows[i] + ";"); |
|
213 |
|
214 // to div3 |
|
215 synthesizeMouse(div3, 30, 5, { type: "mousemove" }); |
|
216 check(kTrue, kTrue, kTrue, |
|
217 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
218 "div1-div3, all boxes are overflow: " + kOverflows[i] + ";"); |
|
219 |
|
220 // to fixedDiv1 (child of div3) |
|
221 synthesizeMouse(fixedDiv1, 30, 5, { type: "mousemove" }); |
|
222 check(kTrue, kTrue, kTrue, |
|
223 kTrue, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
224 "div1-fixedDiv1, all boxes are overflow: " + kOverflows[i] + ";"); |
|
225 |
|
226 // to xbl_child |
|
227 synthesizeMouse(xbl_child, 30, 5, { type: "mousemove" }); |
|
228 check(kTrue, kTrue, kTrue, |
|
229 kTrue, kTrue, kFalse, kFalse, kFalse, kFalse, |
|
230 "div1-xbl_child, all boxes are overflow: " + kOverflows[i] + ";"); |
|
231 |
|
232 // to fixedDiv2 (sibling of div*) |
|
233 synthesizeMouse(fixedDiv2, 30, 5, { type: "mousemove" }); |
|
234 check(kTrue, kTrue, kTrue, |
|
235 kTrue, kTrue, kTrue, kFalse, kFalse, kFalse, |
|
236 "div1-fixedDiv2, all boxes are overflow: " + kOverflows[i] + ";"); |
|
237 |
|
238 clear(); |
|
239 |
|
240 // *********************************************************** |
|
241 // selection starting at fixedDiv1 |
|
242 synthesizeMouse(fixedDiv1, 30, 5, { type: "mousedown" }); |
|
243 |
|
244 // to xbl_child |
|
245 synthesizeMouse(xbl_child, 30, 5, { type: "mousemove" }); |
|
246 check(kFalse, kFalse, kFalse, |
|
247 kTrue, kTrue, kFalse, kFalse, kFalse, kFalse, |
|
248 "fixedDiv1-xbl_child, all boxes are overflow: " + kOverflows[i] + ";"); |
|
249 |
|
250 // to fixedDiv2 |
|
251 synthesizeMouse(fixedDiv2, 30, 5, { type: "mousemove" }); |
|
252 check(kFalse, kFalse, kFalse, |
|
253 kTrue, kTrue, kTrue, kFalse, kFalse, kFalse, |
|
254 "fixedDiv1-fixedDiv2, all boxes are overflow: " + kOverflows[i] + ";"); |
|
255 |
|
256 clear(); |
|
257 |
|
258 // *********************************************************** |
|
259 // selection starting at fixedDiv2 |
|
260 synthesizeMouse(fixedDiv2, 30, 5, { type: "mousedown" }); |
|
261 |
|
262 // to xbl_child |
|
263 synthesizeMouse(xbl_child, 30, 5, { type: "mousemove" }); |
|
264 check(kFalse, kFalse, kFalse, |
|
265 kFalse, kTrue, kTrue, kFalse, kFalse, kFalse, |
|
266 "fixedDiv2-xbl_child, all boxes are overflow: " + kOverflows[i] + ";"); |
|
267 |
|
268 // to fixedDiv1 |
|
269 synthesizeMouse(fixedDiv1, 30, 5, { type: "mousemove" }); |
|
270 check(kFalse, kFalse, kFalse, |
|
271 kTrue, kTrue, kTrue, kFalse, kFalse, kFalse, |
|
272 "fixedDiv2-fixedDiv1, all boxes are overflow: " + kOverflows[i] + ";"); |
|
273 |
|
274 clear(); |
|
275 |
|
276 // *********************************************************** |
|
277 div2.style.overflow = "visible"; |
|
278 |
|
279 // *********************************************************** |
|
280 // selection starting at div2 |
|
281 synthesizeMouse(div2, 30, 5, { type: "mousedown" }); |
|
282 |
|
283 // to div3 |
|
284 synthesizeMouse(div3, 30, 5, { type: "mousemove" }); |
|
285 check(kFalse, kTrue, kTrue, |
|
286 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
287 "div2-div3, div3 is overflow: " + kOverflows[i] + |
|
288 ";, but div2 is overflow: visible;"); |
|
289 |
|
290 // to fixedDiv1 (child of div3) |
|
291 synthesizeMouse(fixedDiv1, 30, 5, { type: "mousemove" }); |
|
292 check(kFalse, kTrue, kTrue, |
|
293 kTrue, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
294 "div2-fixedDiv1, div3 is overflow: " + kOverflows[i] + |
|
295 ";, but div2 is overflow: visible;"); |
|
296 |
|
297 // to xbl_child |
|
298 synthesizeMouse(xbl_child, 30, 5, { type: "mousemove" }); |
|
299 check(kFalse, kTrue, kTrue, |
|
300 kTrue, kTrue, kFalse, kFalse, kFalse, kFalse, |
|
301 "div2-xbl_child, div3 is overflow: " + kOverflows[i] + |
|
302 ";, but div2 is overflow: visible;"); |
|
303 |
|
304 // to fixedDiv2 (sibling of div*) |
|
305 synthesizeMouse(fixedDiv2, 30, 5, { type: "mousemove" }); |
|
306 check(kFalse, kTrue, kTrue, |
|
307 kTrue, kTrue, kTrue, kFalse, kFalse, kFalse, |
|
308 "div2-fixedDiv2, div3 is overflow: " + kOverflows[i] + |
|
309 ";, but div2 is overflow: visible;"); |
|
310 |
|
311 clear(); |
|
312 |
|
313 // *********************************************************** |
|
314 // selection starting at div3 |
|
315 synthesizeMouse(div3, 30, 5, { type: "mousedown" }); |
|
316 |
|
317 // to div2 |
|
318 synthesizeMouse(div2, 30, 5, { type: "mousemove" }); |
|
319 check(kFalse, kTrue, kTrue, |
|
320 kFalse, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
321 "div3-div2, div3 is overflow: " + kOverflows[i] + |
|
322 ";, but div2 is overflow: visible;"); |
|
323 |
|
324 // to fixedDiv1 (child of div3) |
|
325 synthesizeMouse(fixedDiv1, 30, 5, { type: "mousemove" }); |
|
326 check(kFalse, kFalse, kTrue, |
|
327 kTrue, kFalse, kFalse, kFalse, kFalse, kFalse, |
|
328 "div3-fixedDiv1, div3 is overflow: " + kOverflows[i] + |
|
329 ";, but div2 is overflow: visible;"); |
|
330 |
|
331 // to xbl_child |
|
332 synthesizeMouse(xbl_child, 30, 5, { type: "mousemove" }); |
|
333 check(kFalse, kFalse, kTrue, |
|
334 kTrue, kTrue, kFalse, kFalse, kFalse, kFalse, |
|
335 "div3-xbl_child, div3 is overflow: " + kOverflows[i] + |
|
336 ";, but div2 is overflow: visible;"); |
|
337 |
|
338 // to fixedDiv2 (sibling of div*) |
|
339 synthesizeMouse(fixedDiv2, 30, 5, { type: "mousemove" }); |
|
340 check(kFalse, kFalse, kTrue, |
|
341 kTrue, kTrue, kTrue, kFalse, kFalse, kFalse, |
|
342 "div3-fixedDiv2, div3 is overflow: " + kOverflows[i] + |
|
343 ";, but div2 is overflow: visible;"); |
|
344 |
|
345 clear(); |
|
346 } |
|
347 |
|
348 // *********************************************************** |
|
349 // selection starting at iframe |
|
350 synthesizeMouse(iframe, 30, 5, { type: "mousedown" }); |
|
351 |
|
352 // inside iframe |
|
353 synthesizeMouse(iframe, 50, 5, { type: "mousemove" }); |
|
354 check(kFalse, kFalse, kFalse, |
|
355 kFalse, kFalse, kFalse, kTrue, kFalse, kFalse, |
|
356 "iframe-iframe"); |
|
357 |
|
358 // to div2 |
|
359 synthesizeMouse(div2, 30, 5, { type: "mousemove" }); |
|
360 check(kFalse, kFalse, kFalse, |
|
361 kFalse, kFalse, kFalse, kTrue, kFalse, kFalse, |
|
362 "iframe-div2"); |
|
363 |
|
364 clear(); |
|
365 |
|
366 // *********************************************************** |
|
367 // selection starting at input |
|
368 synthesizeMouse(input, 20, 5, { type: "mousedown" }); |
|
369 |
|
370 // inside input |
|
371 synthesizeMouse(input, 40, 5, { type: "mousemove" }); |
|
372 check(kFalse, kFalse, kFalse, |
|
373 kFalse, kFalse, kFalse, kFalse, kTrue, kFalse, |
|
374 "input-input"); |
|
375 |
|
376 // to div3 |
|
377 synthesizeMouse(div3, 30, 5, { type: "mousemove" }); |
|
378 check(kFalse, kFalse, kFalse, |
|
379 kFalse, kFalse, kFalse, kFalse, kTrue, kFalse, |
|
380 "input-div3"); |
|
381 |
|
382 clear(); |
|
383 |
|
384 // *********************************************************** |
|
385 // selection starting at textarea |
|
386 synthesizeMouse(textarea, 30, 5, { type: "mousedown" }); |
|
387 |
|
388 // inside textarea |
|
389 synthesizeMouse(textarea, 50, 5, { type: "mousemove" }); |
|
390 check(kFalse, kFalse, kFalse, |
|
391 kFalse, kFalse, kFalse, kFalse, kFalse, kTrue, |
|
392 "textarea-textarea"); |
|
393 |
|
394 // to div2 |
|
395 synthesizeMouse(div2, 30, 5, { type: "mousemove" }); |
|
396 check(kFalse, kFalse, kFalse, |
|
397 kFalse, kFalse, kFalse, kFalse, kFalse, kTrue, |
|
398 "textarea-div2"); |
|
399 |
|
400 clear(); |
|
401 |
|
402 SimpleTest.finish(); |
|
403 } |
|
404 window.onload = function() { setTimeout(test, 0); }; |
|
405 SimpleTest.waitForExplicitFinish(); |
|
406 </script> |
|
407 </pre> |
|
408 </body> |
|
409 </html> |