Bug 1238160 - Set tab context's isolation from frame attr. r=smaug draft
authorJ. Ryan Stinnett <jryans@gmail.com>
Wed, 17 Feb 2016 21:31:29 -0600
changeset 331749 e442d24503f0ffdcdbb3647b526e93909678a626
parent 331748 cfb7b1ebdfcddba04dbf9f911ddaeecfb46b4916
child 331750 90957ccc6bf25320562db99970da574e1127a363
push id11069
push userbmo:jryans@gmail.com
push dateThu, 18 Feb 2016 06:17:44 +0000
reviewerssmaug
bugs1238160
milestone47.0a1
Bug 1238160 - Set tab context's isolation from frame attr. r=smaug Renames existing nsFrameLoader::OwnerIsBrowser* methods to add "Moz" prefix for clarity. Adds nsFrameLoader::OwnerIsIsolatedMozBrowserFrame which checks the noisolation attribute of mozbrowser frames, if present. This is used to set isolation in nsFrameLoader::GetNewTabContext only when true. MozReview-Commit-ID: Dz02xBoKh1P
accessible/jsat/AccessFu.jsm
b2g/chrome/content/runapp.js
b2g/components/ErrorPage.jsm
dom/base/nsFrameLoader.cpp
dom/base/nsFrameLoader.h
dom/base/nsGkAtomList.h
dom/base/nsIFrameLoader.idl
dom/html/nsBrowserElement.cpp
dom/html/nsGenericHTMLFrameElement.cpp
dom/inputmethod/Keyboard.jsm
dom/interfaces/html/nsIMozBrowserFrame.idl
dom/ipc/ProcessPriorityManager.cpp
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -339,17 +339,17 @@ this.AccessFu = { // jshint ignore:line
       case 'Accessibility:MoveByGranularity':
         this.Input.moveByGranularity(JSON.parse(aData));
         break;
       case 'remote-browser-shown':
       case 'inprocess-browser-shown':
       {
         // Ignore notifications that aren't from a BrowserOrApp
         let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
-        if (!frameLoader.ownerIsBrowserOrAppFrame) {
+        if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
           return;
         }
         this._handleMessageManager(frameLoader.messageManager);
         break;
       }
     }
   },
 
--- a/b2g/chrome/content/runapp.js
+++ b/b2g/chrome/content/runapp.js
@@ -52,17 +52,17 @@ function AppRunner(aName) {
   this._apps = [];
 }
 AppRunner.prototype = {
   observe: function(aSubject, aTopic, aData) {
     let frameLoader = aSubject;
     // get a ref to the app <iframe>
     frameLoader.QueryInterface(Ci.nsIFrameLoader);
     // Ignore notifications that aren't from a BrowserOrApp
-    if (!frameLoader.ownerIsBrowserOrAppFrame) {
+    if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
       return;
     }
 
     let frame = frameLoader.ownerElement;
     if (!frame.appManifestURL) { // Ignore all frames but app frames
       return;
     }
 
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -172,16 +172,16 @@ var ErrorPage = {
   init: function errorPageInit() {
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
     Services.obs.addObserver(this, 'remote-browser-shown', false);
   },
 
   observe: function errorPageObserve(aSubject, aTopic, aData) {
     let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
     // Ignore notifications that aren't from a BrowserOrApp
-    if (!frameLoader.ownerIsBrowserOrAppFrame) {
+    if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
       return;
     }
     this._listenError(frameLoader);
   }
 };
 
 ErrorPage.init();
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -417,17 +417,17 @@ nsFrameLoader::ReallyStartLoadingInterna
     }
   }
   loadInfo->SetReferrerPolicy(referrerPolicy);
 
   // Default flags:
   int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
 
   // Flags for browser frame:
-  if (OwnerIsBrowserFrame()) {
+  if (OwnerIsMozBrowserFrame()) {
     flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
             nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
   }
 
   // Kick off the load...
   bool tmpState = mNeedsAsyncDestroy;
   mNeedsAsyncDestroy = true;
   nsCOMPtr<nsIURI> uriToLoad = mURIToLoad;
@@ -1569,27 +1569,27 @@ nsFrameLoader::SetOwnerContent(Element* 
   if (RenderFrameParent* rfp = GetCurrentRenderFrame()) {
     rfp->OwnerContentChanged(aContent);
   }
 
   ResetPermissionManagerStatus();
 }
 
 bool
-nsFrameLoader::OwnerIsBrowserOrAppFrame()
+nsFrameLoader::OwnerIsMozBrowserOrAppFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsBrowserOrApp() : false;
 }
 
 // The xpcom getter version
 NS_IMETHODIMP
-nsFrameLoader::GetOwnerIsBrowserOrAppFrame(bool* aResult)
+nsFrameLoader::GetOwnerIsMozBrowserOrAppFrame(bool* aResult)
 {
-  *aResult = OwnerIsBrowserOrAppFrame();
+  *aResult = OwnerIsMozBrowserOrAppFrame();
   return NS_OK;
 }
 
 bool
 nsFrameLoader::OwnerIsWidget()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsWidget() : false;
@@ -1607,19 +1607,29 @@ nsFrameLoader::GetOwnerIsWidget(bool* aR
 bool
 nsFrameLoader::OwnerIsAppFrame()
 {
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   return browserFrame ? browserFrame->GetReallyIsApp() : false;
 }
 
 bool
-nsFrameLoader::OwnerIsBrowserFrame()
+nsFrameLoader::OwnerIsMozBrowserFrame()
 {
-  return OwnerIsBrowserOrAppFrame() && !OwnerIsAppFrame();
+  return OwnerIsMozBrowserOrAppFrame() && !OwnerIsAppFrame();
+}
+
+bool
+nsFrameLoader::OwnerIsIsolatedMozBrowserFrame()
+{
+  nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
+  if (!browserFrame) {
+    return false;
+  }
+  return OwnerIsMozBrowserFrame() && browserFrame->GetIsolated();
 }
 
 void
 nsFrameLoader::GetOwnerAppManifestURL(nsAString& aOut)
 {
   aOut.Truncate();
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
   if (browserFrame) {
@@ -1684,25 +1694,25 @@ nsFrameLoader::ShouldUseRemoteProcess()
   if (XRE_IsContentProcess() &&
       !(PR_GetEnv("MOZ_NESTED_OOP_TABS") ||
         Preferences::GetBool("dom.ipc.tabs.nested.enabled", false))) {
     return false;
   }
 
   // If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
   // fall back to the default.
-  if (OwnerIsBrowserOrAppFrame() &&
+  if (OwnerIsMozBrowserOrAppFrame() &&
       !mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::Remote)) {
 
     return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
   }
 
   // Otherwise, we're remote if we have "remote=true" and we're either a
   // browser frame or a XUL element.
-  return (OwnerIsBrowserOrAppFrame() ||
+  return (OwnerIsMozBrowserOrAppFrame() ||
           mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
          mOwnerContent->AttrValueIs(kNameSpaceID_None,
                                     nsGkAtoms::Remote,
                                     nsGkAtoms::_true,
                                     eCaseMatters);
 }
 
 bool
@@ -1875,42 +1885,42 @@ nsFrameLoader::MaybeCreateDocShell()
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell));
     webNav->SetSessionHistory(sessionHistory);
   }
 
   if (OwnerIsAppFrame()) {
     // You can't be both an app and a browser frame.
-    MOZ_ASSERT(!OwnerIsBrowserFrame());
+    MOZ_ASSERT(!OwnerIsMozBrowserFrame());
 
     nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
     MOZ_ASSERT(ownApp);
     uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (ownApp) {
       NS_ENSURE_SUCCESS(ownApp->GetLocalId(&ownAppId), NS_ERROR_FAILURE);
     }
 
     mDocShell->SetIsApp(ownAppId);
   }
 
-  if (OwnerIsBrowserFrame()) {
+  if (OwnerIsMozBrowserFrame()) {
     // You can't be both a browser and an app frame.
     MOZ_ASSERT(!OwnerIsAppFrame());
 
     nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
     uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (containingApp) {
       NS_ENSURE_SUCCESS(containingApp->GetLocalId(&containingAppId),
                         NS_ERROR_FAILURE);
     }
     mDocShell->SetIsBrowserInsideApp(containingAppId);
   }
 
-  if (OwnerIsBrowserOrAppFrame()) {
+  if (OwnerIsMozBrowserOrAppFrame()) {
     // For inproc frames, set the docshell properties.
     nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
     nsAutoString name;
     if (mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
       item->SetName(name);
     }
     mDocShell->SetFullscreenAllowed(
       mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
@@ -2241,17 +2251,17 @@ nsFrameLoader::TryRemoteBrowser()
 
   if (openingTab &&
       openingTab->Manager() &&
       openingTab->Manager()->IsContentParent()) {
     openerContentParent = openingTab->Manager()->AsContentParent();
   }
 
   // <iframe mozbrowser> gets to skip these checks.
-  if (!OwnerIsBrowserOrAppFrame()) {
+  if (!OwnerIsMozBrowserOrAppFrame()) {
     if (parentDocShell->ItemType() != nsIDocShellTreeItem::typeChrome) {
       return false;
     }
 
     if (!mOwnerContent->IsXULElement()) {
       return false;
     }
 
@@ -2556,17 +2566,17 @@ nsFrameLoader::EnsureMessageManager()
 {
   NS_ENSURE_STATE(mOwnerContent);
 
   if (mMessageManager) {
     return NS_OK;
   }
 
   if (!mIsTopLevelContent &&
-      !OwnerIsBrowserOrAppFrame() &&
+      !OwnerIsMozBrowserOrAppFrame() &&
       !IsRemoteFrame() &&
       !(mOwnerContent->IsXULElement() &&
         mOwnerContent->AttrValueIs(kNameSpaceID_None,
                                    nsGkAtoms::forcemessagemanager,
                                    nsGkAtoms::_true, eCaseMatters))) {
     return NS_OK;
   }
 
@@ -2662,17 +2672,17 @@ nsFrameLoader::SwapRemoteBrowser(nsITabP
   RefPtr<TabParent> newParent = TabParent::GetFrom(aTabParent);
   if (!newParent || !mRemoteBrowser) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
   if (!IsRemoteFrame()) {
     NS_WARNING("Switching from in-process to out-of-process is not supported.");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
-  if (!OwnerIsBrowserOrAppFrame()) {
+  if (!OwnerIsMozBrowserOrAppFrame()) {
     NS_WARNING("Switching process for non-mozbrowser/app frame is not supported.");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
   if (newParent == mRemoteBrowser) {
     return NS_OK;
   }
 
   MaybeUpdatePrimaryTabParent(eTabParentRemoved);
@@ -2813,27 +2823,27 @@ nsFrameLoader::ResetPermissionManagerSta
 
   // Finding the new app Id:
   // . first we check if the owner is an app frame
   // . second, we check if the owner is a browser frame
   // in both cases we populate the appId variable.
   uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
   if (OwnerIsAppFrame()) {
     // You can't be both an app and a browser frame.
-    MOZ_ASSERT(!OwnerIsBrowserFrame());
+    MOZ_ASSERT(!OwnerIsMozBrowserFrame());
 
     nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
     MOZ_ASSERT(ownApp);
     uint32_t ownAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (ownApp && NS_SUCCEEDED(ownApp->GetLocalId(&ownAppId))) {
       appId = ownAppId;
     }
   }
 
-  if (OwnerIsBrowserFrame()) {
+  if (OwnerIsMozBrowserFrame()) {
     // You can't be both a browser and an app frame.
     MOZ_ASSERT(!OwnerIsAppFrame());
 
     nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
     uint32_t containingAppId = nsIScriptSecurityManager::NO_APP_ID;
     if (containingApp && NS_SUCCEEDED(containingApp->GetLocalId(&containingAppId))) {
       appId = containingAppId;
     }
@@ -2961,17 +2971,17 @@ nsFrameLoader::GetLoadContext(nsILoadCon
   }
   loadContext.forget(aLoadContext);
   return NS_OK;
 }
 
 void
 nsFrameLoader::InitializeBrowserAPI()
 {
-  if (OwnerIsBrowserOrAppFrame()) {
+  if (OwnerIsMozBrowserOrAppFrame()) {
     if (!IsRemoteFrame()) {
       nsresult rv = EnsureMessageManager();
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return;
       }
       if (mMessageManager) {
         mMessageManager->LoadFrameScript(
           NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"),
@@ -3056,17 +3066,17 @@ nsFrameLoader::MaybeUpdatePrimaryTabPare
 nsresult
 nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
                                 nsIURI* aURI,
                                 const nsACString& aPackageId)
 {
   nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
   nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
   DocShellOriginAttributes attrs;
-  attrs.mInIsolatedMozBrowser = OwnerIsBrowserFrame();
+  attrs.mInIsolatedMozBrowser = OwnerIsIsolatedMozBrowserFrame();
 
   nsCString signedPkgOrigin;
   if (!aPackageId.IsEmpty()) {
     // Only when aPackageId is not empty would signed package origin
     // be meaningful.
     nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
   }
 
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -138,17 +138,17 @@ public:
    * Return the primary frame for our owning content, or null if it
    * can't be found.
    */
   nsIFrame* GetPrimaryFrameOfOwningContent() const
   {
     return mOwnerContent ? mOwnerContent->GetPrimaryFrame() : nullptr;
   }
 
-  /** 
+  /**
    * Return the document that owns this, or null if we don't have
    * an owner.
    */
   nsIDocument* GetOwnerDoc() const
   { return mOwnerContent ? mOwnerContent->OwnerDoc() : nullptr; }
 
   PBrowserParent* GetRemoteBrowser() const;
 
@@ -189,17 +189,17 @@ public:
 
   /**
    * Stashes a detached view on the frame loader. We do this when we're
    * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
    * being reframed we'll restore the detached view when it's recreated,
    * otherwise we'll discard the old presentation and set the detached
    * subdoc view to null. aContainerDoc is the document containing the
    * the subdoc frame. This enables us to detect when the containing
-   * document has changed during reframe, so we can discard the presentation 
+   * document has changed during reframe, so we can discard the presentation
    * in that case.
    */
   void SetDetachedSubdocView(nsView* aDetachedView,
                              nsIDocument* aContainerDoc);
 
   /**
    * Retrieves the detached view and the document containing the view,
    * as set by SetDetachedSubdocView().
@@ -237,35 +237,46 @@ private:
    * Return true if the frame is a remote frame. Return false otherwise
    */
   bool IsRemoteFrame();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozbrowser> or
    * <iframe mozapp>?  (I.e., does the frame return true for
    * nsIMozBrowserFrame::GetReallyIsBrowserOrApp()?)
+   * <xul:browser> is not a mozbrowser or app, so this is false for that case.
    */
-  bool OwnerIsBrowserOrAppFrame();
+  bool OwnerIsMozBrowserOrAppFrame();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozwidget>?  (I.e., does the
    * frame return true for nsIMozBrowserFrame::GetReallyIsWidget()?)
    */
   bool OwnerIsWidget();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozapp>?  (I.e., does the
    * frame return true for nsIMozBrowserFrame::GetReallyIsApp()?)
    */
   bool OwnerIsAppFrame();
 
   /**
    * Is this a frame loader for a bona fide <iframe mozbrowser>?
+   * <xul:browser> is not a mozbrowser, so this is false for that case.
    */
-  bool OwnerIsBrowserFrame();
+  bool OwnerIsMozBrowserFrame();
+
+  /**
+   * Is this a frame loader for an isolated <iframe mozbrowser>?
+   *
+   * By default, mozbrowser frames are isolated.  Isolation can be disabled by
+   * setting the frame's noisolation attribute.  Disabling isolation is
+   * only allowed if the containing document is chrome.
+   */
+  bool OwnerIsIsolatedMozBrowserFrame();
 
   /**
    * Get our owning element's app manifest URL, or return the empty string if
    * our owning element doesn't have an app manifest URL.
    */
   void GetOwnerAppManifestURL(nsAString& aOut);
 
   /**
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -650,16 +650,17 @@ GK_ATOM(noautohide, "noautohide")
 GK_ATOM(norolluponanchor, "norolluponanchor")
 GK_ATOM(nobr, "nobr")
 GK_ATOM(node, "node")
 GK_ATOM(nodefaultsrc, "nodefaultsrc")
 GK_ATOM(nodeSet, "node-set")
 GK_ATOM(noembed, "noembed")
 GK_ATOM(noframes, "noframes")
 GK_ATOM(nohref, "nohref")
+GK_ATOM(noisolation, "noisolation")
 GK_ATOM(nonce, "nonce")
 GK_ATOM(none, "none")
 GK_ATOM(noresize, "noresize")
 GK_ATOM(normal, "normal")
 GK_ATOM(normalizeSpace, "normalize-space")
 GK_ATOM(noscript, "noscript")
 GK_ATOM(noshade, "noshade")
 GK_ATOM(novalidate, "novalidate")
--- a/dom/base/nsIFrameLoader.idl
+++ b/dom/base/nsIFrameLoader.idl
@@ -145,17 +145,17 @@ interface nsIFrameLoader : nsISupports
    * the child content process when these events are targeted to
    * the remote browser element.
    *
    * Used primarly for input events (mouse, keyboard)
    */
   const unsigned long EVENT_MODE_NORMAL_DISPATCH = 0x00000000;
 
   /**
-   * With this event mode, it's the application's responsability to 
+   * With this event mode, it's the application's responsability to
    * convert and forward events to the content process
    */
   const unsigned long EVENT_MODE_DONT_FORWARD_TO_CHILD = 0x00000001;
 
   attribute unsigned long eventMode;
 
   /**
    * If false, then the subdocument is not clipped to its CSS viewport, and the
@@ -191,24 +191,25 @@ interface nsIFrameLoader : nsISupports
    *
    * The notion of "visibility" here is separate from the notion of a
    * window/docshell's visibility.  This field is mostly here so that we can
    * have a notion of visibility in the parent process when frames are OOP.
    */
   [infallible] attribute boolean visible;
 
   /**
-   * Find out whether the owner content really is a browser or app frame
-   * Especially, a widget frame is regarded as an app frame.
+   * Find out whether the owner content really is a mozbrowser or app frame
+   * Especially, a widget frame is regarded as an app frame.  <xul:browser> is
+   * not considered to be a mozbrowser frame.
    */
-  readonly attribute boolean ownerIsBrowserOrAppFrame;
+  readonly attribute boolean ownerIsMozBrowserOrAppFrame;
 
   /**
    * Find out whether the owner content really is a widget. If this attribute
-   * returns true, |ownerIsBrowserOrAppFrame| must return true.
+   * returns true, |ownerIsMozBrowserOrAppFrame| must return true.
    */
   readonly attribute boolean ownerIsWidget;
 
 };
 
 %{C++
 class nsFrameLoader;
 %}
--- a/dom/html/nsBrowserElement.cpp
+++ b/dom/html/nsBrowserElement.cpp
@@ -49,25 +49,25 @@ nsBrowserElement::IsNotWidgetOrThrow(Err
   }
   aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
   return false;
 }
 
 void
 nsBrowserElement::InitBrowserElementAPI()
 {
-  bool isBrowserOrApp;
+  bool isMozBrowserOrApp;
   nsCOMPtr<nsIFrameLoader> frameLoader = GetFrameLoader();
   NS_ENSURE_TRUE_VOID(frameLoader);
-  nsresult rv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
+  nsresult rv = frameLoader->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
   NS_ENSURE_SUCCESS_VOID(rv);
   rv = frameLoader->GetOwnerIsWidget(&mOwnerIsWidget);
   NS_ENSURE_SUCCESS_VOID(rv);
 
-  if (!isBrowserOrApp) {
+  if (!isMozBrowserOrApp) {
     return;
   }
 
   if (!mBrowserElementAPI) {
     mBrowserElementAPI = do_CreateInstance("@mozilla.org/dom/browser-element-api;1");
     if (NS_WARN_IF(!mBrowserElementAPI)) {
       return;
     }
@@ -505,23 +505,23 @@ nsBrowserElement::GetAllowedAudioChannel
 
   // If empty, it means that this is the first call of this method.
   if (mBrowserElementAudioChannels.IsEmpty()) {
     nsCOMPtr<nsIFrameLoader> frameLoader = GetFrameLoader();
     if (NS_WARN_IF(!frameLoader)) {
       return;
     }
 
-    bool isBrowserOrApp;
-    aRv = frameLoader->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
+    bool isMozBrowserOrApp;
+    aRv = frameLoader->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
 
-    if (!isBrowserOrApp) {
+    if (!isMozBrowserOrApp) {
       return;
     }
 
     nsCOMPtr<nsIDOMElement> frameElement;
     aRv = frameLoader->GetOwnerElement(getter_AddRefs(frameElement));
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -546,16 +546,30 @@ nsGenericHTMLFrameElement::GetReallyIsWi
   GetManifestURLByType(nsGkAtoms::mozwidget, widgetManifestURL);
   bool isWidget = !widgetManifestURL.IsEmpty();
 
   *aOut = isWidget && !isApp;
   return NS_OK;
 }
 
 /* [infallible] */ NS_IMETHODIMP
+nsGenericHTMLFrameElement::GetIsolated(bool *aOut)
+{
+  *aOut = true;
+
+  if (!nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
+    return NS_OK;
+  }
+
+  // Isolation is only disabled if the attribute is present
+  *aOut = !HasAttr(kNameSpaceID_None, nsGkAtoms::noisolation);
+  return NS_OK;
+}
+
+/* [infallible] */ NS_IMETHODIMP
 nsGenericHTMLFrameElement::GetIsExpectingSystemMessage(bool *aOut)
 {
   *aOut = false;
 
   if (!nsIMozBrowserFrame::GetReallyIsApp()) {
     return NS_OK;
   }
 
@@ -700,9 +714,8 @@ nsGenericHTMLFrameElement::InitializeBro
 }
 
 void
 nsGenericHTMLFrameElement::SwapFrameLoaders(nsXULElement& aOtherOwner,
                                             ErrorResult& aError)
 {
   aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
 }
-
--- a/dom/inputmethod/Keyboard.jsm
+++ b/dom/inputmethod/Keyboard.jsm
@@ -146,17 +146,17 @@ this.Keyboard = {
           type: 'inputmethod-contextchange',
           inputType: 'blur'
         });
 
         this.formMM = null;
       }
     } else {
       // Ignore notifications that aren't from a BrowserOrApp
-      if (!frameLoader.ownerIsBrowserOrAppFrame) {
+      if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
         return;
       }
       this.initFormsFrameScript(mm);
     }
   },
 
   initFormsFrameScript: function(mm) {
     mm.addMessageListener('Forms:Focus', this);
--- a/dom/interfaces/html/nsIMozBrowserFrame.idl
+++ b/dom/interfaces/html/nsIMozBrowserFrame.idl
@@ -39,16 +39,30 @@ interface nsIMozBrowserFrame : nsIDOMMoz
    * In order to really be a frame, this frame must really be a browser
    * frame (this requirement will go away eventually), the frame's mozwidget
    * attribute must point to the manifest of a valid app, and the src should
    * be in the |widgetPages| specified by the manifest.
    */
   [infallible] readonly attribute boolean reallyIsWidget;
 
   /**
+   * Gets whether this frame is an isolated frame.
+   *
+   * By default, browser frames are isolated, meaning they have a principal
+   * where OriginAttributes.mIsInIsolatedMozBrowser == true.  This isolates
+   * storage and other origin related items from non-browser apps, xul:browsers,
+   * etc.
+   *
+   * Isolation can be disabled by setting the frame's isolated attribute to
+   * false.  Disabling isolation is only allowed if the containing document has
+   * browser permission (or equivalent access).
+   */
+  [infallible] readonly attribute boolean isolated;
+
+  /**
    * This corresponds to the expecting-system-message attribute, which tells us
    * whether we should expect that this frame will receive a system message once
    * it starts up.
    *
    * It's the embedder's job to set this attribute on a frame.  Its presence
    * might cause us to increase the priority of the frame's process.
    */
   [infallible] readonly attribute boolean isExpectingSystemMessage;
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -864,19 +864,19 @@ ParticularProcessPriorityManager::OnRemo
   NS_ENSURE_TRUE_VOID(tp);
 
   MOZ_ASSERT(XRE_IsParentProcess());
   if (tp->Manager() != mContentParent) {
     return;
   }
 
   // Ignore notifications that aren't from a BrowserOrApp
-  bool isBrowserOrApp;
-  fl->GetOwnerIsBrowserOrAppFrame(&isBrowserOrApp);
-  if (isBrowserOrApp) {
+  bool isMozBrowserOrApp;
+  fl->GetOwnerIsMozBrowserOrAppFrame(&isMozBrowserOrApp);
+  if (isMozBrowserOrApp) {
     ResetPriority();
   }
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->RemoveObserver(this, "remote-browser-shown");
   }
 }