Bug 1309735 - Allow usercontextid to be set on mozbrowser frames. r=baku draft
authorJ. Ryan Stinnett <jryans@gmail.com>
Fri, 23 Feb 2018 17:32:18 -0600
changeset 804831 798bf46c5356fd1a99f83c7174295d309887b5d3
parent 804157 752465b44c793318cef36df46ca5ff00c3d8854a
child 805017 7f1e43998257ce1b85c45f8d23d66ef3048c901b
push id112476
push userbmo:jryans@gmail.com
push dateWed, 06 Jun 2018 16:51:54 +0000
reviewersbaku
bugs1309735
milestone62.0a1
Bug 1309735 - Allow usercontextid to be set on mozbrowser frames. r=baku This allows the `usercontextid` attribute to be set on mozbrowser frames. This will help Responsive Design Mode support display of pages in containers, since it uses such frames internally. MozReview-Commit-ID: HWEJni6z1sp
dom/base/nsFrameLoader.cpp
dom/base/test/chrome/window_swapFrameLoaders.xul
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -1073,17 +1073,17 @@ nsFrameLoader::SwapWithOtherRemoteLoader
 
   if (mRemoteBrowser->IsIsolatedMozBrowserElement() !=
       aOther->mRemoteBrowser->IsIsolatedMozBrowserElement()) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   // When we swap docShells, maybe we have to deal with a new page created just
   // for this operation. In this case, the browser code should already have set
-  // the correct userContextId attribute value in the owning XULElement, but our
+  // the correct userContextId attribute value in the owning element, but our
   // docShell, that has been created way before) doesn't know that that
   // happened.
   // This is the reason why now we must retrieve the correct value from the
   // usercontextid attribute before comparing our originAttributes with the
   // other one.
   OriginAttributes ourOriginAttributes =
     mRemoteBrowser->OriginAttributesRef();
   rv = PopulateUserContextIdFromAttribute(ourOriginAttributes);
@@ -1496,17 +1496,17 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
 
   if (ourDocshell->GetIsIsolatedMozBrowserElement() !=
       otherDocshell->GetIsIsolatedMozBrowserElement()) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   // When we swap docShells, maybe we have to deal with a new page created just
   // for this operation. In this case, the browser code should already have set
-  // the correct userContextId attribute value in the owning XULElement, but our
+  // the correct userContextId attribute value in the owning element, but our
   // docShell, that has been created way before) doesn't know that that
   // happened.
   // This is the reason why now we must retrieve the correct value from the
   // usercontextid attribute before comparing our originAttributes with the
   // other one.
   OriginAttributes ourOriginAttributes =
     ourDocshell->GetOriginAttributes();
   rv = PopulateUserContextIdFromAttribute(ourOriginAttributes);
@@ -2178,17 +2178,17 @@ nsFrameLoader::MaybeCreateDocShell()
   // because we need to get the correct presentation URL in ApplySandboxFlags.
   uint32_t sandboxFlags = 0;
   HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
   if (iframe) {
     sandboxFlags = iframe->GetSandboxFlags();
   }
   ApplySandboxFlags(sandboxFlags);
 
-  // Grab the userContextId from owner if XUL
+  // Grab the userContextId from owner
   nsresult rv = PopulateUserContextIdFromAttribute(attrs);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   bool isPrivate = false;
   nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(parentDocShell);
   NS_ENSURE_STATE(parentContext);
@@ -3367,20 +3367,20 @@ nsFrameLoader::GetNewTabContext(MutableT
   return NS_OK;
 }
 
 nsresult
 nsFrameLoader::PopulateUserContextIdFromAttribute(OriginAttributes& aAttr)
 {
   if (aAttr.mUserContextId ==
         nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID)  {
-    // Grab the userContextId from owner if XUL
+    // Grab the userContextId from owner if XUL or mozbrowser frame
     nsAutoString userContextIdStr;
     int32_t namespaceID = mOwnerContent->GetNameSpaceID();
-    if ((namespaceID == kNameSpaceID_XUL) &&
+    if ((namespaceID == kNameSpaceID_XUL || OwnerIsMozBrowserFrame()) &&
         mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usercontextid,
                                userContextIdStr) &&
         !userContextIdStr.IsEmpty()) {
       nsresult rv;
       aAttr.mUserContextId = userContextIdStr.ToInteger(&rv);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
--- a/dom/base/test/chrome/window_swapFrameLoaders.xul
+++ b/dom/base/test/chrome/window_swapFrameLoaders.xul
@@ -24,20 +24,22 @@ Test swapFrameLoaders with different fra
     html: "iframe", // mozbrowser
   }
 
   const SCENARIOS = [
     ["xul", "xul"],
     ["xul", "html"],
     ["html", "xul"],
     ["html", "html"],
-    ["xul", "xul", "remote"],
-    ["xul", "html", "remote"],
-    ["html", "xul", "remote"],
-    ["html", "html", "remote"],
+    ["xul", "xul", { remote: true }],
+    ["xul", "html", { remote: true }],
+    ["html", "xul", { remote: true }],
+    ["html", "html", { remote: true }],
+    ["xul", "html", { userContextId: 2 }],
+    ["xul", "html", { userContextId: 2, remote: true }],
   ];
 
   const HEIGHTS = [
     200,
     400
   ];
 
   function frameScript() {
@@ -64,22 +66,27 @@ Test swapFrameLoaders with different fra
             resolve(aArgs);
           }, useCapture);
           break;
         }
       }
     });
   }
 
-  async function addFrame(type, remote, height) {
+  async function addFrame(type, options, height) {
+    let remote = options && options.remote;
+    let userContextId = options && options.userContextId;
     let frame = document.createElementNS(NS[type], TAG[type]);
     frame.setAttribute("remote", remote);
     if (remote && type == "xul") {
       frame.setAttribute("style", "-moz-binding: none;");
     }
+    if (userContextId) {
+      frame.setAttribute("usercontextid", userContextId);
+    }
     if (type == "html") {
       frame.setAttribute("mozbrowser", "true");
       frame.setAttribute("noisolation", "true");
       frame.setAttribute("allowfullscreen", "true");
     } else if (type == "xul") {
       frame.setAttribute("type", "content");
     }
     let src = `data:text/html,<!doctype html>` +
@@ -94,25 +101,24 @@ Test swapFrameLoaders with different fra
   add_task(async function() {
     await SpecialPowers.pushPrefEnv(
       { "set": [["dom.mozBrowserFramesEnabled", true],
                 ["network.disable.ipc.security", true]] });
   });
 
   add_task(async function() {
     for (let scenario of SCENARIOS) {
-      let [ typeA, typeB, remote ] = scenario;
-      remote = !!remote;
+      let [ typeA, typeB, options ] = scenario;
       let heightA = HEIGHTS[0];
-      info(`Adding frame A, type ${typeA}, remote ${remote}, height ${heightA}`);
-      let frameA = await addFrame(typeA, remote, heightA);
+      info(`Adding frame A, type ${typeA}, options ${JSON.stringify(options)}, height ${heightA}`);
+      let frameA = await addFrame(typeA, options, heightA);
 
       let heightB = HEIGHTS[1];
-      info(`Adding frame B, type ${typeB}, remote ${remote}, height ${heightB}`);
-      let frameB = await addFrame(typeB, remote, heightB);
+      info(`Adding frame B, type ${typeB}, options ${JSON.stringify(options)}, height ${heightB}`);
+      let frameB = await addFrame(typeB, options, heightB);
 
       let frameScriptFactory = function(name) {
         return `function() {
           addMessageListener("ping", function() {
             sendAsyncMessage("pong", "${name}");
           });
           addMessageListener("check-browser-api", function() {
             let exists = "api" in this;