Bug 1399068 - Send the context menu target node up to the parent as an explicit CPOW to fix login selection. r=Felipe, a=ritu
authorMike Conley <mconley@mozilla.com>
Wed, 04 Oct 2017 14:29:09 -0400
changeset 432290 d40416856dd2cf8b87a2191c81a5c70cba0fc301
parent 432289 d6473a55aa1e8b3910321f5793043b4570f308f9
child 432291 fce8e9263a0116456ba6f0b9a7b66b4b7ff8801d
push id7927
push userryanvm@gmail.com
push dateMon, 09 Oct 2017 18:10:37 +0000
treeherdermozilla-beta@b9e89e842081 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersFelipe, ritu
bugs1399068, 1360406
milestone57.0
Bug 1399068 - Send the context menu target node up to the parent as an explicit CPOW to fix login selection. r=Felipe, a=ritu LoginManagerParent expects either a CPOW or a DOM node (in the non-e10s case) to be passed as the inputElement for LoginManagerParent.fillForm. In bug 1360406, we serialized the target in the content process so that the parent didn't have access to the CPOW anymore. This patch adds a targetAsCPOW property to the nsContextMenu solely for passing back and forth between the parent and content processes in order to refer to the target DOM node. MozReview-Commit-ID: IMwVK0Ewlhy
browser/base/content/nsContextMenu.js
browser/modules/ContextMenu.jsm
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -24,16 +24,23 @@ function setContextMenuContentData(data)
   gContextMenuContentData = data;
 }
 
 function openContextMenu(aMessage) {
   let data = aMessage.data;
   let browser = aMessage.target;
   let spellInfo = data.spellInfo;
 
+  // ContextMenu.jsm sends us the target as a CPOW only so that
+  // we can send that CPOW back down to the content process and
+  // have it resolve to a DOM node. The parent should not attempt
+  // to access any properties on this CPOW (in fact, doing so
+  // will throw an exception).
+  data.context.targetAsCPOW = aMessage.objects.targetAsCPOW;
+
   if (spellInfo) {
     spellInfo.target = aMessage.target.messageManager;
   }
 
   let documentURIObject = makeURI(data.docLocation,
                                   data.charSet,
                                   makeURI(data.baseURI));
   gContextMenuContentData = { context: data.context,
@@ -199,16 +206,17 @@ nsContextMenu.prototype = {
     this.onMozExtLink        = context.onMozExtLink;
     this.onNumeric           = context.onNumeric;
     this.onPassword          = context.onPassword;
     this.onSaveableLink      = context.onSaveableLink;
     this.onTextInput         = context.onTextInput;
     this.onVideo             = context.onVideo;
 
     this.target = this.isRemote ? context.target : document.popupNode;
+    this.targetAsCPOW = context.targetAsCPOW;
 
     this.principal = context.principal;
     this.frameOuterWindowID = context.frameOuterWindowID;
 
     this.inSyntheticDoc = context.inSyntheticDoc;
 
     // Everything after this isn't sent directly from ContextMenu
     this.ownerDoc = this.target.ownerDocument;
@@ -712,17 +720,17 @@ nsContextMenu.prototype = {
       fillMenu.setAttribute("label", fillMenu.getAttribute("label-login"));
       fillMenu.setAttribute("accesskey", fillMenu.getAttribute("accesskey-login"));
     }
 
     if (!showFill || disableFill) {
       return;
     }
     let documentURI = gContextMenuContentData.documentURIObject;
-    let fragment = LoginManagerContextMenu.addLoginsToMenu(this.target, this.browser, documentURI);
+    let fragment = LoginManagerContextMenu.addLoginsToMenu(this.targetAsCPOW, this.browser, documentURI);
 
     this.showItem("fill-login-no-logins", !fragment);
 
     if (!fragment) {
       return;
     }
     let popup = document.getElementById("fill-login-popup");
     let insertBeforeElement = document.getElementById("fill-login-no-logins");
--- a/browser/modules/ContextMenu.jsm
+++ b/browser/modules/ContextMenu.jsm
@@ -567,17 +567,18 @@ class ContextMenu {
     let context = this.context;
     this.target = context.target;
 
     let spellInfo = null;
     let editFlags = null;
     let principal = null;
     let customMenuItems = null;
 
-    if (context.target) {
+    let targetAsCPOW = context.target;
+    if (targetAsCPOW) {
       this._cleanContext();
     }
 
     let isRemote = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
 
     if (isRemote) {
       editFlags = SpellCheckHelper.isEditable(aEvent.target, this.content);
 
@@ -616,25 +617,29 @@ class ContextMenu {
       contentDisposition,
       frameOuterWindowID,
       popupNodeSelectors,
       disableSetDesktopBg,
       parentAllowsMixedContent,
     };
 
     if (isRemote) {
-      this.global.sendAsyncMessage("contextmenu", data);
+      this.global.sendAsyncMessage("contextmenu", data, {
+        targetAsCPOW,
+      });
     } else {
       let browser = this.global.docShell.chromeEventHandler;
       let mainWin = browser.ownerGlobal;
 
       data.documentURIObject = doc.documentURIObject;
       data.disableSetDesktopBackground = data.disableSetDesktopBg;
       delete data.disableSetDesktopBg;
 
+      data.context.targetAsCPOW = targetAsCPOW;
+
       mainWin.setContextMenuContentData(data);
     }
   }
 
   /**
    * Some things are not serializable, so we either have to only send
    * their needed data or regenerate them in nsContextMenu.js
    * - target and target.ownerDocument