Bug 1372276 - Part 1: Remove contextMenu from HTMLElement; r?bz,smaug draft
authorGordon P. Hemsley <gphemsley@gmail.com>
Sat, 29 Jul 2017 20:38:14 -0400
changeset 618196 06a3ac5234e2c3ea1b2df4f4e52d710fbb1f50c2
parent 618195 30a27786c6081cd8a2696d5a9f28b98c859fda35
child 618197 60e629d4f6b7a2ccc01d24f1f69ac47a2b7dcf4e
push id71235
push userbmo:gphemsley@gphemsley.org
push dateSun, 30 Jul 2017 14:44:40 +0000
reviewersbz, smaug
bugs1372276
milestone56.0a1
Bug 1372276 - Part 1: Remove contextMenu from HTMLElement; r?bz,smaug MozReview-Commit-ID: IbHWVE1IKO6
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_contextmenu.js
browser/base/content/test/general/browser_contextmenu_childprocess.js
browser/base/content/test/general/subtst_contextmenu.html
dom/base/nsTreeSanitizer.cpp
dom/browser-element/mochitest/browserElement_ContextmenuEvents.js
dom/html/nsGenericHTMLElement.cpp
dom/html/nsGenericHTMLElement.h
dom/html/test/browser.ini
dom/html/test/browser_content_contextmenu_userinput.js
dom/html/test/file_content_contextmenu.html
dom/webidl/HTMLElement.webidl
testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json
testing/runtimes/mochitest-browser-chrome.runtimes.json
testing/web-platform/meta/html/semantics/interactive-elements/contextmenu-historical.html.ini
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -587,18 +587,16 @@ support-files =
 [browser_blockHPKP.js]
 tags = psm
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_windowactivation.js]
 support-files =
   file_window_activation.html
   file_window_activation2.html
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
-[browser_contextmenu_childprocess.js]
-# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug963945.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_domFullscreen_fullscreenMode.js]
 tags = fullscreen
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_newTabDrop.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
--- a/browser/base/content/test/general/browser_contextmenu.js
+++ b/browser/base/content/test/general/browser_contextmenu.js
@@ -539,68 +539,16 @@ add_task(async function test_copylinkcom
         let doc = content.document;
         let input = doc.getElementById("test-input");
         Assert.equal(input.value, "http://mozilla.com/", "paste for command cmd_paste");
       });
     }
   });
 });
 
-add_task(async function test_pagemenu() {
-  await test_contextmenu("#test-pagemenu",
-    ["context-navigation",   null,
-         ["context-back",         false,
-          "context-forward",      false,
-          "context-reload",       true,
-          "context-bookmarkpage", true], null,
-     "---",                  null,
-     "+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-savepage",     true,
-     ...(hasPocket ? ["context-pocket", true] : []),
-     "---", null,
-     "context-sendpagetodevice", true, [], null,
-     "---",                  null,
-     "context-viewbgimage",  false,
-     "context-selectall",    true,
-     "---",                  null,
-     "context-viewsource",   true,
-     "context-viewinfo",     true
-    ],
-    {async postCheckContextMenuFn() {
-      let item = contextMenu.getElementsByAttribute("generateditemid", "1")[0];
-      ok(item, "Got generated XUL menu item");
-      item.doCommand();
-      await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
-        let pagemenu = content.document.getElementById("test-pagemenu");
-        Assert.ok(!pagemenu.hasAttribute("hopeless"), "attribute got removed");
-      });
-    },
-    maybeScreenshotsPresent: true
-  });
-});
-
 add_task(async function test_dom_full_screen() {
   await test_contextmenu("#test-dom-full-screen",
     ["context-navigation",           null,
          ["context-back",            false,
           "context-forward",         false,
           "context-reload",          true,
           "context-bookmarkpage",    true], null,
      "---",                          null,
@@ -642,17 +590,17 @@ add_task(async function test_dom_full_sc
           content.document.exitFullscreen();
           await awaitFullScreenChange;
         });
       }
     }
   );
 });
 
-add_task(async function test_pagemenu2() {
+add_task(async function test_text() {
   await test_contextmenu("#test-text",
     ["context-navigation", null,
          ["context-back",         false,
           "context-forward",      false,
           "context-reload",       true,
           "context-bookmarkpage", true], null,
      "---",                  null,
      "context-savepage",     true,
deleted file mode 100644
--- a/browser/base/content/test/general/browser_contextmenu_childprocess.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-const gBaseURL = "https://example.com/browser/browser/base/content/test/general/";
-
-add_task(async function() {
-  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, gBaseURL + "subtst_contextmenu.html");
-
-  let contextMenu = document.getElementById("contentAreaContextMenu");
-
-  // Get the point of the element with the page menu (test-pagemenu) and
-  // synthesize a right mouse click there.
-  let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
-  await BrowserTestUtils.synthesizeMouse("#test-pagemenu", 5, 5, { type: "contextmenu", button: 2 }, tab.linkedBrowser);
-  await popupShownPromise;
-
-  checkMenu(contextMenu);
-
-  let popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
-  contextMenu.hidePopup();
-  await popupHiddenPromise;
-
-  await BrowserTestUtils.removeTab(tab);
-});
-
-function checkItems(menuitem, arr) {
-  for (let i = 0; i < arr.length; i += 2) {
-    let str = arr[i];
-    let details = arr[i + 1];
-    if (str == "---") {
-      is(menuitem.localName, "menuseparator", "menuseparator");
-    } else if ("children" in details) {
-      is(menuitem.localName, "menu", "submenu");
-      is(menuitem.getAttribute("label"), str, str + " label");
-      checkItems(menuitem.firstChild.firstChild, details.children);
-    } else {
-      is(menuitem.localName, "menuitem", str + " menuitem");
-
-      is(menuitem.getAttribute("label"), str, str + " label");
-      is(menuitem.getAttribute("type"), details.type, str + " type");
-      is(menuitem.getAttribute("image"), details.icon ? gBaseURL + details.icon : "", str + " icon");
-
-      if (details.checked)
-        is(menuitem.getAttribute("checked"), "true", str + " checked");
-      else
-        ok(!menuitem.hasAttribute("checked"), str + " checked");
-
-      if (details.disabled)
-        is(menuitem.getAttribute("disabled"), "true", str + " disabled");
-      else
-        ok(!menuitem.hasAttribute("disabled"), str + " disabled");
-    }
-
-    menuitem = menuitem.nextSibling;
-  }
-}
-
-function checkMenu(contextMenu) {
-  let items = [ "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,
-                "Submenu",  { children:
-                  ["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}] }
-               ];
-  checkItems(contextMenu.childNodes[2], items);
-}
--- a/browser/base/content/test/general/subtst_contextmenu.html
+++ b/browser/base/content/test/general/subtst_contextmenu.html
@@ -21,51 +21,16 @@ Browser context menu subtest.
 <iframe id="test-iframe" width="98"  height="98" style="border: 1px solid black"></iframe>
 <iframe id="test-video-in-iframe" src="video.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
 <iframe id="test-audio-in-iframe" src="audio.ogg" width="98" height="98" style="border: 1px solid black"></iframe>
 <iframe id="test-image-in-iframe" src="ctxmenu-image.png" width="98" height="98" style="border: 1px solid black"></iframe>
 <textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
 <div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
 <div id="test-contenteditable-spellcheck-false" contenteditable="true" spellcheck="false">test</div> <!-- No Check Spelling menu item -->
 <div id="test-dom-full-screen">DOM full screen FTW</div>
-<div contextmenu="myMenu">
-  <p id="test-pagemenu" hopeless="true">I've got a context menu!</p>
-  <menu id="myMenu" type="context">
-    <menuitem label="Plain item" onclick="document.getElementById('test-pagemenu').removeAttribute('hopeless');"></menuitem>
-    <menuitem label="Disabled item" disabled></menuitem>
-    <menuitem> Item w/ textContent</menuitem>
-    <menu>
-      <menuitem type="checkbox" label="Checkbox" checked></menuitem>
-    </menu>
-    <menu>
-      <menuitem type="radio" label="Radio1" checked></menuitem>
-      <menuitem type="radio" label="Radio2"></menuitem>
-      <menuitem type="radio" label="Radio3"></menuitem>
-    </menu>
-    <menu>
-      <menuitem label="Item w/ icon" icon="favicon.ico"></menuitem>
-      <menuitem label="Item w/ bad icon" icon="data://www.mozilla.org/favicon.ico"></menuitem>
-    </menu>
-    <menu label="Submenu">
-      <menuitem type="radio" label="Radio1" radiogroup="rg"></menuitem>
-      <menuitem type="radio" label="Radio2" checked radiogroup="rg"></menuitem>
-      <menuitem type="radio" label="Radio3" radiogroup="rg"></menuitem>
-      <menu>
-        <menuitem type="checkbox" label="Checkbox"></menuitem>
-      </menu>
-    </menu>
-    <menu hidden>
-      <menuitem label="Bogus item"></menuitem>
-    </menu>
-    <menu>
-    </menu>
-    <menuitem label="Hidden item" hidden></menuitem>
-    <menuitem></menuitem>
-  </menu>
-</div>
 <div id="test-select-text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
 <div id="test-select-text-link">http://mozilla.com</div>
 <a id="test-image-link" href="#"><img src="ctxmenu-image.png"></a>
 <input id="test-select-input-text" type="text" value="input">
 <input id="test-select-input-text-type-password" type="password" value="password">
 <embed id="test-plugin" style="width: 200px; height: 200px;" type="application/x-test"></embed>
 <img id="test-longdesc" src="ctxmenu-image.png" longdesc="http://www.mozilla.org"></embed>
 <iframe id="test-srcdoc" width="98"  height="98" srcdoc="Hello World" style="border: 1px solid black"></iframe>
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -162,17 +162,16 @@ nsIAtom** const kAttributesHTML[] = {
   &nsGkAtoms::charset,
   &nsGkAtoms::checked,
   &nsGkAtoms::cite,
   &nsGkAtoms::_class,
   &nsGkAtoms::cols,
   &nsGkAtoms::colspan,
   &nsGkAtoms::content,
   &nsGkAtoms::contenteditable,
-  &nsGkAtoms::contextmenu,
   &nsGkAtoms::controls,
   &nsGkAtoms::coords,
   &nsGkAtoms::datetime,
   &nsGkAtoms::dir,
   &nsGkAtoms::disabled,
   &nsGkAtoms::draggable,
   &nsGkAtoms::enctype,
   &nsGkAtoms::face,
--- a/dom/browser-element/mochitest/browserElement_ContextmenuEvents.js
+++ b/dom/browser-element/mochitest/browserElement_ContextmenuEvents.js
@@ -11,155 +11,20 @@ var videoUrl = 'http://mochi.test:8888/t
 function runTests() {
   createIframe(function onIframeLoaded() {
     checkEmptyContextMenu();
   });
 }
 
 function checkEmptyContextMenu() {
   sendContextMenuTo('body', function onContextMenu(detail) {
-    is(detail.contextmenu, null, 'Body context clicks have no context menu');
-
-    checkInnerContextMenu();
-  });
-}
-
-function checkInnerContextMenu() {
-  sendContextMenuTo('#inner-link', function onContextMenu(detail) {
-    is(detail.systemTargets.length, 1, 'Includes anchor data');
-    is(detail.contextmenu.items.length, 3, 'Inner clicks trigger correct customized menu');
-    is(detail.contextmenu.items[0].label, 'foo', 'Customized menu has a "foo" menu item');
-    is(detail.contextmenu.items[1].label, 'bar', 'Customized menu has a "bar" menu item');
-    is(detail.contextmenu.items[2].id, 'copy-link', '#inner-link has a copy-link menu item');
-    is(detail.contextmenu.customized, true, 'Make sure contextmenu has customized items');
-
-    var target = detail.systemTargets[0];
-    is(target.nodeName, 'A', 'Reports correct nodeName');
-    is(target.data.uri, 'foo.html', 'Reports correct uri');
-    is(target.data.text, 'Menu 1', 'Reports correct link text');
-
-    checkCustomContextMenu();
-  });
-}
-
-function checkCustomContextMenu() {
-  sendContextMenuTo('#menu1-trigger', function onContextMenu(detail) {
-    is(detail.contextmenu.items.length, 2, 'trigger custom contextmenu');
-
-    checkNestedContextMenu();
-  });
-}
-
-function checkNestedContextMenu() {
-  sendContextMenuTo('#menu2-trigger', function onContextMenu(detail) {
-    var innerMenu = detail.contextmenu.items.filter(function(x) {
-      return x.type === 'menu';
-    });
-    is(detail.systemTargets.length, 2, 'Includes two systemTargets');
-    is(detail.systemTargets[0].nodeName, 'IMG', 'Includes "IMG" node');
-    is(detail.systemTargets[0].data.uri, 'example.png', 'Img data has the correct uri');
-    is(detail.systemTargets[1].nodeName, 'A', 'Includes "A" node');
-    is(detail.systemTargets[1].data.uri, 'bar.html', 'Anchor has the correct uri');
-    ok(innerMenu.length > 0, 'Menu contains a nested menu');
-
-    is(detail.contextmenu.items.length, 4, 'We have correct # of menu items')
-    is(detail.contextmenu.customized, true, 'Make sure contextmenu has customized items');
-    is(detail.contextmenu.items[0].label, 'outer', 'Customized menu has an "outer" menu item');
-    is(detail.contextmenu.items[1].label, 'submenu', 'Customized menu has an "submenu" menu item');
-    is(detail.contextmenu.items[2].id, 'copy-link', 'Has a copy-link menu item');
-    is(detail.contextmenu.items[3].id, 'copy-image', 'Has a copy-image menu item');
-    checkPreviousContextMenuHandler();
-  });
-}
-
- // Finished testing the data passed to the contextmenu handler,
- // now we start selecting contextmenu items
-function checkPreviousContextMenuHandler() {
-  // This is previously triggered contextmenu data, since we have
-  // fired subsequent contextmenus this should not be mistaken
-  // for a current menuitem
-  var detail = previousContextMenuDetail;
-  var previousId = detail.contextmenu.items[0].id;
-  checkContextMenuCallbackForId(detail, previousId, function onCallbackFired(label) {
-    is(label, null, 'Callback label should be empty since this handler is old');
-
-    checkCurrentContextMenuHandler();
+    checkVideoContextMenu();
   });
 }
 
-function checkCurrentContextMenuHandler() {
-  // This triggers a current menuitem
-  var detail = currentContextMenuDetail;
-
-  var innerMenu = detail.contextmenu.items.filter(function(x) {
-    return x.type === 'menu';
-  });
-
-  var currentId = innerMenu[0].items[1].id;
-  checkContextMenuCallbackForId(detail, currentId, function onCallbackFired(label) {
-    is(label, 'inner 2', 'Callback label should be set correctly');
-
-    checkAgainCurrentContextMenuHandler();
-  });
-}
-
-function checkAgainCurrentContextMenuHandler() {
-  // Once an item it selected, subsequent selections are ignored
-  var detail = currentContextMenuDetail;
-
-  var innerMenu = detail.contextmenu.items.filter(function(x) {
-    return x.type === 'menu';
-  });
-
-  var currentId = innerMenu[0].items[1].id;
-  checkContextMenuCallbackForId(detail, currentId, function onCallbackFired(label) {
-    is(label, null, 'Callback label should be empty since this handler has already been used');
-
-    checkCallbackWithPreventDefault();
-  });
-};
-
-// Finished testing callbacks if the embedder calls preventDefault() on the
-// mozbrowsercontextmenu event, now we start checking for some cases where the embedder
-// does not want to call preventDefault() for some reasons.
-function checkCallbackWithPreventDefault() {
-  sendContextMenuTo('#menu1-trigger', function onContextMenu(detail) {
-    var id = detail.contextmenu.items[0].id;
-    checkContextMenuCallbackForId(detail, id, function onCallbackFired(label) {
-      is(label, 'foo', 'Callback label should be set correctly');
-
-      checkCallbackWithoutPreventDefault();
-    });
-  });
-}
-
-function checkCallbackWithoutPreventDefault() {
-  sendContextMenuTo('#menu1-trigger', function onContextMenu(detail) {
-    var id = detail.contextmenu.items[0].id;
-    checkContextMenuCallbackForId(detail, id, function onCallbackFired(label) {
-      is(label, null, 'Callback label should be null');
-
-      checkImageContextMenu();
-    });
-  }, /* ignorePreventDefault */ true);
-}
-
-function checkImageContextMenu() {
-  sendContextMenuTo('#menu3-trigger', function onContextMenu(detail) {
-    var target = detail.systemTargets[0];
-    is(target.nodeName, 'IMG', 'Reports correct nodeName');
-    is(target.data.uri, 'example.png', 'Reports correct uri');
-    is(detail.contextmenu.items.length, 1, 'Reports correct # of menu items');
-    is(detail.contextmenu.items[0].id, 'copy-image', 'IMG has a copy-image menu item');
-    is(detail.contextmenu.customized, false, 'Make sure we do not have customized items');
-
-    checkVideoContextMenu();
-  }, /* ignorePreventDefault */ true);
-}
-
 function checkVideoContextMenu() {
   sendContextMenuTo('#menu4-trigger', function onContextMenu(detail) {
     var target = detail.systemTargets[0];
     is(target.nodeName, 'VIDEO', 'Reports correct nodeName');
     is(target.data.uri, videoUrl, 'Reports uri correctly in data');
     is(target.data.hasVideo, true, 'Video data in video tag does "hasVideo"');
 
     checkAudioContextMenu();
@@ -273,29 +138,16 @@ function checkContextMenuCallbackForId(d
 
 var iframe = null;
 function createIframe(callback) {
   iframe = document.createElement('iframe');
   iframe.setAttribute('mozbrowser', 'true');
 
   iframe.src = 'data:text/html,<html>' +
     '<body>' +
-    '<menu type="context" id="menu1" label="firstmenu">' +
-      '<menuitem label="foo" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
-      '<menuitem label="bar" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
-    '</menu>' +
-    '<menu type="context" id="menu2" label="secondmenu">' +
-      '<menuitem label="outer" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
-      '<menu label="submenu">' +
-        '<menuitem label="inner 1"></menuitem>' +
-        '<menuitem label="inner 2" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
-      '</menu>' +
-    '</menu>' +
-    '<div id="menu1-trigger" contextmenu="menu1"><a id="inner-link" href="foo.html">Menu 1</a></div>' +
-    '<a href="bar.html" contextmenu="menu2"><img id="menu2-trigger" src="example.png" /></a>' +
     '<img id="menu3-trigger" src="example.png" />' +
     '<video id="menu4-trigger" src="' + videoUrl + '"></video>' +
     '<video id="menu5-trigger" preload="metadata"></video>' +
     '<audio id="menu6-trigger" src="' + audioUrl + '"></audio>' +
     '<form action="no_method"><input id="menu7-trigger" name="input1"></input></form>' +
     '<form action="http://example.com/get_method" method="get"><input id="menu8-trigger" name="input2"></input></form>' +
     '<form action="post_method" method="post"><input id="menu9-trigger" name="input3"></input></form>' +
     '</body></html>';
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1663,31 +1663,16 @@ nsGenericHTMLElement::GetURIAttr(nsIAtom
   // Don't care about return value.  If it fails, we still want to
   // return true, and *aURI will be null.
   nsContentUtils::NewURIWithDocumentCharset(aURI,
                                             attr->GetStringValue(),
                                             OwnerDoc(), baseURI);
   return true;
 }
 
-HTMLMenuElement*
-nsGenericHTMLElement::GetContextMenu() const
-{
-  nsAutoString value;
-  GetHTMLAttr(nsGkAtoms::contextmenu, value);
-  if (!value.IsEmpty()) {
-    //XXXsmaug How should this work in Shadow DOM?
-    nsIDocument* doc = GetUncomposedDoc();
-    if (doc) {
-      return HTMLMenuElement::FromContentOrNull(doc->GetElementById(value));
-    }
-  }
-  return nullptr;
-}
-
 bool
 nsGenericHTMLElement::IsLabelable() const
 {
   return IsAnyOfHTMLElements(nsGkAtoms::progress, nsGkAtoms::meter);
 }
 
 /* static */ bool
 nsGenericHTMLElement::MatchLabelsElement(Element* aElement, int32_t aNamespaceID,
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -164,17 +164,16 @@ public:
   }
 
   /**
    * Returns the count of descendants (inclusive of this node) in
    * the uncomposed document that are explicitly set as editable.
    */
   uint32_t EditableInclusiveDescendantCount();
 
-  mozilla::dom::HTMLMenuElement* GetContextMenu() const;
   bool Spellcheck();
   void SetSpellcheck(bool aSpellcheck, mozilla::ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::spellcheck,
                 aSpellcheck ? NS_LITERAL_STRING("true")
                             : NS_LITERAL_STRING("false"),
                 aError);
   }
--- a/dom/html/test/browser.ini
+++ b/dom/html/test/browser.ini
@@ -1,29 +1,27 @@
 [DEFAULT]
 support-files =
   bug592641_img.jpg
   dummy_page.html
   file_bug649778.html
   file_bug649778.html^headers^
   file_fullscreen-api-keys.html
-  file_content_contextmenu.html
   form_data_file.bin
   form_data_file.txt
   form_submit_server.sjs
   head.js
 
 [browser_bug592641.js]
 [browser_bug649778.js]
 skip-if = e10s # Bug 1271025
 [browser_bug1081537.js]
 [browser_bug1108547.js]
 support-files =
   file_bug1108547-1.html
   file_bug1108547-2.html
   file_bug1108547-3.html
-[browser_content_contextmenu_userinput.js]
 [browser_DOMDocElementInserted.js]
 [browser_form_post_from_file_to_http.js]
 [browser_fullscreen-api-keys.js]
 tags = fullscreen
 [browser_fullscreen-contextmenu-esc.js]
 tags = fullscreen
deleted file mode 100644
--- a/dom/html/test/browser_content_contextmenu_userinput.js
+++ /dev/null
@@ -1,50 +0,0 @@
-"use strict";
-
-const kPage = "http://example.org/browser/" +
-              "dom/html/test/file_content_contextmenu.html";
-
-add_task(async function() {
-  await BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: kPage
-  }, async function(aBrowser) {
-    let contextMenu = document.getElementById("contentAreaContextMenu");
-    ok(contextMenu, "Got context menu");
-
-    info("Open context menu");
-    is(contextMenu.state, "closed", "Should not have opened context menu");
-    let popupShownPromise = promiseWaitForEvent(window, "popupshown");
-    EventUtils.synthesizeMouse(aBrowser, window.innerWidth / 3,
-                               window.innerHeight / 3,
-                               {type: "contextmenu", button: 2}, window);
-    await popupShownPromise;
-    is(contextMenu.state, "open", "Should have opened context menu");
-
-    let pageMenuSep = document.getElementById("page-menu-separator");
-    ok(pageMenuSep && !pageMenuSep.hidden,
-       "Page menu separator should be shown");
-
-    let testMenuSep = pageMenuSep.previousSibling;
-    ok(testMenuSep && !testMenuSep.hidden,
-       "User-added menu separator should be shown");
-
-    let testMenuItem = testMenuSep.previousSibling;
-    is(testMenuItem.label, "Test Context Menu Click", "Got context menu item");
-
-    let promiseCtxMenuClick = ContentTask.spawn(aBrowser, null, async function() {
-      await new Promise(resolve => {
-        let Ci = Components.interfaces;
-        let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor)
-                                 .getInterface(Ci.nsIDOMWindowUtils);
-        let menuitem = content.document.getElementById("menuitem");
-        menuitem.addEventListener("click", function() {
-          Assert.ok(windowUtils.isHandlingUserInput,
-                    "Content menu click should be a user input");
-          resolve();
-        });
-      });
-    });
-    EventUtils.synthesizeMouseAtCenter(testMenuItem, {}, window);
-    await promiseCtxMenuClick;
-  });
-});
deleted file mode 100644
--- a/dom/html/test/file_content_contextmenu.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <meta charset="UTF-8">
-  <title></title>
-  <style>
-    body {
-      margin: 0;
-      width: 100vw;
-      height: 100vh;
-    }
-  </style>
-</head>
-<body contextmenu="testmenu">
-  <menu type="context" id="testmenu">
-    <menuitem label="Test Context Menu Click" id="menuitem"></menuitem>
-    <hr>
-  </menu>
-</body>
-</html>
--- a/dom/webidl/HTMLElement.webidl
+++ b/dom/webidl/HTMLElement.webidl
@@ -45,20 +45,16 @@ interface HTMLElement : Element {
   readonly attribute DOMString accessKeyLabel;
   [CEReactions, SetterThrows, Pure]
            attribute boolean draggable;
   //[PutForwards=value] readonly attribute DOMTokenList dropzone;
   [SetterThrows, Pure]
            attribute DOMString contentEditable;
   [Pure]
   readonly attribute boolean isContentEditable;
-  [Pure]
-  readonly attribute HTMLMenuElement? contextMenu;
-  //[SetterThrows]
-  //         attribute HTMLMenuElement? contextMenu;
   [CEReactions, SetterThrows, Pure]
            attribute boolean spellcheck;
 
   // command API
   //readonly attribute DOMString? commandType;
   //readonly attribute DOMString? commandLabel;
   //readonly attribute DOMString? commandIcon;
   //readonly attribute boolean? commandHidden;
--- a/testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json
+++ b/testing/runtimes/mochitest-browser-chrome-e10s.runtimes.json
@@ -58,19 +58,18 @@
     "browser/base/content/test/general/browser_bug822367.js": 9554, 
     "browser/base/content/test/general/browser_bug902156.js": 5042, 
     "browser/base/content/test/general/browser_bug906190.js": 28243, 
     "browser/base/content/test/general/browser_bug963945.js": 3613, 
     "browser/base/content/test/general/browser_close_dependent_tabs.js": 2877, 
     "browser/base/content/test/general/browser_contentAltClick.js": 3557, 
     "browser/base/content/test/general/browser_contentSearchUI.js": 20488, 
     "browser/base/content/test/general/browser_contextmenu.js": 4785, 
-    "browser/base/content/test/general/browser_contextmenu_childprocess.js": 5501, 
     "browser/base/content/test/general/browser_ctrlTab.js": 5609, 
-    "browser/base/content/test/general/browser_datachoices_notification.js": 6696, 
+    "browser/base/content/test/general/browser_datachoices_notification.js": 6696,
     "browser/base/content/test/general/browser_decoderDoctor.js": 4428, 
     "browser/base/content/test/general/browser_devices_get_user_media.js": 14991, 
     "browser/base/content/test/general/browser_devices_get_user_media_in_frame.js": 4616, 
     "browser/base/content/test/general/browser_documentnavigation.js": 6759, 
     "browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js": 5545, 
     "browser/base/content/test/general/browser_e10s_chrome_process.js": 8580, 
     "browser/base/content/test/general/browser_e10s_switchbrowser.js": 12757, 
     "browser/base/content/test/general/browser_fullscreen-window-open.js": 4312, 
--- a/testing/runtimes/mochitest-browser-chrome.runtimes.json
+++ b/testing/runtimes/mochitest-browser-chrome.runtimes.json
@@ -63,19 +63,18 @@
     "browser/base/content/test/general/browser_bug882977.js": 2116, 
     "browser/base/content/test/general/browser_bug902156.js": 4323, 
     "browser/base/content/test/general/browser_bug906190.js": 23834, 
     "browser/base/content/test/general/browser_bug963945.js": 3860, 
     "browser/base/content/test/general/browser_contentAltClick.js": 3194, 
     "browser/base/content/test/general/browser_contentAreaClick.js": 2520, 
     "browser/base/content/test/general/browser_contentSearchUI.js": 16302, 
     "browser/base/content/test/general/browser_contextmenu.js": 6404, 
-    "browser/base/content/test/general/browser_contextmenu_childprocess.js": 4201, 
     "browser/base/content/test/general/browser_ctrlTab.js": 4962, 
-    "browser/base/content/test/general/browser_datachoices_notification.js": 3564, 
+    "browser/base/content/test/general/browser_datachoices_notification.js": 3564,
     "browser/base/content/test/general/browser_datareporting_notification.js": 4123, 
     "browser/base/content/test/general/browser_decoderDoctor.js": 1926, 
     "browser/base/content/test/general/browser_devices_get_user_media.js": 20295, 
     "browser/base/content/test/general/browser_devices_get_user_media_in_frame.js": 6180, 
     "browser/base/content/test/general/browser_documentnavigation.js": 5228, 
     "browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js": 4787, 
     "browser/base/content/test/general/browser_e10s_chrome_process.js": 4526, 
     "browser/base/content/test/general/browser_e10s_switchbrowser.js": 5444, 
--- a/testing/web-platform/meta/html/semantics/interactive-elements/contextmenu-historical.html.ini
+++ b/testing/web-platform/meta/html/semantics/interactive-elements/contextmenu-historical.html.ini
@@ -2,17 +2,17 @@
   type: testharness
   [HTMLMenuItemElement must not be not present]
     expected: FAIL
 
   [onshow must not be present on the GlobalEventHandlers locations]
     expected: FAIL
 
   [el.contextMenu must not be present]
-    expected: FAIL
+    expected: PASS
 
   [menu.type must not exist or reflect the content attribute]
     expected: FAIL
 
   [menu.label must not exist or reflect the content attribute]
     expected: FAIL
 
   [The user-agent stylesheet must leave type="context" menus as block display like other menus]