Bug 1159490 - Allow cut/copy event dispatch unconditionally in HTML documents. r=neil
authorMichael Layzell <michael@thelayzells.com>
Wed, 13 May 2015 08:44:00 +0200
changeset 245567 1921222e708e8b070b8ef5db215d5bec2217d375
parent 245566 0431f570160df1497943b8d7039b5f70c4b45e74
child 245568 0ecd4281ab79b5e9c32d366fe1b2476a238a6b40
push id60210
push usercbook@mozilla.com
push dateTue, 26 May 2015 07:11:41 +0000
treeherdermozilla-inbound@1921222e708e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersneil
bugs1159490
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1159490 - Allow cut/copy event dispatch unconditionally in HTML documents. r=neil
browser/base/content/test/general/test_contextmenu.html
browser/base/content/test/general/test_contextmenu_input.html
browser/components/customizableui/test/browser_947914_button_copy.js
browser/components/customizableui/test/browser_947914_button_cut.js
browser/devtools/scratchpad/test/browser_scratchpad_edit_ui_updates.js
toolkit/content/editMenuOverlay.js
toolkit/content/globalOverlay.js
toolkit/content/tests/chrome/bug366992_window.xul
--- a/browser/base/content/test/general/test_contextmenu.html
+++ b/browser/base/content/test/general/test_contextmenu.html
@@ -352,18 +352,18 @@ function runTest(testNum) {
         closeContextMenu();
         openContextMenuFor(textarea); // Invoke context menu for next test
     },
 
     function () {
         // Context menu for textarea before spell check initialization finishes
         checkContextMenu(["context-undo",                false,
                           "---",                         null,
-                          "context-cut",                 false,
-                          "context-copy",                false,
+                          "context-cut",                 true,
+                          "context-copy",                true,
                           "context-paste",               null,
                           "context-delete",              false,
                           "---",                         null,
                           "context-selectall",           true,
                           "---",                         null,
                           "spell-add-dictionaries-main", true,
                          ].concat(inspectItems));
         closeContextMenu();
@@ -372,18 +372,18 @@ function runTest(testNum) {
 
     function () {
         // Context menu for textarea after spell check initialization finishes
         checkContextMenu(["*chubbiness",         true, // spelling suggestion
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "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,
@@ -404,18 +404,18 @@ function runTest(testNum) {
 
     function () {
         // Context menu for textarea after a word has been added
         // to the dictionary
         checkContextMenu(["spell-undo-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "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,
@@ -429,18 +429,18 @@ function runTest(testNum) {
 
     function () {
         // Context menu for contenteditable
         checkContextMenu(["spell-no-suggestions", false,
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "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,
@@ -645,18 +645,18 @@ function runTest(testNum) {
         selectInputText(select_inputtext_password); // Select text prior to opening context menu.
         openContextMenuFor(select_inputtext_password); // Invoke context menu for next test.
     },
 
     function () {
         // Context menu for selected text in input[type="password"]
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      true,
                           "---",                 null,
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-check-enabled", true,
                           //spell checker is shown on input[type="password"] on this testcase
                           "spell-dictionaries",  true,
@@ -738,18 +738,18 @@ function runTest(testNum) {
         closeContextMenu();
         openContextMenuFor(inputspellfalse, false, true); // Invoke context menu for next test.
     },
 
     function () {
         // Context menu for text input field with spellcheck=false
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-add-dictionaries-main",  true,
                          ].concat(inspectItems));
 
--- a/browser/base/content/test/general/test_contextmenu_input.html
+++ b/browser/base/content/test/general/test_contextmenu_input.html
@@ -35,18 +35,18 @@ function runTest(testNum) {
     case 1:
         openContextMenuFor(input); // Invoke context menu for next test.
         break;
 
     case 2:
         // Context menu for text input field.
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   false,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "---",                 null,
                           "context-inspect",     true]);
@@ -56,18 +56,18 @@ function runTest(testNum) {
         openContextMenuFor(input, false, true);
         break;
 
     case 3:
         var value = false;
         // Context menu for spell-check input.
         checkContextMenu(["context-undo",        value,
                           "---",                 null,
-                          "context-cut",         value,
-                          "context-copy",        value,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      value,
                           "---",                 null,
                           "context-selectall",   value,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "spell-dictionaries",  true,
                               ["spell-check-dictionary-en-US", true,
@@ -85,18 +85,18 @@ function runTest(testNum) {
     case 4:
         var value = false;
         // Context menu for spell-check input with a unknwon word.
         checkContextMenu(["*prodigality",        true, // spelling suggestion
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        value,
                           "---",                 null,
-                          "context-cut",         value,
-                          "context-copy",        value,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      value,
                           "---",                 null,
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "spell-dictionaries",  true,
                               ["spell-check-dictionary-en-US", true,
@@ -110,18 +110,18 @@ function runTest(testNum) {
         openContextMenuFor(inputspellcorrect, false, true);
         break;
 
     case 5:
         var value = false;
         // Context menu for spell-check input with a known word.
         checkContextMenu(["context-undo",        value,
                           "---",                 null,
-                          "context-cut",         value,
-                          "context-copy",        value,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      value,
                           "---",                 null,
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "spell-dictionaries",  true,
                               ["spell-check-dictionary-en-US", true,
@@ -134,55 +134,72 @@ function runTest(testNum) {
         input.disabled = true;
         openContextMenuFor(input); // Invoke context menu for next test.
         break;
 
     case 6:
         // Context menu for disabled input.
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   true,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "---",                 null,
                           "context-inspect",     true]);
 
         closeContextMenu();
         input.disabled = false;
         input.type = 'password';
         openContextMenuFor(input); // Invoke context menu for next test.
         break;
 
     case 7: // password
-    case 8: // email
-    case 9: // url
-    case 10: // tel
-    case 11: // type='number'
-        // Context menu for tel, password, email, url and number input fields.
+        // Context menu for password input fields.
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   false,
                           "---",                 null,
                           "context-inspect",     true]);
 
         closeContextMenu();
 
-        if (testNum == 7) {
-          input.type = 'email';
-        } else if (testNum == 8) {
+        input.type = 'email';
+
+        openContextMenuFor(input); // Invoke context menu for next test.
+        break;
+
+    case 8: // email
+    case 9: // url
+    case 10: // tel
+    case 11: // type='number'
+        // Context menu for tel, email, url and number input fields.
+        checkContextMenu(["context-undo",        false,
+                          "---",                 null,
+                          "context-cut",         true,
+                          "context-copy",        true,
+                          "context-paste",       null, // ignore clipboard state
+                          "context-delete",      false,
+                          "---",                 null,
+                          "context-selectall",   false,
+                          "---",                 null,
+                          "context-inspect",     true]);
+
+        closeContextMenu();
+
+        if (testNum == 8) {
           input.type = 'url';
         } else if (testNum == 9) {
           input.type = 'tel';
         } else if (testNum == 10) {
           input.type = 'number';
         } else if (testNum == 11) {
           input.type = 'date';
         }
@@ -223,18 +240,18 @@ function runTest(testNum) {
 
         openContextMenuFor(input);
         break;
 
     case 16: // type='search'
         // Context menu for search input fields.
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   false,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "---",                 null,
                           "context-inspect",     true]);
@@ -252,18 +269,18 @@ function runTest(testNum) {
         input.readOnly = true;
         openContextMenuFor(input);
         break;
 
     case 17:
         // Context menu for a read-only input.
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
-                          "context-cut",         false,
-                          "context-copy",        false,
+                          "context-cut",         true,
+                          "context-copy",        true,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   false,
                           "---",                 null,
                           "context-inspect",     true]);
         closeContextMenu();
 
--- a/browser/components/customizableui/test/browser_947914_button_copy.js
+++ b/browser/components/customizableui/test/browser_947914_button_copy.js
@@ -14,26 +14,26 @@ add_task(function() {
 
   gURLBar.focus();
   info("The URL bar was focused");
   yield PanelUI.show();
   info("Menu panel was opened");
 
   let copyButton = document.getElementById("copy-button");
   ok(copyButton, "Copy button exists in Panel Menu");
-  is(copyButton.getAttribute("disabled"), "true", "Copy button is initially disabled");
+  ok(!copyButton.getAttribute("disabled"), "Copy button is initially enabled");
 
   // copy text from URL bar
   gURLBar.value = testText;
   gURLBar.focus();
   gURLBar.select();
   yield PanelUI.show();
   info("Menu panel was opened");
 
-  ok(!copyButton.hasAttribute("disabled"), "Copy button gets enabled");
+  ok(!copyButton.hasAttribute("disabled"), "Copy button is enabled when selecting");
 
   copyButton.click();
   is(gURLBar.value, testText, "Selected text is unaltered when clicking copy");
 
   // check that the text was added to the clipboard
   let clipboard = Services.clipboard;
   let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
   globalClipboard = clipboard.kGlobalClipboard;
--- a/browser/components/customizableui/test/browser_947914_button_cut.js
+++ b/browser/components/customizableui/test/browser_947914_button_cut.js
@@ -13,26 +13,26 @@ add_task(function() {
   let testText = "cut text test";
 
   gURLBar.focus();
   yield PanelUI.show();
   info("Menu panel was opened");
 
   let cutButton = document.getElementById("cut-button");
   ok(cutButton, "Cut button exists in Panel Menu");
-  ok(cutButton.getAttribute("disabled"), "Cut button is disabled");
+  ok(!cutButton.hasAttribute("disabled"), "Cut button is enabled");
 
   // cut text from URL bar
   gURLBar.value = testText;
   gURLBar.focus();
   gURLBar.select();
   yield PanelUI.show();
   info("Menu panel was opened");
 
-  ok(!cutButton.hasAttribute("disabled"), "Cut button gets enabled");
+  ok(!cutButton.hasAttribute("disabled"), "Cut button is enabled when selecting");
   cutButton.click();
   is(gURLBar.value, "", "Selected text is removed from source when clicking on cut");
 
   // check that the text was added to the clipboard
   let clipboard = Services.clipboard;
   let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
   globalClipboard = clipboard.kGlobalClipboard;
 
--- a/browser/devtools/scratchpad/test/browser_scratchpad_edit_ui_updates.js
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_edit_ui_updates.js
@@ -114,17 +114,17 @@ function runTests()
         }
       } else {
         menuPopup.hidePopup();
       }
     });
   };
 
   let firstShow = function() {
-    ok(cutItem.hasAttribute("disabled"), "cut menuitem is disabled");
+    ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled");
     closeMenu(firstHide);
   };
 
   let firstHide = function() {
     sp.editor.setSelection({ line: 0, ch: 0 }, { line: 0, ch: 10 });
     openMenu(11, 11, showAfterSelect);
   };
 
@@ -144,17 +144,17 @@ function runTests()
   };
 
   let onCut = function() {
     sp.editor.off("change", onCut);
     openMenu(12, 12, showAfterCut);
   };
 
   let showAfterCut = function() {
-    ok(cutItem.hasAttribute("disabled"), "cut menuitem is disabled after cut");
+    ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled after cut");
     ok(!pasteItem.hasAttribute("disabled"), "paste menuitem is enabled after cut");
     closeMenu(hideAfterCut);
   };
 
   let hideAfterCut = function() {
     waitForFocus(function () {
       sp.editor.on("change", onPaste);
       EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
@@ -162,17 +162,17 @@ function runTests()
   };
 
   let onPaste = function() {
     sp.editor.off("change", onPaste);
     openMenu(13, 13, showAfterPaste);
   };
 
   let showAfterPaste = function() {
-    ok(cutItem.hasAttribute("disabled"), "cut menuitem is disabled after paste");
+    ok(!cutItem.hasAttribute("disabled"), "cut menuitem is enabled after paste");
     ok(!pasteItem.hasAttribute("disabled"), "paste menuitem is enabled after paste");
     closeMenu(hideAfterPaste);
   };
 
   let hideAfterPaste = function() {
     if (pass == 0) {
       pass++;
       testContextMenu();
--- a/toolkit/content/editMenuOverlay.js
+++ b/toolkit/content/editMenuOverlay.js
@@ -12,18 +12,17 @@ function goUpdateGlobalEditMenuItems()
   // cut, copy, and paste buttons been added to the toolbars) for performance.
   // This only works in applications/on platforms that set the gEditUIVisible
   // flag, so we check to see if that flag is defined before using it.
   if (typeof gEditUIVisible != "undefined" && !gEditUIVisible)
     return;
 
   goUpdateCommand("cmd_undo");
   goUpdateCommand("cmd_redo");
-  goUpdateCommand("cmd_cut");
-  goUpdateCommand("cmd_copy");
+  // don't update the cmd_cut or cmd_copy items - as we want them to always be enabled
   goUpdateCommand("cmd_paste");
   goUpdateCommand("cmd_selectAll");
   goUpdateCommand("cmd_delete");
   goUpdateCommand("cmd_switchTextDirection");
 }
 
 // update menu items that relate to undo/redo
 function goUpdateUndoEditMenuItems()
--- a/toolkit/content/globalOverlay.js
+++ b/toolkit/content/globalOverlay.js
@@ -88,17 +88,17 @@ function goUpdateCommand(aCommand)
   }
 }
 
 function goDoCommand(aCommand)
 {
   try {
     var controller = top.document.commandDispatcher
                         .getControllerForCommand(aCommand);
-    if (controller && controller.isCommandEnabled(aCommand))
+    if (controller)
       controller.doCommand(aCommand);
   }
   catch (e) {
     Components.utils.reportError("An error occurred executing the " +
                                  aCommand + " command: " + e);
   }
 }
 
--- a/toolkit/content/tests/chrome/bug366992_window.xul
+++ b/toolkit/content/tests/chrome/bug366992_window.xul
@@ -14,44 +14,44 @@
         height="600"
         title="366992 test">
 
   <commandset id="editMenuCommands"/>
 
   <script type="application/javascript"
           src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript"><![CDATA[
-    // Without the fix for bug 366992, the copy command would be enabled
+    // Without the fix for bug 366992, the delete command would be enabled
     // for the textbox even though the textbox's controller for this command
     // disables it.
     var gShouldNotBeReachedController = {
       supportsCommand: function(aCommand) {
-        return aCommand == "cmd_copy";
+        return aCommand == "cmd_delete";
       },
       isCommandEnabled: function(aCommand) {
-        return aCommand == "cmd_copy";
+        return aCommand == "cmd_delete";
       },
       doCommand: function(aCommand) { }
     }
 
     function ok(condition, message) {
       window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
     }
     function finish() {
       window.controllers.removeController(gShouldNotBeReachedController);
       window.close();
       window.opener.wrappedJSObject.SimpleTest.finish();
     }
 
     function onLoad() {
       document.getElementById("textbox").focus();
-      var copyDisabled = document.getElementById("cmd_copy")
-                                 .getAttribute("disabled") == "true";
-      ok(copyDisabled,
-         "cmd_copy should be disabled when the empty textbox is focused");
+      var deleteDisabled = document.getElementById("cmd_delete")
+                                   .getAttribute("disabled") == "true";
+      ok(deleteDisabled,
+         "cmd_delete should be disabled when the empty textbox is focused");
       finish();
     }
     
     window.controllers.appendController(gShouldNotBeReachedController);
   ]]></script>
 
   <textbox id="textbox"/>
 </window>