summaryrefslogtreecommitdiffstats
path: root/comm/suite/browser/test/mochitest/test_contextmenu.html
diff options
context:
space:
mode:
Diffstat (limited to 'comm/suite/browser/test/mochitest/test_contextmenu.html')
-rw-r--r--comm/suite/browser/test/mochitest/test_contextmenu.html931
1 files changed, 931 insertions, 0 deletions
diff --git a/comm/suite/browser/test/mochitest/test_contextmenu.html b/comm/suite/browser/test/mochitest/test_contextmenu.html
new file mode 100644
index 0000000000..0dea49c925
--- /dev/null
+++ b/comm/suite/browser/test/mochitest/test_contextmenu.html
@@ -0,0 +1,931 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Tests for browser context menu</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+Browser context menu tests.
+<p id="display"></p>
+
+<div id="content">
+</div>
+
+<pre id="test">
+<script class="testbody">
+
+/** Test for Login Manager: multiple login autocomplete. **/
+
+SpecialPowers.ChromeUtils.import("resource://gre/modules/InlineSpellChecker.jsm", window);
+SpecialPowers.ChromeUtils.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm", window);
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+
+function openContextMenuFor(element, shiftkey, waitForSpellCheck) {
+ // Context menu should be closed before we open it again.
+ is(SpecialPowers.wrap(contextMenu).state, "closed", "checking if popup is closed");
+
+ if (lastElement)
+ lastElement.blur();
+ element.focus();
+
+ // Some elements need time to focus and spellcheck before any tests are
+ // run on them.
+ function actuallyOpenContextMenuFor() {
+ lastElement = element;
+ var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
+ synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
+ }
+
+ if (waitForSpellCheck)
+ onSpellCheck(element, actuallyOpenContextMenuFor);
+ else
+ actuallyOpenContextMenuFor();
+}
+
+function closeContextMenu() {
+ contextMenu.hidePopup();
+}
+
+function executeCopyCommand(command, expectedValue)
+{
+ // Just execute the command directly rather than simulating a context menu
+ // press to avoid having to deal with its asynchronous nature
+ SpecialPowers.wrap(subwindow).controllers.getControllerForCommand(command).doCommand(command);
+
+ // The easiest way to check the clipboard is to paste the contents into a
+ // textbox
+ input.focus();
+ input.value = "";
+ SpecialPowers.wrap(input).controllers.getControllerForCommand("cmd_paste").doCommand("cmd_paste");
+ is(input.value, expectedValue, "paste for command " + command);
+}
+
+function invokeItemAction(generatedItemId)
+{
+ var item = contextMenu.getElementsByAttribute("generateditemid",
+ generatedItemId)[0];
+ ok(item, "Got generated XUL menu item");
+ item.doCommand();
+ is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
+}
+
+function getVisibleMenuItems(aMenu, aData) {
+ var items = [];
+ var accessKeys = {};
+ for (var i = 0; i < aMenu.childNodes.length; i++) {
+ var item = aMenu.childNodes[i];
+ if (item.hidden)
+ continue;
+
+ var key = item.accessKey;
+ if (key)
+ key = key.toLowerCase();
+
+ var isGenerated = item.hasAttribute("generateditemid");
+
+ if (item.nodeName == "menuitem") {
+ var isSpellSuggestion = item.className == "spell-suggestion";
+ if (isSpellSuggestion) {
+ is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
+ } else if (isGenerated) {
+ is(item.id, "", "child menuitem #" + i + " is a generated item");
+ } else {
+ ok(item.id, "child menuitem #" + i + " has an ID");
+ }
+ var label = item.getAttribute("label");
+ ok(label.length, "menuitem " + item.id + " has a label");
+ if (isSpellSuggestion) {
+ is(key, "", "Spell suggestions shouldn't have an access key");
+ items.push("*" + label);
+ } else if (isGenerated) {
+ items.push("+" + label);
+ } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
+ item.id != "spell-no-suggestions") {
+ ok(key, "menuitem " + item.id + " has an access key");
+ if (accessKeys[key])
+ ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
+ else
+ accessKeys[key] = item.id;
+ }
+ if (!isSpellSuggestion && !isGenerated) {
+ items.push(item.id);
+ }
+ if (isGenerated) {
+ var p = {};
+ p.type = item.getAttribute("type");
+ p.icon = item.getAttribute("image");
+ p.checked = item.hasAttribute("checked");
+ p.disabled = item.hasAttribute("disabled");
+ items.push(p);
+ } else {
+ items.push(!item.disabled);
+ }
+ } else if (item.nodeName == "menuseparator") {
+ ok(true, "--- seperator id is " + item.id);
+ items.push("---");
+ items.push(null);
+ } else if (item.nodeName == "menu") {
+ if (isGenerated) {
+ item.id = "generated-submenu-" + aData.generatedSubmenuId++;
+ }
+ ok(item.id, "child menu #" + i + " has an ID");
+ if (!isGenerated) {
+ ok(key, "menu has an access key");
+ if (accessKeys[key])
+ ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
+ else
+ accessKeys[key] = item.id;
+ }
+ items.push(item.id);
+ items.push(!item.disabled);
+ // Add a dummy item to that the indexes in checkMenu are the same
+ // for expectedItems and actualItems.
+ items.push([]);
+ items.push(null);
+ } else {
+ ok(false, "child #" + i + " of menu ID " + aMenu.id +
+ " has an unknown type (" + item.nodeName + ")");
+ }
+ }
+ return items;
+}
+
+function checkContextMenu(expectedItems) {
+ is(contextMenu.state, "open", "checking if popup is open");
+ var data = { generatedSubmenuId: 1 };
+ checkMenu(contextMenu, expectedItems, data);
+}
+
+/*
+ * checkMenu - checks to see if the specified <menupopup> contains the
+ * expected items and state.
+ * expectedItems is a array of (1) item IDs and (2) a boolean specifying if
+ * the item is enabled or not (or null to ignore it). Submenus can be checked
+ * by providing a nested array entry after the expected <menu> ID.
+ * For example: ["blah", true, // item enabled
+ * "submenu", null, // submenu
+ * ["sub1", true, // submenu contents
+ * "sub2", false], null, // submenu contents
+ * "lol", false] // item disabled
+ *
+ */
+function checkMenu(menu, expectedItems, data) {
+ var actualItems = getVisibleMenuItems(menu, data);
+ //ok(false, "Items are: " + actualItems);
+ for (var i = 0; i < expectedItems.length; i+=2) {
+ var actualItem = actualItems[i];
+ var actualEnabled = actualItems[i + 1];
+ var expectedItem = expectedItems[i];
+ var expectedEnabled = expectedItems[i + 1];
+ if (expectedItem instanceof Array) {
+ ok(true, "Checking submenu...");
+ var menuID = expectedItems[i - 2]; // The last item was the menu ID.
+ var submenu = menu.getElementsByAttribute("id", menuID)[0];
+ ok(submenu && submenu.nodeName == "menu", "got expected submenu element");
+ checkMenu(submenu.menupopup, expectedItem, data);
+ } else {
+ is(actualItem, expectedItem,
+ "checking item #" + i/2 + " (" + expectedItem + ") name");
+
+ if (typeof expectedEnabled == "object" && expectedEnabled != null ||
+ typeof actualEnabled == "object" && actualEnabled != null) {
+
+ ok(!(actualEnabled == null), "actualEnabled is not null");
+ ok(!(expectedEnabled == null), "expectedEnabled is not null");
+ is(typeof actualEnabled, typeof expectedEnabled, "checking types");
+
+ if (typeof actualEnabled != typeof expectedEnabled ||
+ actualEnabled == null || expectedEnabled == null)
+ continue;
+
+ is(actualEnabled.type, expectedEnabled.type,
+ "checking item #" + i/2 + " (" + expectedItem + ") type attr value");
+ var icon = actualEnabled.icon;
+ if (icon) {
+ var tmp = "";
+ var j = icon.length - 1;
+ while (j && icon[j] != "/") {
+ tmp = icon[j--] + tmp;
+ }
+ icon = tmp;
+ }
+ is(icon, expectedEnabled.icon,
+ "checking item #" + i/2 + " (" + expectedItem + ") icon attr value");
+ is(actualEnabled.checked, expectedEnabled.checked,
+ "checking item #" + i/2 + " (" + expectedItem + ") has checked attr");
+ is(actualEnabled.disabled, expectedEnabled.disabled,
+ "checking item #" + i/2 + " (" + expectedItem + ") has disabled attr");
+ } else if (expectedEnabled != null)
+ is(actualEnabled, expectedEnabled,
+ "checking item #" + i/2 + " (" + expectedItem + ") enabled state");
+ }
+ }
+ // Could find unexpected extra items at the end...
+ is(actualItems.length, expectedItems.length, "checking expected number of menu entries");
+}
+
+/*
+ * runTest
+ *
+ * Called by a popupshowing event handler. Each test checks for expected menu
+ * contents, closes the popup, and finally triggers the popup on a new element
+ * (thus kicking off another cycle).
+ *
+ */
+function runTest(testNum) {
+ ok(true, "Starting test #" + testNum);
+
+ switch (testNum) {
+ case 1:
+ // Invoke context menu for next test.
+ openContextMenuFor(text);
+ break;
+
+ case 2:
+ // Context menu for plain text
+ plainTextItems = ["context-back", false,
+ "context-forward", false,
+ "context-reload", true,
+ "context-stop", false,
+ "---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "context-sendpage", true,
+ "---", null,
+ "context-viewbgimage", false,
+ "context-selectall", true,
+ "---", null,
+ "context-viewsource", true,
+ "context-viewinfo", true];
+ checkContextMenu(plainTextItems);
+ closeContextMenu();
+ openContextMenuFor(link); // Invoke context menu for next test.
+ break;
+
+ case 3:
+ // Context menu for text link
+ checkContextMenu(["context-openlinkintab", true,
+ "context-openlink", true,
+ "context-openlinkinprivatewindow", true,
+ "---", null,
+ "context-bookmarklink", true,
+ "context-savelink", true,
+ "context-sendlink", true,
+ "context-copylink", true,
+ "---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "---", null,
+ "context-metadata", true]);
+ closeContextMenu();
+ openContextMenuFor(mailto); // Invoke context menu for next test.
+ break;
+
+ case 4:
+ // Context menu for text mailto-link
+ checkContextMenu(["context-copyemail", true,
+ "context-copylink", true,
+ "---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "---", null,
+ "context-metadata", true]);
+ closeContextMenu();
+ openContextMenuFor(input); // Invoke context menu for next test.
+ break;
+
+ case 5:
+ // Context menu for text input field
+ checkContextMenu(["context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", false,
+ "---", null,
+ "spell-check-enabled", true]);
+ closeContextMenu();
+ input_sel.value = "test";
+ input_sel.select();
+ openContextMenuFor(input_sel); // Invoke context menu for next test.
+ break;
+
+ case 6:
+ // Context menu for text input field with text
+ checkContextMenu(["context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", true,
+ "context-copy", true,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", true,
+ "---", null,
+ "context-selectall", true,
+ "context-searchselect", true,
+ "---", null,
+ "spell-check-enabled", true]);
+ closeContextMenu();
+ openContextMenuFor(img); // Invoke context menu for next test.
+ break;
+
+ case 7:
+ // Context menu for an image
+ checkContextMenu(["context-reloadimage", true,
+ "context-viewimage", true,
+ "context-blockimage", true,
+ "context-copyimage", true,
+ "---", null,
+ "context-saveimage", true,
+ "context-sendimage", true].concat(
+ ("@mozilla.org/suite/shell-service;1" in Cc) ?
+ ["context-setDesktopBackground", true] : []).concat(
+ ["---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "context-sendpage", true,
+ "---", null,
+ "context-metadata", true]));
+ closeContextMenu();
+ openContextMenuFor(canvas); // Invoke context menu for next test.
+ break;
+
+ case 8:
+ // Context menu for a canvas
+ checkContextMenu(["context-viewimage", true,
+ "context-saveimage", true,
+ "context-bookmarkpage", true,
+ "context-sendpage", true,
+ "context-selectall", true]);
+ closeContextMenu();
+ openContextMenuFor(video_ok); // Invoke context menu for next test.
+ break;
+
+ case 9:
+ // Context menu for a video (with a VALID media source)
+ checkContextMenu(["context-media-play", true,
+ "context-media-mute", true,
+ "context-media-playbackrate", true,
+ ["context-media-playbackrate-050", true,
+ "context-media-playbackrate-100", true,
+ "context-media-playbackrate-150", true,
+ "context-media-playbackrate-200", true], null,
+ "context-media-hidecontrols", true,
+ "context-video-showstats", true,
+ "context-video-fullscreen", true,
+ "---", null,
+ "context-viewvideo", true,
+ "context-copyvideourl", true,
+ "---", null,
+ "context-savevideo", true,
+ "context-sendvideo", true,
+ "context-video-saveimage", true]);
+ closeContextMenu();
+ openContextMenuFor(audio_in_video); // Invoke context menu for next test.
+ break;
+
+ case 10:
+ // Context menu for a video (with an audio-only file)
+ checkContextMenu(["context-media-play", true,
+ "context-media-mute", true,
+ "context-media-playbackrate", true,
+ ["context-media-playbackrate-050", true,
+ "context-media-playbackrate-100", true,
+ "context-media-playbackrate-150", true,
+ "context-media-playbackrate-200", true], null,
+ "context-media-showcontrols", true,
+ "---", null,
+ "context-copyaudiourl", true,
+ "---", null,
+ "context-saveaudio", true,
+ "context-sendaudio", true]);
+ closeContextMenu();
+ openContextMenuFor(video_bad); // Invoke context menu for next test.
+ break;
+
+ case 11:
+ // Context menu for a video (with an INVALID media source)
+ checkContextMenu(["context-media-play", false,
+ "context-media-mute", false,
+ "context-media-playbackrate", false,
+ ["context-media-playbackrate-050", null,
+ "context-media-playbackrate-100", null,
+ "context-media-playbackrate-150", null,
+ "context-media-playbackrate-200", null], null,
+ "context-media-hidecontrols", false,
+ "context-video-showstats", false,
+ "context-video-fullscreen", false,
+ "---", null,
+ "context-viewvideo", true,
+ "context-copyvideourl", true,
+ "---", null,
+ "context-savevideo", true,
+ "context-sendvideo", true,
+ "context-video-saveimage", false]);
+ closeContextMenu();
+ openContextMenuFor(video_bad2); // Invoke context menu for next test.
+ break;
+
+ case 12:
+ // Context menu for a video (with an INVALID media source)
+ checkContextMenu(["context-media-play", false,
+ "context-media-mute", false,
+ "context-media-playbackrate", false,
+ ["context-media-playbackrate-050", null,
+ "context-media-playbackrate-100", null,
+ "context-media-playbackrate-150", null,
+ "context-media-playbackrate-200", null], null,
+ "context-media-hidecontrols", false,
+ "context-video-showstats", false,
+ "context-video-fullscreen", false,
+ "---", null,
+ "context-viewvideo", false,
+ "context-copyvideourl", false,
+ "---", null,
+ "context-savevideo", false,
+ "context-sendvideo", false,
+ "context-video-saveimage", false]);
+ closeContextMenu();
+ openContextMenuFor(iframe); // Invoke context menu for next test.
+ break;
+
+ case 13:
+ // Context menu for an iframe
+ checkContextMenu(["context-back", false,
+ "context-forward", false,
+ "context-reload", true,
+ "context-stop", false,
+ "---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "context-sendpage", true,
+ "---", null,
+ "context-viewbgimage", false,
+ "context-selectall", true,
+ "---", null,
+ "context-viewsource", true,
+ "context-viewinfo", true,
+ "---", null,
+ "frame", null,
+ ["context-showonlythisframe", true,
+ "context-openframeintab", true,
+ "context-openframe", true,
+ "---", null,
+ "context-reloadframe", true,
+ "---", null,
+ "context-bookmarkframe", true,
+ "context-saveframe", true,
+ "context-sendframe", true,
+ "---", null,
+ "context-viewframesource", true,
+ "context-viewframeinfo", true], null]);
+ closeContextMenu();
+ openContextMenuFor(video_in_iframe); // Invoke context menu for next test.
+ break;
+
+ case 14:
+ // Context menu for a video in an iframe
+ checkContextMenu(["context-media-play", true,
+ "context-media-mute", true,
+ "context-media-playbackrate", true,
+ ["context-media-playbackrate-050", true,
+ "context-media-playbackrate-100", true,
+ "context-media-playbackrate-150", true,
+ "context-media-playbackrate-200", true], null,
+ "context-media-hidecontrols", true,
+ "context-video-showstats", true,
+ "context-video-fullscreen", true,
+ "---", null,
+ "context-viewvideo", true,
+ "context-copyvideourl", true,
+ "---", null,
+ "context-savevideo", true,
+ "context-sendvideo", true,
+ "context-video-saveimage", true,
+ "---", null,
+ "frame", null,
+ ["context-showonlythisframe", true,
+ "context-openframeintab", true,
+ "context-openframe", true,
+ "---", null,
+ "context-reloadframe", true,
+ "---", null,
+ "context-bookmarkframe", true,
+ "context-saveframe", true,
+ "context-sendframe", true,
+ "---", null,
+ "context-viewframesource", true,
+ "context-viewframeinfo", true], null]);
+ closeContextMenu();
+ openContextMenuFor(image_in_iframe); // Invoke context menu for next test.
+ break;
+
+ case 15:
+ // Context menu for an image in an iframe
+ checkContextMenu(["context-reloadimage", true,
+ "context-viewimage", true,
+ "context-blockimage", true,
+ "context-copyimage", true,
+ "---", null,
+ "context-saveimage", true,
+ "context-sendimage", true,
+ ].concat(
+ ("@mozilla.org/suite/shell-service;1" in Cc) ?
+ ["context-setDesktopBackground", true] : [])
+ .concat(
+ ["---", null,
+ "context-sendpage", true,
+ "---", null,
+ "context-metadata", true,
+ "---", null,
+ "frame", null,
+ ["context-showonlythisframe", true,
+ "context-openframeintab", true,
+ "context-openframe", true,
+ "---", null,
+ "context-reloadframe", true,
+ "---", null,
+ "context-bookmarkframe", true,
+ "context-saveframe", true,
+ "context-sendframe", true,
+ "---", null,
+ "context-viewframesource", true,
+ "context-viewframeinfo", true], null]));
+ closeContextMenu();
+ openContextMenuFor(text); // Invoke context menu for next test.
+ break;
+
+ case 16:
+ // Re-check context menu for plain text to make sure it hasn't changed
+ checkContextMenu(plainTextItems);
+ closeContextMenu();
+ textarea_sel.select();
+ openContextMenuFor(textarea_sel, false, true);
+ break;
+
+ case 17:
+ // search for text with text area's selected value
+ checkContextMenu(["context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", true,
+ "context-copy", true,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", true,
+ "---", null,
+ "context-selectall", true,
+ "context-searchselect", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+ closeContextMenu();
+ openContextMenuFor(textarea, false, true); // Invoke context menu for next test, but wait for the spellcheck.
+ break;
+
+ case 18:
+ // Context menu for textarea
+ checkContextMenu(["*chubbiness", true, // spelling suggestion
+ "---", null,
+ "spell-add-to-dictionary", true,
+ "spell-ignore-word", true,
+ "---", null,
+ "context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+
+ contextMenu.ownerDocument.getElementById("spell-add-to-dictionary").doCommand(); // Add to dictionary
+ closeContextMenu();
+ openContextMenuFor(textarea, false, true); // Invoke context menu for next test.
+ break;
+
+ case 19:
+ // Context menu for textarea after a word has been added
+ // to the dictionary
+ checkContextMenu(["spell-undo-add-to-dictionary", true,
+ "---", null,
+ "context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null,
+ ]);
+
+ contextMenu.ownerDocument.getElementById("spell-undo-add-to-dictionary").doCommand(); // Undo add to dictionary
+ closeContextMenu();
+ openContextMenuFor(contenteditable, false, true);
+ break;
+
+ case 20:
+ // Context menu for contenteditable
+ checkContextMenu(["spell-no-suggestions", false,
+ "---", null,
+ "spell-add-to-dictionary", true,
+ "spell-ignore-word", true,
+ "---", null,
+ "context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+
+ closeContextMenu();
+ openContextMenuFor(inputspell, false, true); // Invoke context menu for next test.
+ break;
+
+ case 21:
+ // Context menu for spell-check input
+ checkContextMenu(["*prodigality", true, // spelling suggestion
+ "---", null,
+ "spell-add-to-dictionary", true,
+ "spell-ignore-word", true,
+ "---", null,
+ "context-undo", false,
+ "context-redo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+
+ closeContextMenu();
+ openContextMenuFor(link); // Invoke context menu for next test.
+ break;
+
+ case 22:
+ executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
+ closeContextMenu();
+ openContextMenuFor(pagemenu); // Invoke context menu for next test.
+ break;
+
+ case 23:
+ // Context menu for element with assigned content context menu
+ checkContextMenu(["+Plain item", {type: "", icon: "", checked: false, disabled: false},
+ "+Disabled item", {type: "", icon: "", checked: false, disabled: true},
+ "+Item w/ textContent", {type: "", icon: "", checked: false, disabled: false},
+ "---", null,
+ "+Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false},
+ "---", null,
+ "+Radio1", {type: "checkbox", icon: "", checked: true, disabled: false},
+ "+Radio2", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "---", null,
+ "+Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false},
+ "+Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false},
+ "---", null,
+ "generated-submenu-1", true,
+ ["+Radio1", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "+Radio2", {type: "checkbox", icon: "", checked: true, disabled: false},
+ "+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
+ "---", null,
+ "+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null,
+ "---", null,
+ "context-back", false,
+ "context-forward", false,
+ "context-reload", true,
+ "context-stop", false,
+ "---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "context-sendpage", true,
+ "---", null,
+ "context-viewbgimage", false,
+ "context-selectall", true,
+ "---", null,
+ "context-viewsource", true,
+ "context-viewinfo", true]);
+
+ invokeItemAction("0");
+ closeContextMenu();
+ openContextMenuFor(pagemenu, true); // Invoke context menu for next test.
+ break;
+
+ case 24:
+ // Context menu for element with assigned content context menu
+ // The shift key should bypass content context menu processing
+ checkContextMenu(["context-back", false,
+ "context-forward", false,
+ "context-reload", true,
+ "context-stop", false,
+ "---", null,
+ "context-bookmarkpage", true,
+ "context-savepage", true,
+ "context-sendpage", true,
+ "---", null,
+ "context-viewbgimage", false,
+ "context-selectall", true,
+ "---", null,
+ "context-viewsource", true,
+ "context-viewinfo", true]);
+ closeContextMenu();
+
+ // Continue with SeaMonkey specific cases.
+ openContextMenuFor(img_link); // Invoke context menu for next test.
+ break;
+
+ case 25:
+ // Context menu for an image with a link
+ checkContextMenu(["context-openlinkintab", true,
+ "context-openlink", true,
+ "context-openlinkinprivatewindow", true,
+ "---", null,
+ "context-bookmarklink", true,
+ "context-savelink", true,
+ "context-sendlink", true,
+ "context-copylink", true,
+ "---", null,
+ "context-reloadimage", true,
+ "context-viewimage", true,
+ "context-blockimage", true,
+ "context-copyimage", true,
+ "---", null,
+ "context-saveimage", true,
+ "context-sendimage", true].concat(
+ ("@mozilla.org/suite/shell-service;1" in Cc) ?
+ ["context-setDesktopBackground", true] : []).concat(
+ ["---", null,
+ "context-bookmarkpage", true,
+ "---", null,
+ "context-metadata", true]));
+ closeContextMenu();
+ openContextMenuFor(img_mailto); // Invoke context menu for next test.
+ break;
+
+ case 26:
+ // Context menu for an image with a mailto: link
+ checkContextMenu(["context-copyemail", true,
+ "context-copylink", true,
+ "---", null,
+ "context-reloadimage", true,
+ "context-viewimage", true,
+ "context-blockimage", true,
+ "context-copyimage", true,
+ "---", null,
+ "context-saveimage", true,
+ "context-sendimage", true].concat(
+ ("@mozilla.org/suite/shell-service;1" in Cc) ?
+ ["context-setDesktopBackground", true] : []).concat(
+ ["---", null,
+ "context-bookmarkpage", true,
+ "---", null,
+ "context-metadata", true]));
+ closeContextMenu();
+
+ subwindow.close();
+ SimpleTest.finish();
+ return;
+
+ /*
+ * Other things that would be nice to test:
+ * - selected text
+ * - spelling / misspelled word (in text input?)
+ * - check state of disabled items
+ * - test execution of menu items (maybe as a separate test?)
+ */
+
+ default:
+ ok(false, "Unexpected invocation of test #" + testNum);
+ subwindow.close();
+ SimpleTest.finish();
+ return;
+ }
+
+}
+
+
+var testNum = 1;
+var subwindow, chromeWin, contextMenu, lastElement;
+var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2,
+ iframe, video_in_iframe, image_in_iframe, textarea, contenteditable,
+ inputspell, pagemenu, audio_in_video;
+
+// SeaMonkey specific variables.
+var img_link, img_mailto;
+
+function startTest() {
+ chromeWin = SpecialPowers.wrap(subwindow)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .QueryInterface(Ci.nsIDOMChromeWindow);
+ contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
+ ok(contextMenu, "Got context menu XUL");
+
+ if (chromeWin.document.getElementById("context-stop").getAttribute("disabled") != "true") {
+ isnot(false, "Document still loading");
+ SimpleTest.executeSoon(startTest);
+ return;
+ }
+
+ lastElement = null;
+
+ text = subwindow.document.getElementById("test-text");
+ link = subwindow.document.getElementById("test-link");
+ mailto = subwindow.document.getElementById("test-mailto");
+ input = subwindow.document.getElementById("test-input");
+ input_sel = subwindow.document.getElementById("test-input-select");
+ img = subwindow.document.getElementById("test-image");
+ canvas = subwindow.document.getElementById("test-canvas");
+ video_ok = subwindow.document.getElementById("test-video-ok");
+ audio_in_video = subwindow.document.getElementById("test-audio-in-video");
+ video_bad = subwindow.document.getElementById("test-video-bad");
+ video_bad2 = subwindow.document.getElementById("test-video-bad2");
+ iframe = subwindow.document.getElementById("test-iframe");
+ video_in_iframe = subwindow.document.getElementById("test-video-in-iframe").contentDocument.getElementsByTagName("video")[0];
+ // Ensure that contextmenu has 'context-media-play' item when check runs.
+ video_in_iframe.pause();
+ image_in_iframe = subwindow.document.getElementById("test-image-in-iframe").contentDocument.getElementsByTagName("img")[0];
+ textarea = subwindow.document.getElementById("test-textarea");
+ textarea_sel = subwindow.document.getElementById("test-textarea-sel");
+ contenteditable = subwindow.document.getElementById("test-contenteditable");
+ contenteditable.focus(); // content editable needs to be focused to enable spellcheck
+ inputspell = subwindow.document.getElementById("test-input-spellcheck");
+ pagemenu = subwindow.document.getElementById("test-pagemenu");
+
+ // SeaMonkey specific elements.
+ img_link = subwindow.document.getElementById("test-image-link");
+ img_mailto = subwindow.document.getElementById("test-image-mailto");
+
+ contextMenu.addEventListener("popupshown", function() { runTest(++testNum); });
+ runTest(1);
+}
+
+// We open this in a separate window, because the Mochitests run inside a frame.
+// The frame causes an extra menu item, and prevents running the test
+// standalone (ie, clicking the test name in the Mochitest window) to see
+// success/failure messages.
+var painted = false, loaded = false;
+
+function waitForEvents(event)
+{
+ if (event.type == "MozAfterPaint")
+ painted = true;
+ else if (event.type == "load")
+ loaded = true;
+ if (painted && loaded) {
+ subwindow.removeEventListener("MozAfterPaint", waitForEvents);
+ subwindow.onload = null;
+ startTest();
+ }
+}
+
+var subwindow = window.open("./subtst_contextmenu.html", "contextmenu-subtext", "width=600,height=700");
+subwindow.addEventListener("MozAfterPaint", waitForEvents);
+subwindow.onload = waitForEvents;
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>