michael@0: // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: function debugClipFlavors(aClip) michael@0: { michael@0: let xfer = Cc["@mozilla.org/widget/transferable;1"]. michael@0: createInstance(Ci.nsITransferable); michael@0: xfer.init(null); michael@0: aClip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard); michael@0: let array = xfer.flavorsTransferableCanExport(); michael@0: let count = array.Count(); michael@0: info("flavors:" + count); michael@0: for (let idx = 0; idx < count; idx++) { michael@0: let string = array.GetElementAt(idx).QueryInterface(Ci.nsISupportsString); michael@0: info("[" + idx + "] " + string); michael@0: } michael@0: } michael@0: michael@0: function checkContextMenuPositionRange(aElement, aMinLeft, aMaxLeft, aMinTop, aMaxTop) { michael@0: ok(aElement.left > aMinLeft && aElement.left < aMaxLeft, michael@0: "Left position is " + aElement.left + ", expected between " + aMinLeft + " and " + aMaxLeft); michael@0: michael@0: ok(aElement.top > aMinTop && aElement.top < aMaxTop, michael@0: "Top position is " + aElement.top + ", expected between " + aMinTop + " and " + aMaxTop); michael@0: } michael@0: michael@0: gTests.push({ michael@0: desc: "text context menu", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: michael@0: purgeEventQueue(); michael@0: emptyClipboard(); michael@0: michael@0: let win = Browser.selectedTab.browser.contentWindow; michael@0: michael@0: yield hideContextUI(); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Context menu in content on selected text michael@0: michael@0: // select some text michael@0: let span = win.document.getElementById("text1"); michael@0: win.getSelection().selectAllChildren(span); michael@0: michael@0: yield waitForMs(0); michael@0: michael@0: // invoke selection context menu michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, span); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // selected text context: michael@0: checkContextUIMenuItemVisibility(["context-copy", michael@0: "context-search"]); michael@0: michael@0: let menuItem = document.getElementById("context-copy"); michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: michael@0: yield promise; michael@0: michael@0: // The wait is needed to give time to populate the clipboard. michael@0: let string = ""; michael@0: yield waitForCondition(function () { michael@0: string = SpecialPowers.getClipboardData("text/unicode"); michael@0: return string === span.textContent; michael@0: }); michael@0: ok(string === span.textContent, "copied selected text from span"); michael@0: michael@0: win.getSelection().removeAllRanges(); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Context menu in content on selected text that includes a link michael@0: michael@0: // invoke selection with link context menu michael@0: let link = win.document.getElementById("text2-link"); michael@0: win.getSelection().selectAllChildren(link); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, link); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // selected text context: michael@0: checkContextUIMenuItemVisibility(["context-copy", michael@0: "context-search", michael@0: "context-open-in-new-tab", michael@0: "context-copy-link"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: win.scrollBy(0, 1); michael@0: let hidden = yield promise; michael@0: ok(hidden && !(hidden instanceof Error), "scrolling hides the context menu"); michael@0: win.getSelection().removeAllRanges(); michael@0: win.scrollBy(0, -1); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Context menu in content on a link michael@0: michael@0: link = win.document.getElementById("text2-link"); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, link); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // selected text context: michael@0: checkContextUIMenuItemVisibility(["context-open-in-new-tab", michael@0: "context-copy-link", michael@0: "context-bookmark-link"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in input with no selection, no data on clipboard michael@0: michael@0: emptyClipboard(); michael@0: michael@0: let input = win.document.getElementById("text3-input"); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, input); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextUIMenuItemVisibility(["context-select", michael@0: "context-select-all"]); michael@0: michael@0: // copy menu item should not exist when no text is selected michael@0: let menuItem = document.getElementById("context-copy"); michael@0: ok(menuItem && menuItem.hidden, "menu item is not visible"); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in input with selection copied to clipboard michael@0: michael@0: let input = win.document.getElementById("text3-input"); michael@0: input.value = "hello, I'm sorry but I must be going."; michael@0: input.setSelectionRange(0, 5); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, input, 20); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextUIMenuItemVisibility(["context-cut", michael@0: "context-copy"]); michael@0: michael@0: let menuItem = document.getElementById("context-copy"); michael@0: let popupPromise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: michael@0: yield popupPromise; michael@0: michael@0: // The wait is needed to give time to populate the clipboard. michael@0: let string = ""; michael@0: yield waitForCondition(function () { michael@0: string = SpecialPowers.getClipboardData("text/unicode"); michael@0: return string === "hello"; michael@0: }); michael@0: michael@0: ok(string === "hello", "copied selected text"); michael@0: michael@0: emptyClipboard(); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in input with text selection, no data on clipboard michael@0: michael@0: input = win.document.getElementById("text3-input"); michael@0: input.select(); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, input, 20); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // selected text context: michael@0: checkContextUIMenuItemVisibility(["context-cut", michael@0: "context-copy"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in input with no selection, data on clipboard michael@0: michael@0: SpecialPowers.clipboardCopyString("foo"); michael@0: input = win.document.getElementById("text3-input"); michael@0: input.select(); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, input, 20); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // selected text context: michael@0: checkContextUIMenuItemVisibility(["context-cut", michael@0: "context-copy", michael@0: "context-paste"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in input with selection cut to clipboard michael@0: michael@0: emptyClipboard(); michael@0: michael@0: let input = win.document.getElementById("text3-input"); michael@0: input.value = "hello, I'm sorry but I must be going."; michael@0: input.setSelectionRange(0, 5); michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, input, 20); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextUIMenuItemVisibility(["context-cut", michael@0: "context-copy"]); michael@0: michael@0: let menuItem = document.getElementById("context-cut"); michael@0: let popupPromise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: michael@0: yield popupPromise; michael@0: michael@0: // The wait is needed to give time to populate the clipboard. michael@0: let string = ""; michael@0: yield waitForCondition(function () { michael@0: string = SpecialPowers.getClipboardData("text/unicode"); michael@0: return string === "hello"; michael@0: }); michael@0: michael@0: let inputValue = input.value; michael@0: ok(string === "hello", "cut selected text in clipboard"); michael@0: ok(inputValue === ", I'm sorry but I must be going.", "cut selected text from input value"); michael@0: michael@0: emptyClipboard(); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in empty input, data on clipboard (paste operation) michael@0: michael@0: SpecialPowers.clipboardCopyString("foo"); michael@0: input = win.document.getElementById("text3-input"); michael@0: input.value = ""; michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, input, 20); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // selected text context: michael@0: checkContextUIMenuItemVisibility(["context-paste"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // context in empty input, no data on clipboard (??) michael@0: michael@0: emptyClipboard(); michael@0: ContextUI.dismiss(); michael@0: michael@0: input = win.document.getElementById("text3-input"); michael@0: input.value = ""; michael@0: michael@0: promise = waitForEvent(Elements.tray, "transitionend"); michael@0: sendContextMenuClickToElement(win, input, 20); michael@0: yield promise; michael@0: michael@0: // should *not* be visible michael@0: ok(!ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: // the test above will invoke the app bar michael@0: yield hideContextUI(); michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: purgeEventQueue(); michael@0: } michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "checks for context menu positioning when browser shifts", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: michael@0: purgeEventQueue(); michael@0: emptyClipboard(); michael@0: michael@0: let browserwin = Browser.selectedTab.browser.contentWindow; michael@0: michael@0: yield hideContextUI(); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // test for proper context menu positioning when the browser michael@0: // is offset by a notification box. michael@0: michael@0: yield showNotification(); michael@0: michael@0: // select some text michael@0: let span = browserwin.document.getElementById("text4"); michael@0: browserwin.getSelection().selectAllChildren(span); michael@0: michael@0: // invoke selection context menu michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(browserwin, span); michael@0: yield promise; michael@0: michael@0: // should be visible and at a specific position michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: let notificationBox = Browser.getNotificationBox(); michael@0: let notification = notificationBox.getNotificationWithValue("popup-blocked"); michael@0: let notificationHeight = notification.boxObject.height; michael@0: michael@0: checkContextMenuPositionRange(ContextMenuUI._panel, 0, 15, 220, 230); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: /* michael@0: XXX code used to diagnose bug 880739 michael@0: michael@0: var observeLogger = { michael@0: observe: function (aSubject, aTopic, aData) { michael@0: info("observeLogger: " + aTopic); michael@0: }, michael@0: QueryInterface: function (aIID) { michael@0: if (!aIID.equals(Ci.nsIObserver) && michael@0: !aIID.equals(Ci.nsISupportsWeakReference) && michael@0: !aIID.equals(Ci.nsISupports)) { michael@0: throw Components.results.NS_ERROR_NO_INTERFACE; michael@0: } michael@0: return this; michael@0: }, michael@0: init: function init() { michael@0: Services.obs.addObserver(observeLogger, "dl-start", true); michael@0: Services.obs.addObserver(observeLogger, "dl-done", true); michael@0: Services.obs.addObserver(observeLogger, "dl-failed", true); michael@0: Services.obs.addObserver(observeLogger, "dl-scanning", true); michael@0: Services.obs.addObserver(observeLogger, "dl-blocked", true); michael@0: Services.obs.addObserver(observeLogger, "dl-dirty", true); michael@0: Services.obs.addObserver(observeLogger, "dl-cancel", true); michael@0: }, michael@0: shutdown: function shutdown() { michael@0: Services.obs.removeObserver(observeLogger, "dl-start"); michael@0: Services.obs.removeObserver(observeLogger, "dl-done"); michael@0: Services.obs.removeObserver(observeLogger, "dl-failed"); michael@0: Services.obs.removeObserver(observeLogger, "dl-scanning"); michael@0: Services.obs.removeObserver(observeLogger, "dl-blocked"); michael@0: Services.obs.removeObserver(observeLogger, "dl-dirty"); michael@0: Services.obs.removeObserver(observeLogger, "dl-cancel"); michael@0: } michael@0: } michael@0: */ michael@0: michael@0: // Image context menu tests michael@0: gTests.push({ michael@0: desc: "image context menu", michael@0: setUp: function() { michael@0: // XXX code used to diagnose bug 880739 michael@0: //observeLogger.init(); michael@0: }, michael@0: tearDown: function() { michael@0: // XXX code used to diagnose bug 880739 michael@0: //observeLogger.shutdown(); michael@0: }, michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_01.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_01.html"); michael@0: michael@0: let win = Browser.selectedTab.browser.contentWindow; michael@0: michael@0: purgeEventQueue(); michael@0: michael@0: yield hideContextUI(); michael@0: michael@0: // If we don't do this, sometimes the first sendContextMenuClickToWindow michael@0: // will trigger the app bar. michael@0: yield waitForImageLoad(win, "image01"); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Context menu options michael@0: /* michael@0: XXX disabled temporarily due to bug 880739 michael@0: michael@0: // image01 - 1x1x100x100 michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToWindow(win, 10, 10); michael@0: yield promise; michael@0: michael@0: purgeEventQueue(); michael@0: michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextUIMenuItemVisibility(["context-save-image-lib", michael@0: "context-copy-image", michael@0: "context-copy-image-loc", michael@0: "context-open-image-tab"]); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Save to image library michael@0: michael@0: let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"] michael@0: .getService(Components.interfaces.nsIProperties); michael@0: let saveLocationPath = dirSvc.get("Pict", Components.interfaces.nsIFile); michael@0: saveLocationPath.append("image01.png"); michael@0: michael@0: registerCleanupFunction(function () { michael@0: saveLocationPath.remove(false); michael@0: }); michael@0: michael@0: if (saveLocationPath.exists()) { michael@0: info("had to remove old image!"); michael@0: saveLocationPath.remove(false); michael@0: } michael@0: michael@0: let menuItem = document.getElementById("context-save-image-lib"); michael@0: ok(menuItem, "menu item exists"); michael@0: ok(!menuItem.hidden, "menu item visible"); michael@0: michael@0: // dl-start, dl-failed, dl-scanning, dl-blocked, dl-dirty, dl-cancel michael@0: let downloadPromise = waitForObserver("dl-done", 10000); michael@0: michael@0: let popupPromise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: yield popupPromise; michael@0: yield downloadPromise; michael@0: michael@0: purgeEventQueue(); michael@0: michael@0: ok(saveLocationPath.exists(), "image saved"); michael@0: */ michael@0: //////////////////////////////////////////////////////////// michael@0: // Copy image michael@0: michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToWindow(win, 20, 20); michael@0: yield promise; michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: let menuItem = document.getElementById("context-copy-image"); michael@0: ok(menuItem, "menu item exists"); michael@0: ok(!menuItem.hidden, "menu item visible"); michael@0: let popupPromise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: yield popupPromise; michael@0: michael@0: purgeEventQueue(); michael@0: michael@0: let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); michael@0: let flavors = ["image/png"]; michael@0: ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my png flavor"); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Copy image location michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToWindow(win, 30, 30); michael@0: yield promise; michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: menuItem = document.getElementById("context-copy-image-loc"); michael@0: ok(menuItem, "menu item exists"); michael@0: ok(!menuItem.hidden, "menu item visible"); michael@0: popupPromise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: yield popupPromise; michael@0: michael@0: purgeEventQueue(); michael@0: michael@0: let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); michael@0: let flavors = ["text/unicode"]; michael@0: ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my text flavor"); michael@0: michael@0: let xfer = Cc["@mozilla.org/widget/transferable;1"]. michael@0: createInstance(Ci.nsITransferable); michael@0: xfer.init(null); michael@0: xfer.addDataFlavor("text/unicode"); michael@0: clip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard); michael@0: let str = new Object(); michael@0: let strLength = new Object(); michael@0: xfer.getTransferData("text/unicode", str, strLength); michael@0: str = str.value.QueryInterface(Components.interfaces.nsISupportsString); michael@0: michael@0: ok(str == chromeRoot + "res/image01.png", "url copied"); michael@0: michael@0: //////////////////////////////////////////////////////////// michael@0: // Open image in new tab michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToWindow(win, 40, 40); michael@0: yield promise; michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: menuItem = document.getElementById("context-open-image-tab"); michael@0: ok(menuItem, "menu item exists"); michael@0: ok(!menuItem.hidden, "menu item visible"); michael@0: let tabPromise = waitForEvent(document, "TabOpen"); michael@0: popupPromise = waitForEvent(document, "popuphidden"); michael@0: EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); michael@0: yield popupPromise; michael@0: let event = yield tabPromise; michael@0: michael@0: purgeEventQueue(); michael@0: michael@0: let imagetab = Browser.getTabFromChrome(event.originalTarget); michael@0: ok(imagetab != null, "tab created"); michael@0: michael@0: Browser.closeTab(imagetab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "tests for subframe positioning", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_03.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_03.html"); michael@0: michael@0: let win = Browser.selectedTab.browser.contentWindow; michael@0: michael@0: // Sometimes the context ui is visible, sometimes it isn't. michael@0: try { michael@0: yield waitForCondition(function () { michael@0: return ContextUI.isVisible; michael@0: }, 500, 50); michael@0: } catch (ex) {} michael@0: michael@0: ContextUI.dismiss(); michael@0: michael@0: let frame1 = win.document.getElementById("frame1"); michael@0: let link1 = frame1.contentDocument.getElementById("link1"); michael@0: michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 175, 190); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: frame1.contentDocument.defaultView.scrollBy(0, 200); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 95, 110); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: let rlink1 = win.document.getElementById("rlink1"); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, rlink1, 40, 10); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextMenuPositionRange(ContextMenuUI._panel, 295, 310, 540, 555); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: win.scrollBy(0, 200); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(win, rlink1, 40, 10); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextMenuPositionRange(ContextMenuUI._panel, 295, 310, 340, 355); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: let link2 = frame1.contentDocument.getElementById("link2"); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(frame1.contentDocument.defaultView, link2, 85, 10); michael@0: yield promise; michael@0: michael@0: // should be visible michael@0: ok(ContextMenuUI._menuPopup.visible, "is visible"); michael@0: michael@0: checkContextMenuPositionRange(ContextMenuUI._panel, 265, 280, 110, 125); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: function reopenSetUp() { michael@0: info(chromeRoot + "browser_context_menu_tests_04.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_04.html"); michael@0: michael@0: // Sometimes the context UI won't actually show up. michael@0: // Since we're just normalizing, we don't want waitForCondition michael@0: // to cause an orange, so we're putting a try/catch here. michael@0: try { michael@0: yield waitForCondition(() => ContextUI.isVisible); michael@0: ContextUI.dismiss(); michael@0: } catch(e) {} michael@0: } michael@0: michael@0: function reopenTearDown() { michael@0: let promise = waitForEvent(document, "popuphidden") michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: ok(!ContextMenuUI._menuPopup.visible, "popup is actually hidden"); michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: michael@0: function getReopenTest(aElementInputFn, aWindowInputFn) { michael@0: return function () { michael@0: let win = Browser.selectedTab.browser.contentWindow; michael@0: let panel = ContextMenuUI._menuPopup._panel; michael@0: michael@0: let link1 = win.document.getElementById("text1-link"); michael@0: let link2 = win.document.getElementById("text2-link"); michael@0: michael@0: // Show the menu on link 1 michael@0: let showpromise = waitForEvent(panel, "popupshown"); michael@0: aElementInputFn(win, link1); michael@0: michael@0: ok((yield showpromise), "popupshown event fired"); michael@0: ok(ContextMenuUI._menuPopup.visible, "initial popup is visible"); michael@0: michael@0: // Show the menu on link 2 michael@0: let hidepromise = waitForEvent(panel, "popuphidden"); michael@0: showpromise = waitForEvent(panel, "popupshown"); michael@0: aElementInputFn(win, link2); michael@0: michael@0: ok((yield hidepromise), "popuphidden event fired"); michael@0: ok((yield showpromise), "popupshown event fired"); michael@0: ok(ContextMenuUI._menuPopup.visible, "popup is still visible"); michael@0: michael@0: // Hide the menu michael@0: hidepromise = waitForEvent(panel, "popuphidden") michael@0: aWindowInputFn(win, 10, 10); michael@0: michael@0: ok((yield hidepromise), "popuphidden event fired"); michael@0: ok(!ContextMenuUI._menuPopup.visible, "popup is no longer visible"); michael@0: } michael@0: } michael@0: michael@0: gTests.push({ michael@0: desc: "bug 856264 - mouse - context menu should reopen on other links", michael@0: setUp: reopenSetUp, michael@0: tearDown: reopenTearDown, michael@0: run: getReopenTest(sendContextMenuMouseClickToElement, sendMouseClick) michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "bug 856264 - touch - context menu should reopen on other links", michael@0: setUp: reopenSetUp, michael@0: tearDown: reopenTearDown, michael@0: run: getReopenTest(sendContextMenuClickToElement, sendTap) michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "Bug 947505 - Right-click in a designMode document should display a " + michael@0: "context menu", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: michael@0: purgeEventQueue(); michael@0: emptyClipboard(); michael@0: ContextUI.dismiss(); michael@0: michael@0: yield waitForCondition(() => !ContextUI.navbarVisible); michael@0: michael@0: let tabWindow = Browser.selectedTab.browser.contentWindow; michael@0: let testSpan = tabWindow.document.getElementById("text1"); michael@0: michael@0: // Case #1: Document isn't in design mode and nothing is selected. michael@0: tabWindow.document.designMode = "off"; michael@0: michael@0: // Simulate right mouse click to reproduce the same step as noted in the michael@0: // appropriate bug. It's valid for non-touch case only. michael@0: synthesizeNativeMouseRDown(Browser.selectedTab.browser, 10, 10); michael@0: synthesizeNativeMouseRUp(Browser.selectedTab.browser, 10, 10); michael@0: michael@0: yield waitForCondition(() => ContextUI.navbarVisible); michael@0: michael@0: ok(ContextUI.navbarVisible, "Navbar is visible on context menu action."); michael@0: ok(ContextUI.tabbarVisible, "Tabbar is visible on context menu action."); michael@0: michael@0: ContextUI.dismiss(); michael@0: yield waitForCondition(() => !ContextUI.navbarVisible); michael@0: michael@0: // Case #2: Document isn't in design mode and text is selected. michael@0: tabWindow.getSelection().selectAllChildren(testSpan); michael@0: michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToSelection(tabWindow); michael@0: yield promise; michael@0: michael@0: checkContextUIMenuItemVisibility(["context-copy", "context-search"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: // Case #3: Document is in design mode and nothing is selected. michael@0: tabWindow.document.designMode = "on"; michael@0: tabWindow.getSelection().removeAllRanges(); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(tabWindow, testSpan); michael@0: yield promise; michael@0: michael@0: checkContextUIMenuItemVisibility(["context-select-all", "context-select"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: // Case #4: Document is in design mode and text is selected. michael@0: tabWindow.getSelection().selectAllChildren(testSpan); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToSelection(tabWindow); michael@0: yield promise; michael@0: michael@0: checkContextUIMenuItemVisibility(["context-cut", "context-copy", michael@0: "context-select-all", "context-select", michael@0: "context-search"]); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "Bug 961702 - 'Copy' context menu action does not copy rich content " + michael@0: "while document in design mode (or inside container that allows to " + michael@0: "edit its content)", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_05.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_05.html"); michael@0: michael@0: purgeEventQueue(); michael@0: emptyClipboard(); michael@0: ContextUI.dismiss(); michael@0: michael@0: yield waitForCondition(() => !ContextUI.navbarVisible); michael@0: michael@0: let tabWindow = Browser.selectedTab.browser.contentWindow; michael@0: let testDiv = tabWindow.document.getElementById("div1"); michael@0: michael@0: // Case #1: Document is in design mode. michael@0: tabWindow.document.designMode = "on"; michael@0: michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(tabWindow, testDiv); michael@0: yield promise; michael@0: michael@0: let selectAllMenuItem = document.getElementById("context-select-all"); michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: sendNativeTap(selectAllMenuItem); michael@0: yield promise; michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToSelection(tabWindow); michael@0: yield promise; michael@0: michael@0: let copyMenuItem = document.getElementById("context-copy"); michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: sendNativeTap(copyMenuItem); michael@0: yield promise; michael@0: michael@0: // The wait is needed to give time to populate the clipboard. michael@0: let clipboardContent = ""; michael@0: let contentToCopy = tabWindow.document.body.innerHTML; michael@0: yield waitForCondition(function () { michael@0: clipboardContent = SpecialPowers.getClipboardData("text/html"); michael@0: return clipboardContent == contentToCopy; michael@0: }); michael@0: ok(clipboardContent == contentToCopy, "Rich content copied."); michael@0: michael@0: // Case #2: Container with editable content. michael@0: emptyClipboard(); michael@0: tabWindow.document.designMode = "off"; michael@0: tabWindow.getSelection().removeAllRanges(); michael@0: michael@0: promise = waitForEvent(tabWindow.document.body, "focus"); michael@0: sendNativeTap(testDiv); michael@0: yield promise; michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(tabWindow, testDiv); michael@0: yield promise; michael@0: michael@0: selectAllMenuItem = document.getElementById("context-select-all"); michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: sendNativeTap(selectAllMenuItem); michael@0: yield promise; michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToSelection(tabWindow); michael@0: yield promise; michael@0: michael@0: copyMenuItem = document.getElementById("context-copy"); michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: sendNativeTap(copyMenuItem); michael@0: yield promise; michael@0: michael@0: // The wait is needed to give time to populate the clipboard. michael@0: clipboardContent = ""; michael@0: contentToCopy = testDiv.innerHTML; michael@0: yield waitForCondition(function () { michael@0: clipboardContent = SpecialPowers.getClipboardData("text/html"); michael@0: return clipboardContent == contentToCopy; michael@0: }); michael@0: ok(clipboardContent == contentToCopy, "Rich content copied."); michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "Bug 963067 - 'Cut' in the cut, copy, paste menu is always active " + michael@0: "after a browser launch.", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: michael@0: purgeEventQueue(); michael@0: emptyClipboard(); michael@0: michael@0: ContextUI.dismiss(); michael@0: yield waitForCondition(() => !ContextUI.navbarVisible); michael@0: michael@0: let tabWindow = Browser.selectedTab.browser.contentWindow; michael@0: let input = tabWindow.document.getElementById("text3-input"); michael@0: let cutMenuItem = document.getElementById("context-cut"); michael@0: michael@0: input.select(); michael@0: michael@0: // Emulate RichListBox's behavior and set first item selected by default. michael@0: cutMenuItem.selected = true; michael@0: michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(tabWindow, input); michael@0: yield promise; michael@0: michael@0: ok(!cutMenuItem.hidden && !cutMenuItem.selected, michael@0: "Cut menu item is visible and not selected."); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: ContextMenuUI.hide(); michael@0: yield promise; michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: gTests.push({ michael@0: desc: "Bug 867499 - Selecting 'copy' from context menu for selected text " + michael@0: "dismisses selection.", michael@0: run: function test() { michael@0: info(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: yield addTab(chromeRoot + "browser_context_menu_tests_02.html"); michael@0: michael@0: emptyClipboard(); michael@0: ContextUI.dismiss(); michael@0: michael@0: yield waitForCondition(() => !ContextUI.navbarVisible); michael@0: michael@0: let tabWindow = Browser.selectedTab.browser.contentWindow; michael@0: let testSpan = tabWindow.document.getElementById("text1"); michael@0: michael@0: let promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToElement(tabWindow, testSpan, 5, 5); michael@0: yield promise; michael@0: michael@0: yield waitForCondition(()=>SelectionHelperUI.isSelectionUIVisible); michael@0: michael@0: promise = waitForEvent(document, "popupshown"); michael@0: sendContextMenuClickToSelection(tabWindow); michael@0: yield promise; michael@0: michael@0: let copyMenuItem = document.getElementById("context-copy"); michael@0: michael@0: ok(!copyMenuItem.hidden, "Copy menu item should be visible."); michael@0: michael@0: promise = waitForEvent(document, "popuphidden"); michael@0: sendNativeTap(copyMenuItem, 5, 5); michael@0: yield promise; michael@0: yield waitForCondition(() => michael@0: !!SpecialPowers.getClipboardData("text/unicode")); michael@0: michael@0: ok(SelectionHelperUI.isSelectionUIVisible, michael@0: "Selection monocles should stay active after copy action."); michael@0: michael@0: Browser.closeTab(Browser.selectedTab, { forceClose: true }); michael@0: } michael@0: }); michael@0: michael@0: function test() { michael@0: setDevPixelEqualToPx(); michael@0: runTests(); michael@0: }