|
1 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- |
|
2 /* vim: set ts=2 et sw=2 tw=80: */ |
|
3 /* Any copyright is dedicated to the Public Domain. |
|
4 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
5 |
|
6 "use strict"; |
|
7 |
|
8 function debugClipFlavors(aClip) |
|
9 { |
|
10 let xfer = Cc["@mozilla.org/widget/transferable;1"]. |
|
11 createInstance(Ci.nsITransferable); |
|
12 xfer.init(null); |
|
13 aClip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard); |
|
14 let array = xfer.flavorsTransferableCanExport(); |
|
15 let count = array.Count(); |
|
16 info("flavors:" + count); |
|
17 for (let idx = 0; idx < count; idx++) { |
|
18 let string = array.GetElementAt(idx).QueryInterface(Ci.nsISupportsString); |
|
19 info("[" + idx + "] " + string); |
|
20 } |
|
21 } |
|
22 |
|
23 function checkContextMenuPositionRange(aElement, aMinLeft, aMaxLeft, aMinTop, aMaxTop) { |
|
24 ok(aElement.left > aMinLeft && aElement.left < aMaxLeft, |
|
25 "Left position is " + aElement.left + ", expected between " + aMinLeft + " and " + aMaxLeft); |
|
26 |
|
27 ok(aElement.top > aMinTop && aElement.top < aMaxTop, |
|
28 "Top position is " + aElement.top + ", expected between " + aMinTop + " and " + aMaxTop); |
|
29 } |
|
30 |
|
31 gTests.push({ |
|
32 desc: "text context menu", |
|
33 run: function test() { |
|
34 info(chromeRoot + "browser_context_menu_tests_02.html"); |
|
35 yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); |
|
36 |
|
37 purgeEventQueue(); |
|
38 emptyClipboard(); |
|
39 |
|
40 let win = Browser.selectedTab.browser.contentWindow; |
|
41 |
|
42 yield hideContextUI(); |
|
43 |
|
44 //////////////////////////////////////////////////////////// |
|
45 // Context menu in content on selected text |
|
46 |
|
47 // select some text |
|
48 let span = win.document.getElementById("text1"); |
|
49 win.getSelection().selectAllChildren(span); |
|
50 |
|
51 yield waitForMs(0); |
|
52 |
|
53 // invoke selection context menu |
|
54 let promise = waitForEvent(document, "popupshown"); |
|
55 sendContextMenuClickToElement(win, span); |
|
56 yield promise; |
|
57 |
|
58 // should be visible |
|
59 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
60 |
|
61 // selected text context: |
|
62 checkContextUIMenuItemVisibility(["context-copy", |
|
63 "context-search"]); |
|
64 |
|
65 let menuItem = document.getElementById("context-copy"); |
|
66 promise = waitForEvent(document, "popuphidden"); |
|
67 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
68 |
|
69 yield promise; |
|
70 |
|
71 // The wait is needed to give time to populate the clipboard. |
|
72 let string = ""; |
|
73 yield waitForCondition(function () { |
|
74 string = SpecialPowers.getClipboardData("text/unicode"); |
|
75 return string === span.textContent; |
|
76 }); |
|
77 ok(string === span.textContent, "copied selected text from span"); |
|
78 |
|
79 win.getSelection().removeAllRanges(); |
|
80 |
|
81 //////////////////////////////////////////////////////////// |
|
82 // Context menu in content on selected text that includes a link |
|
83 |
|
84 // invoke selection with link context menu |
|
85 let link = win.document.getElementById("text2-link"); |
|
86 win.getSelection().selectAllChildren(link); |
|
87 promise = waitForEvent(document, "popupshown"); |
|
88 sendContextMenuClickToElement(win, link); |
|
89 yield promise; |
|
90 |
|
91 // should be visible |
|
92 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
93 |
|
94 // selected text context: |
|
95 checkContextUIMenuItemVisibility(["context-copy", |
|
96 "context-search", |
|
97 "context-open-in-new-tab", |
|
98 "context-copy-link"]); |
|
99 |
|
100 promise = waitForEvent(document, "popuphidden"); |
|
101 win.scrollBy(0, 1); |
|
102 let hidden = yield promise; |
|
103 ok(hidden && !(hidden instanceof Error), "scrolling hides the context menu"); |
|
104 win.getSelection().removeAllRanges(); |
|
105 win.scrollBy(0, -1); |
|
106 |
|
107 //////////////////////////////////////////////////////////// |
|
108 // Context menu in content on a link |
|
109 |
|
110 link = win.document.getElementById("text2-link"); |
|
111 promise = waitForEvent(document, "popupshown"); |
|
112 sendContextMenuClickToElement(win, link); |
|
113 yield promise; |
|
114 |
|
115 // should be visible |
|
116 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
117 |
|
118 // selected text context: |
|
119 checkContextUIMenuItemVisibility(["context-open-in-new-tab", |
|
120 "context-copy-link", |
|
121 "context-bookmark-link"]); |
|
122 |
|
123 promise = waitForEvent(document, "popuphidden"); |
|
124 ContextMenuUI.hide(); |
|
125 yield promise; |
|
126 |
|
127 //////////////////////////////////////////////////////////// |
|
128 // context in input with no selection, no data on clipboard |
|
129 |
|
130 emptyClipboard(); |
|
131 |
|
132 let input = win.document.getElementById("text3-input"); |
|
133 promise = waitForEvent(document, "popupshown"); |
|
134 sendContextMenuClickToElement(win, input); |
|
135 yield promise; |
|
136 |
|
137 // should be visible |
|
138 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
139 |
|
140 checkContextUIMenuItemVisibility(["context-select", |
|
141 "context-select-all"]); |
|
142 |
|
143 // copy menu item should not exist when no text is selected |
|
144 let menuItem = document.getElementById("context-copy"); |
|
145 ok(menuItem && menuItem.hidden, "menu item is not visible"); |
|
146 |
|
147 promise = waitForEvent(document, "popuphidden"); |
|
148 ContextMenuUI.hide(); |
|
149 yield promise; |
|
150 |
|
151 //////////////////////////////////////////////////////////// |
|
152 // context in input with selection copied to clipboard |
|
153 |
|
154 let input = win.document.getElementById("text3-input"); |
|
155 input.value = "hello, I'm sorry but I must be going."; |
|
156 input.setSelectionRange(0, 5); |
|
157 promise = waitForEvent(document, "popupshown"); |
|
158 sendContextMenuClickToElement(win, input, 20); |
|
159 yield promise; |
|
160 |
|
161 // should be visible |
|
162 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
163 |
|
164 checkContextUIMenuItemVisibility(["context-cut", |
|
165 "context-copy"]); |
|
166 |
|
167 let menuItem = document.getElementById("context-copy"); |
|
168 let popupPromise = waitForEvent(document, "popuphidden"); |
|
169 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
170 |
|
171 yield popupPromise; |
|
172 |
|
173 // The wait is needed to give time to populate the clipboard. |
|
174 let string = ""; |
|
175 yield waitForCondition(function () { |
|
176 string = SpecialPowers.getClipboardData("text/unicode"); |
|
177 return string === "hello"; |
|
178 }); |
|
179 |
|
180 ok(string === "hello", "copied selected text"); |
|
181 |
|
182 emptyClipboard(); |
|
183 |
|
184 //////////////////////////////////////////////////////////// |
|
185 // context in input with text selection, no data on clipboard |
|
186 |
|
187 input = win.document.getElementById("text3-input"); |
|
188 input.select(); |
|
189 promise = waitForEvent(document, "popupshown"); |
|
190 sendContextMenuClickToElement(win, input, 20); |
|
191 yield promise; |
|
192 |
|
193 // should be visible |
|
194 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
195 |
|
196 // selected text context: |
|
197 checkContextUIMenuItemVisibility(["context-cut", |
|
198 "context-copy"]); |
|
199 |
|
200 promise = waitForEvent(document, "popuphidden"); |
|
201 ContextMenuUI.hide(); |
|
202 yield promise; |
|
203 |
|
204 //////////////////////////////////////////////////////////// |
|
205 // context in input with no selection, data on clipboard |
|
206 |
|
207 SpecialPowers.clipboardCopyString("foo"); |
|
208 input = win.document.getElementById("text3-input"); |
|
209 input.select(); |
|
210 promise = waitForEvent(document, "popupshown"); |
|
211 sendContextMenuClickToElement(win, input, 20); |
|
212 yield promise; |
|
213 |
|
214 // should be visible |
|
215 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
216 |
|
217 // selected text context: |
|
218 checkContextUIMenuItemVisibility(["context-cut", |
|
219 "context-copy", |
|
220 "context-paste"]); |
|
221 |
|
222 promise = waitForEvent(document, "popuphidden"); |
|
223 ContextMenuUI.hide(); |
|
224 yield promise; |
|
225 |
|
226 //////////////////////////////////////////////////////////// |
|
227 // context in input with selection cut to clipboard |
|
228 |
|
229 emptyClipboard(); |
|
230 |
|
231 let input = win.document.getElementById("text3-input"); |
|
232 input.value = "hello, I'm sorry but I must be going."; |
|
233 input.setSelectionRange(0, 5); |
|
234 promise = waitForEvent(document, "popupshown"); |
|
235 sendContextMenuClickToElement(win, input, 20); |
|
236 yield promise; |
|
237 |
|
238 // should be visible |
|
239 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
240 |
|
241 checkContextUIMenuItemVisibility(["context-cut", |
|
242 "context-copy"]); |
|
243 |
|
244 let menuItem = document.getElementById("context-cut"); |
|
245 let popupPromise = waitForEvent(document, "popuphidden"); |
|
246 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
247 |
|
248 yield popupPromise; |
|
249 |
|
250 // The wait is needed to give time to populate the clipboard. |
|
251 let string = ""; |
|
252 yield waitForCondition(function () { |
|
253 string = SpecialPowers.getClipboardData("text/unicode"); |
|
254 return string === "hello"; |
|
255 }); |
|
256 |
|
257 let inputValue = input.value; |
|
258 ok(string === "hello", "cut selected text in clipboard"); |
|
259 ok(inputValue === ", I'm sorry but I must be going.", "cut selected text from input value"); |
|
260 |
|
261 emptyClipboard(); |
|
262 |
|
263 //////////////////////////////////////////////////////////// |
|
264 // context in empty input, data on clipboard (paste operation) |
|
265 |
|
266 SpecialPowers.clipboardCopyString("foo"); |
|
267 input = win.document.getElementById("text3-input"); |
|
268 input.value = ""; |
|
269 |
|
270 promise = waitForEvent(document, "popupshown"); |
|
271 sendContextMenuClickToElement(win, input, 20); |
|
272 yield promise; |
|
273 |
|
274 // should be visible |
|
275 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
276 |
|
277 // selected text context: |
|
278 checkContextUIMenuItemVisibility(["context-paste"]); |
|
279 |
|
280 promise = waitForEvent(document, "popuphidden"); |
|
281 ContextMenuUI.hide(); |
|
282 yield promise; |
|
283 |
|
284 //////////////////////////////////////////////////////////// |
|
285 // context in empty input, no data on clipboard (??) |
|
286 |
|
287 emptyClipboard(); |
|
288 ContextUI.dismiss(); |
|
289 |
|
290 input = win.document.getElementById("text3-input"); |
|
291 input.value = ""; |
|
292 |
|
293 promise = waitForEvent(Elements.tray, "transitionend"); |
|
294 sendContextMenuClickToElement(win, input, 20); |
|
295 yield promise; |
|
296 |
|
297 // should *not* be visible |
|
298 ok(!ContextMenuUI._menuPopup.visible, "is visible"); |
|
299 |
|
300 // the test above will invoke the app bar |
|
301 yield hideContextUI(); |
|
302 |
|
303 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
304 purgeEventQueue(); |
|
305 } |
|
306 }); |
|
307 |
|
308 gTests.push({ |
|
309 desc: "checks for context menu positioning when browser shifts", |
|
310 run: function test() { |
|
311 info(chromeRoot + "browser_context_menu_tests_02.html"); |
|
312 yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); |
|
313 |
|
314 purgeEventQueue(); |
|
315 emptyClipboard(); |
|
316 |
|
317 let browserwin = Browser.selectedTab.browser.contentWindow; |
|
318 |
|
319 yield hideContextUI(); |
|
320 |
|
321 //////////////////////////////////////////////////////////// |
|
322 // test for proper context menu positioning when the browser |
|
323 // is offset by a notification box. |
|
324 |
|
325 yield showNotification(); |
|
326 |
|
327 // select some text |
|
328 let span = browserwin.document.getElementById("text4"); |
|
329 browserwin.getSelection().selectAllChildren(span); |
|
330 |
|
331 // invoke selection context menu |
|
332 let promise = waitForEvent(document, "popupshown"); |
|
333 sendContextMenuClickToElement(browserwin, span); |
|
334 yield promise; |
|
335 |
|
336 // should be visible and at a specific position |
|
337 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
338 |
|
339 let notificationBox = Browser.getNotificationBox(); |
|
340 let notification = notificationBox.getNotificationWithValue("popup-blocked"); |
|
341 let notificationHeight = notification.boxObject.height; |
|
342 |
|
343 checkContextMenuPositionRange(ContextMenuUI._panel, 0, 15, 220, 230); |
|
344 |
|
345 promise = waitForEvent(document, "popuphidden"); |
|
346 ContextMenuUI.hide(); |
|
347 yield promise; |
|
348 |
|
349 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
350 } |
|
351 }); |
|
352 |
|
353 /* |
|
354 XXX code used to diagnose bug 880739 |
|
355 |
|
356 var observeLogger = { |
|
357 observe: function (aSubject, aTopic, aData) { |
|
358 info("observeLogger: " + aTopic); |
|
359 }, |
|
360 QueryInterface: function (aIID) { |
|
361 if (!aIID.equals(Ci.nsIObserver) && |
|
362 !aIID.equals(Ci.nsISupportsWeakReference) && |
|
363 !aIID.equals(Ci.nsISupports)) { |
|
364 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
365 } |
|
366 return this; |
|
367 }, |
|
368 init: function init() { |
|
369 Services.obs.addObserver(observeLogger, "dl-start", true); |
|
370 Services.obs.addObserver(observeLogger, "dl-done", true); |
|
371 Services.obs.addObserver(observeLogger, "dl-failed", true); |
|
372 Services.obs.addObserver(observeLogger, "dl-scanning", true); |
|
373 Services.obs.addObserver(observeLogger, "dl-blocked", true); |
|
374 Services.obs.addObserver(observeLogger, "dl-dirty", true); |
|
375 Services.obs.addObserver(observeLogger, "dl-cancel", true); |
|
376 }, |
|
377 shutdown: function shutdown() { |
|
378 Services.obs.removeObserver(observeLogger, "dl-start"); |
|
379 Services.obs.removeObserver(observeLogger, "dl-done"); |
|
380 Services.obs.removeObserver(observeLogger, "dl-failed"); |
|
381 Services.obs.removeObserver(observeLogger, "dl-scanning"); |
|
382 Services.obs.removeObserver(observeLogger, "dl-blocked"); |
|
383 Services.obs.removeObserver(observeLogger, "dl-dirty"); |
|
384 Services.obs.removeObserver(observeLogger, "dl-cancel"); |
|
385 } |
|
386 } |
|
387 */ |
|
388 |
|
389 // Image context menu tests |
|
390 gTests.push({ |
|
391 desc: "image context menu", |
|
392 setUp: function() { |
|
393 // XXX code used to diagnose bug 880739 |
|
394 //observeLogger.init(); |
|
395 }, |
|
396 tearDown: function() { |
|
397 // XXX code used to diagnose bug 880739 |
|
398 //observeLogger.shutdown(); |
|
399 }, |
|
400 run: function test() { |
|
401 info(chromeRoot + "browser_context_menu_tests_01.html"); |
|
402 yield addTab(chromeRoot + "browser_context_menu_tests_01.html"); |
|
403 |
|
404 let win = Browser.selectedTab.browser.contentWindow; |
|
405 |
|
406 purgeEventQueue(); |
|
407 |
|
408 yield hideContextUI(); |
|
409 |
|
410 // If we don't do this, sometimes the first sendContextMenuClickToWindow |
|
411 // will trigger the app bar. |
|
412 yield waitForImageLoad(win, "image01"); |
|
413 |
|
414 //////////////////////////////////////////////////////////// |
|
415 // Context menu options |
|
416 /* |
|
417 XXX disabled temporarily due to bug 880739 |
|
418 |
|
419 // image01 - 1x1x100x100 |
|
420 let promise = waitForEvent(document, "popupshown"); |
|
421 sendContextMenuClickToWindow(win, 10, 10); |
|
422 yield promise; |
|
423 |
|
424 purgeEventQueue(); |
|
425 |
|
426 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
427 |
|
428 checkContextUIMenuItemVisibility(["context-save-image-lib", |
|
429 "context-copy-image", |
|
430 "context-copy-image-loc", |
|
431 "context-open-image-tab"]); |
|
432 |
|
433 //////////////////////////////////////////////////////////// |
|
434 // Save to image library |
|
435 |
|
436 let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] |
|
437 .getService(Components.interfaces.nsIProperties); |
|
438 let saveLocationPath = dirSvc.get("Pict", Components.interfaces.nsIFile); |
|
439 saveLocationPath.append("image01.png"); |
|
440 |
|
441 registerCleanupFunction(function () { |
|
442 saveLocationPath.remove(false); |
|
443 }); |
|
444 |
|
445 if (saveLocationPath.exists()) { |
|
446 info("had to remove old image!"); |
|
447 saveLocationPath.remove(false); |
|
448 } |
|
449 |
|
450 let menuItem = document.getElementById("context-save-image-lib"); |
|
451 ok(menuItem, "menu item exists"); |
|
452 ok(!menuItem.hidden, "menu item visible"); |
|
453 |
|
454 // dl-start, dl-failed, dl-scanning, dl-blocked, dl-dirty, dl-cancel |
|
455 let downloadPromise = waitForObserver("dl-done", 10000); |
|
456 |
|
457 let popupPromise = waitForEvent(document, "popuphidden"); |
|
458 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
459 yield popupPromise; |
|
460 yield downloadPromise; |
|
461 |
|
462 purgeEventQueue(); |
|
463 |
|
464 ok(saveLocationPath.exists(), "image saved"); |
|
465 */ |
|
466 //////////////////////////////////////////////////////////// |
|
467 // Copy image |
|
468 |
|
469 let promise = waitForEvent(document, "popupshown"); |
|
470 sendContextMenuClickToWindow(win, 20, 20); |
|
471 yield promise; |
|
472 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
473 |
|
474 let menuItem = document.getElementById("context-copy-image"); |
|
475 ok(menuItem, "menu item exists"); |
|
476 ok(!menuItem.hidden, "menu item visible"); |
|
477 let popupPromise = waitForEvent(document, "popuphidden"); |
|
478 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
479 yield popupPromise; |
|
480 |
|
481 purgeEventQueue(); |
|
482 |
|
483 let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); |
|
484 let flavors = ["image/png"]; |
|
485 ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my png flavor"); |
|
486 |
|
487 //////////////////////////////////////////////////////////// |
|
488 // Copy image location |
|
489 |
|
490 promise = waitForEvent(document, "popupshown"); |
|
491 sendContextMenuClickToWindow(win, 30, 30); |
|
492 yield promise; |
|
493 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
494 |
|
495 menuItem = document.getElementById("context-copy-image-loc"); |
|
496 ok(menuItem, "menu item exists"); |
|
497 ok(!menuItem.hidden, "menu item visible"); |
|
498 popupPromise = waitForEvent(document, "popuphidden"); |
|
499 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
500 yield popupPromise; |
|
501 |
|
502 purgeEventQueue(); |
|
503 |
|
504 let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); |
|
505 let flavors = ["text/unicode"]; |
|
506 ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my text flavor"); |
|
507 |
|
508 let xfer = Cc["@mozilla.org/widget/transferable;1"]. |
|
509 createInstance(Ci.nsITransferable); |
|
510 xfer.init(null); |
|
511 xfer.addDataFlavor("text/unicode"); |
|
512 clip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard); |
|
513 let str = new Object(); |
|
514 let strLength = new Object(); |
|
515 xfer.getTransferData("text/unicode", str, strLength); |
|
516 str = str.value.QueryInterface(Components.interfaces.nsISupportsString); |
|
517 |
|
518 ok(str == chromeRoot + "res/image01.png", "url copied"); |
|
519 |
|
520 //////////////////////////////////////////////////////////// |
|
521 // Open image in new tab |
|
522 |
|
523 promise = waitForEvent(document, "popupshown"); |
|
524 sendContextMenuClickToWindow(win, 40, 40); |
|
525 yield promise; |
|
526 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
527 |
|
528 menuItem = document.getElementById("context-open-image-tab"); |
|
529 ok(menuItem, "menu item exists"); |
|
530 ok(!menuItem.hidden, "menu item visible"); |
|
531 let tabPromise = waitForEvent(document, "TabOpen"); |
|
532 popupPromise = waitForEvent(document, "popuphidden"); |
|
533 EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); |
|
534 yield popupPromise; |
|
535 let event = yield tabPromise; |
|
536 |
|
537 purgeEventQueue(); |
|
538 |
|
539 let imagetab = Browser.getTabFromChrome(event.originalTarget); |
|
540 ok(imagetab != null, "tab created"); |
|
541 |
|
542 Browser.closeTab(imagetab, { forceClose: true }); |
|
543 } |
|
544 }); |
|
545 |
|
546 gTests.push({ |
|
547 desc: "tests for subframe positioning", |
|
548 run: function test() { |
|
549 info(chromeRoot + "browser_context_menu_tests_03.html"); |
|
550 yield addTab(chromeRoot + "browser_context_menu_tests_03.html"); |
|
551 |
|
552 let win = Browser.selectedTab.browser.contentWindow; |
|
553 |
|
554 // Sometimes the context ui is visible, sometimes it isn't. |
|
555 try { |
|
556 yield waitForCondition(function () { |
|
557 return ContextUI.isVisible; |
|
558 }, 500, 50); |
|
559 } catch (ex) {} |
|
560 |
|
561 ContextUI.dismiss(); |
|
562 |
|
563 let frame1 = win.document.getElementById("frame1"); |
|
564 let link1 = frame1.contentDocument.getElementById("link1"); |
|
565 |
|
566 let promise = waitForEvent(document, "popupshown"); |
|
567 sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10); |
|
568 yield promise; |
|
569 |
|
570 // should be visible |
|
571 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
572 |
|
573 checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 175, 190); |
|
574 |
|
575 promise = waitForEvent(document, "popuphidden"); |
|
576 ContextMenuUI.hide(); |
|
577 yield promise; |
|
578 |
|
579 frame1.contentDocument.defaultView.scrollBy(0, 200); |
|
580 |
|
581 promise = waitForEvent(document, "popupshown"); |
|
582 sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10); |
|
583 yield promise; |
|
584 |
|
585 // should be visible |
|
586 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
587 |
|
588 checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 95, 110); |
|
589 |
|
590 promise = waitForEvent(document, "popuphidden"); |
|
591 ContextMenuUI.hide(); |
|
592 yield promise; |
|
593 |
|
594 let rlink1 = win.document.getElementById("rlink1"); |
|
595 |
|
596 promise = waitForEvent(document, "popupshown"); |
|
597 sendContextMenuClickToElement(win, rlink1, 40, 10); |
|
598 yield promise; |
|
599 |
|
600 // should be visible |
|
601 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
602 |
|
603 checkContextMenuPositionRange(ContextMenuUI._panel, 295, 310, 540, 555); |
|
604 |
|
605 promise = waitForEvent(document, "popuphidden"); |
|
606 ContextMenuUI.hide(); |
|
607 yield promise; |
|
608 |
|
609 win.scrollBy(0, 200); |
|
610 |
|
611 promise = waitForEvent(document, "popupshown"); |
|
612 sendContextMenuClickToElement(win, rlink1, 40, 10); |
|
613 yield promise; |
|
614 |
|
615 // should be visible |
|
616 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
617 |
|
618 checkContextMenuPositionRange(ContextMenuUI._panel, 295, 310, 340, 355); |
|
619 |
|
620 promise = waitForEvent(document, "popuphidden"); |
|
621 ContextMenuUI.hide(); |
|
622 yield promise; |
|
623 |
|
624 let link2 = frame1.contentDocument.getElementById("link2"); |
|
625 |
|
626 promise = waitForEvent(document, "popupshown"); |
|
627 sendContextMenuClickToElement(frame1.contentDocument.defaultView, link2, 85, 10); |
|
628 yield promise; |
|
629 |
|
630 // should be visible |
|
631 ok(ContextMenuUI._menuPopup.visible, "is visible"); |
|
632 |
|
633 checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 110, 125); |
|
634 |
|
635 promise = waitForEvent(document, "popuphidden"); |
|
636 ContextMenuUI.hide(); |
|
637 yield promise; |
|
638 |
|
639 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
640 } |
|
641 }); |
|
642 |
|
643 function reopenSetUp() { |
|
644 info(chromeRoot + "browser_context_menu_tests_04.html"); |
|
645 yield addTab(chromeRoot + "browser_context_menu_tests_04.html"); |
|
646 |
|
647 // Sometimes the context UI won't actually show up. |
|
648 // Since we're just normalizing, we don't want waitForCondition |
|
649 // to cause an orange, so we're putting a try/catch here. |
|
650 try { |
|
651 yield waitForCondition(() => ContextUI.isVisible); |
|
652 ContextUI.dismiss(); |
|
653 } catch(e) {} |
|
654 } |
|
655 |
|
656 function reopenTearDown() { |
|
657 let promise = waitForEvent(document, "popuphidden") |
|
658 ContextMenuUI.hide(); |
|
659 yield promise; |
|
660 ok(!ContextMenuUI._menuPopup.visible, "popup is actually hidden"); |
|
661 |
|
662 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
663 } |
|
664 |
|
665 function getReopenTest(aElementInputFn, aWindowInputFn) { |
|
666 return function () { |
|
667 let win = Browser.selectedTab.browser.contentWindow; |
|
668 let panel = ContextMenuUI._menuPopup._panel; |
|
669 |
|
670 let link1 = win.document.getElementById("text1-link"); |
|
671 let link2 = win.document.getElementById("text2-link"); |
|
672 |
|
673 // Show the menu on link 1 |
|
674 let showpromise = waitForEvent(panel, "popupshown"); |
|
675 aElementInputFn(win, link1); |
|
676 |
|
677 ok((yield showpromise), "popupshown event fired"); |
|
678 ok(ContextMenuUI._menuPopup.visible, "initial popup is visible"); |
|
679 |
|
680 // Show the menu on link 2 |
|
681 let hidepromise = waitForEvent(panel, "popuphidden"); |
|
682 showpromise = waitForEvent(panel, "popupshown"); |
|
683 aElementInputFn(win, link2); |
|
684 |
|
685 ok((yield hidepromise), "popuphidden event fired"); |
|
686 ok((yield showpromise), "popupshown event fired"); |
|
687 ok(ContextMenuUI._menuPopup.visible, "popup is still visible"); |
|
688 |
|
689 // Hide the menu |
|
690 hidepromise = waitForEvent(panel, "popuphidden") |
|
691 aWindowInputFn(win, 10, 10); |
|
692 |
|
693 ok((yield hidepromise), "popuphidden event fired"); |
|
694 ok(!ContextMenuUI._menuPopup.visible, "popup is no longer visible"); |
|
695 } |
|
696 } |
|
697 |
|
698 gTests.push({ |
|
699 desc: "bug 856264 - mouse - context menu should reopen on other links", |
|
700 setUp: reopenSetUp, |
|
701 tearDown: reopenTearDown, |
|
702 run: getReopenTest(sendContextMenuMouseClickToElement, sendMouseClick) |
|
703 }); |
|
704 |
|
705 gTests.push({ |
|
706 desc: "bug 856264 - touch - context menu should reopen on other links", |
|
707 setUp: reopenSetUp, |
|
708 tearDown: reopenTearDown, |
|
709 run: getReopenTest(sendContextMenuClickToElement, sendTap) |
|
710 }); |
|
711 |
|
712 gTests.push({ |
|
713 desc: "Bug 947505 - Right-click in a designMode document should display a " + |
|
714 "context menu", |
|
715 run: function test() { |
|
716 info(chromeRoot + "browser_context_menu_tests_02.html"); |
|
717 yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); |
|
718 |
|
719 purgeEventQueue(); |
|
720 emptyClipboard(); |
|
721 ContextUI.dismiss(); |
|
722 |
|
723 yield waitForCondition(() => !ContextUI.navbarVisible); |
|
724 |
|
725 let tabWindow = Browser.selectedTab.browser.contentWindow; |
|
726 let testSpan = tabWindow.document.getElementById("text1"); |
|
727 |
|
728 // Case #1: Document isn't in design mode and nothing is selected. |
|
729 tabWindow.document.designMode = "off"; |
|
730 |
|
731 // Simulate right mouse click to reproduce the same step as noted in the |
|
732 // appropriate bug. It's valid for non-touch case only. |
|
733 synthesizeNativeMouseRDown(Browser.selectedTab.browser, 10, 10); |
|
734 synthesizeNativeMouseRUp(Browser.selectedTab.browser, 10, 10); |
|
735 |
|
736 yield waitForCondition(() => ContextUI.navbarVisible); |
|
737 |
|
738 ok(ContextUI.navbarVisible, "Navbar is visible on context menu action."); |
|
739 ok(ContextUI.tabbarVisible, "Tabbar is visible on context menu action."); |
|
740 |
|
741 ContextUI.dismiss(); |
|
742 yield waitForCondition(() => !ContextUI.navbarVisible); |
|
743 |
|
744 // Case #2: Document isn't in design mode and text is selected. |
|
745 tabWindow.getSelection().selectAllChildren(testSpan); |
|
746 |
|
747 let promise = waitForEvent(document, "popupshown"); |
|
748 sendContextMenuClickToSelection(tabWindow); |
|
749 yield promise; |
|
750 |
|
751 checkContextUIMenuItemVisibility(["context-copy", "context-search"]); |
|
752 |
|
753 promise = waitForEvent(document, "popuphidden"); |
|
754 ContextMenuUI.hide(); |
|
755 yield promise; |
|
756 |
|
757 // Case #3: Document is in design mode and nothing is selected. |
|
758 tabWindow.document.designMode = "on"; |
|
759 tabWindow.getSelection().removeAllRanges(); |
|
760 |
|
761 promise = waitForEvent(document, "popupshown"); |
|
762 sendContextMenuClickToElement(tabWindow, testSpan); |
|
763 yield promise; |
|
764 |
|
765 checkContextUIMenuItemVisibility(["context-select-all", "context-select"]); |
|
766 |
|
767 promise = waitForEvent(document, "popuphidden"); |
|
768 ContextMenuUI.hide(); |
|
769 yield promise; |
|
770 |
|
771 // Case #4: Document is in design mode and text is selected. |
|
772 tabWindow.getSelection().selectAllChildren(testSpan); |
|
773 |
|
774 promise = waitForEvent(document, "popupshown"); |
|
775 sendContextMenuClickToSelection(tabWindow); |
|
776 yield promise; |
|
777 |
|
778 checkContextUIMenuItemVisibility(["context-cut", "context-copy", |
|
779 "context-select-all", "context-select", |
|
780 "context-search"]); |
|
781 |
|
782 promise = waitForEvent(document, "popuphidden"); |
|
783 ContextMenuUI.hide(); |
|
784 yield promise; |
|
785 |
|
786 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
787 } |
|
788 }); |
|
789 |
|
790 gTests.push({ |
|
791 desc: "Bug 961702 - 'Copy' context menu action does not copy rich content " + |
|
792 "while document in design mode (or inside container that allows to " + |
|
793 "edit its content)", |
|
794 run: function test() { |
|
795 info(chromeRoot + "browser_context_menu_tests_05.html"); |
|
796 yield addTab(chromeRoot + "browser_context_menu_tests_05.html"); |
|
797 |
|
798 purgeEventQueue(); |
|
799 emptyClipboard(); |
|
800 ContextUI.dismiss(); |
|
801 |
|
802 yield waitForCondition(() => !ContextUI.navbarVisible); |
|
803 |
|
804 let tabWindow = Browser.selectedTab.browser.contentWindow; |
|
805 let testDiv = tabWindow.document.getElementById("div1"); |
|
806 |
|
807 // Case #1: Document is in design mode. |
|
808 tabWindow.document.designMode = "on"; |
|
809 |
|
810 let promise = waitForEvent(document, "popupshown"); |
|
811 sendContextMenuClickToElement(tabWindow, testDiv); |
|
812 yield promise; |
|
813 |
|
814 let selectAllMenuItem = document.getElementById("context-select-all"); |
|
815 promise = waitForEvent(document, "popuphidden"); |
|
816 sendNativeTap(selectAllMenuItem); |
|
817 yield promise; |
|
818 |
|
819 promise = waitForEvent(document, "popupshown"); |
|
820 sendContextMenuClickToSelection(tabWindow); |
|
821 yield promise; |
|
822 |
|
823 let copyMenuItem = document.getElementById("context-copy"); |
|
824 promise = waitForEvent(document, "popuphidden"); |
|
825 sendNativeTap(copyMenuItem); |
|
826 yield promise; |
|
827 |
|
828 // The wait is needed to give time to populate the clipboard. |
|
829 let clipboardContent = ""; |
|
830 let contentToCopy = tabWindow.document.body.innerHTML; |
|
831 yield waitForCondition(function () { |
|
832 clipboardContent = SpecialPowers.getClipboardData("text/html"); |
|
833 return clipboardContent == contentToCopy; |
|
834 }); |
|
835 ok(clipboardContent == contentToCopy, "Rich content copied."); |
|
836 |
|
837 // Case #2: Container with editable content. |
|
838 emptyClipboard(); |
|
839 tabWindow.document.designMode = "off"; |
|
840 tabWindow.getSelection().removeAllRanges(); |
|
841 |
|
842 promise = waitForEvent(tabWindow.document.body, "focus"); |
|
843 sendNativeTap(testDiv); |
|
844 yield promise; |
|
845 |
|
846 promise = waitForEvent(document, "popupshown"); |
|
847 sendContextMenuClickToElement(tabWindow, testDiv); |
|
848 yield promise; |
|
849 |
|
850 selectAllMenuItem = document.getElementById("context-select-all"); |
|
851 promise = waitForEvent(document, "popuphidden"); |
|
852 sendNativeTap(selectAllMenuItem); |
|
853 yield promise; |
|
854 |
|
855 promise = waitForEvent(document, "popupshown"); |
|
856 sendContextMenuClickToSelection(tabWindow); |
|
857 yield promise; |
|
858 |
|
859 copyMenuItem = document.getElementById("context-copy"); |
|
860 promise = waitForEvent(document, "popuphidden"); |
|
861 sendNativeTap(copyMenuItem); |
|
862 yield promise; |
|
863 |
|
864 // The wait is needed to give time to populate the clipboard. |
|
865 clipboardContent = ""; |
|
866 contentToCopy = testDiv.innerHTML; |
|
867 yield waitForCondition(function () { |
|
868 clipboardContent = SpecialPowers.getClipboardData("text/html"); |
|
869 return clipboardContent == contentToCopy; |
|
870 }); |
|
871 ok(clipboardContent == contentToCopy, "Rich content copied."); |
|
872 |
|
873 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
874 } |
|
875 }); |
|
876 |
|
877 gTests.push({ |
|
878 desc: "Bug 963067 - 'Cut' in the cut, copy, paste menu is always active " + |
|
879 "after a browser launch.", |
|
880 run: function test() { |
|
881 info(chromeRoot + "browser_context_menu_tests_02.html"); |
|
882 yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); |
|
883 |
|
884 purgeEventQueue(); |
|
885 emptyClipboard(); |
|
886 |
|
887 ContextUI.dismiss(); |
|
888 yield waitForCondition(() => !ContextUI.navbarVisible); |
|
889 |
|
890 let tabWindow = Browser.selectedTab.browser.contentWindow; |
|
891 let input = tabWindow.document.getElementById("text3-input"); |
|
892 let cutMenuItem = document.getElementById("context-cut"); |
|
893 |
|
894 input.select(); |
|
895 |
|
896 // Emulate RichListBox's behavior and set first item selected by default. |
|
897 cutMenuItem.selected = true; |
|
898 |
|
899 let promise = waitForEvent(document, "popupshown"); |
|
900 sendContextMenuClickToElement(tabWindow, input); |
|
901 yield promise; |
|
902 |
|
903 ok(!cutMenuItem.hidden && !cutMenuItem.selected, |
|
904 "Cut menu item is visible and not selected."); |
|
905 |
|
906 promise = waitForEvent(document, "popuphidden"); |
|
907 ContextMenuUI.hide(); |
|
908 yield promise; |
|
909 |
|
910 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
911 } |
|
912 }); |
|
913 |
|
914 gTests.push({ |
|
915 desc: "Bug 867499 - Selecting 'copy' from context menu for selected text " + |
|
916 "dismisses selection.", |
|
917 run: function test() { |
|
918 info(chromeRoot + "browser_context_menu_tests_02.html"); |
|
919 yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); |
|
920 |
|
921 emptyClipboard(); |
|
922 ContextUI.dismiss(); |
|
923 |
|
924 yield waitForCondition(() => !ContextUI.navbarVisible); |
|
925 |
|
926 let tabWindow = Browser.selectedTab.browser.contentWindow; |
|
927 let testSpan = tabWindow.document.getElementById("text1"); |
|
928 |
|
929 let promise = waitForEvent(document, "popupshown"); |
|
930 sendContextMenuClickToElement(tabWindow, testSpan, 5, 5); |
|
931 yield promise; |
|
932 |
|
933 yield waitForCondition(()=>SelectionHelperUI.isSelectionUIVisible); |
|
934 |
|
935 promise = waitForEvent(document, "popupshown"); |
|
936 sendContextMenuClickToSelection(tabWindow); |
|
937 yield promise; |
|
938 |
|
939 let copyMenuItem = document.getElementById("context-copy"); |
|
940 |
|
941 ok(!copyMenuItem.hidden, "Copy menu item should be visible."); |
|
942 |
|
943 promise = waitForEvent(document, "popuphidden"); |
|
944 sendNativeTap(copyMenuItem, 5, 5); |
|
945 yield promise; |
|
946 yield waitForCondition(() => |
|
947 !!SpecialPowers.getClipboardData("text/unicode")); |
|
948 |
|
949 ok(SelectionHelperUI.isSelectionUIVisible, |
|
950 "Selection monocles should stay active after copy action."); |
|
951 |
|
952 Browser.closeTab(Browser.selectedTab, { forceClose: true }); |
|
953 } |
|
954 }); |
|
955 |
|
956 function test() { |
|
957 setDevPixelEqualToPx(); |
|
958 runTests(); |
|
959 } |