Bug 1496840 - Add a browsingContext getter to the browser element. r=farre
authorFelipe Gomes <felipc@gmail.com>
Mon, 12 Nov 2018 17:57:48 +0000
changeset 445917 ab2cc746e45119d3bfca34d222a3189036cbe101
parent 445916 65987ae1dfca24cd89bf99803f78d298ca9029b8
child 445918 05331fb8f5338974b913217bc67815df25a32e86
push id72824
push userfgomes@mozilla.com
push dateMon, 12 Nov 2018 17:59:20 +0000
treeherderautoland@ab2cc746e451 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfarre
bugs1496840
milestone65.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 1496840 - Add a browsingContext getter to the browser element. r=farre Differential Revision: https://phabricator.services.mozilla.com/D7935
docshell/test/browser/browser_browsingContext.js
dom/base/ChromeUtils.cpp
dom/base/ChromeUtils.h
dom/chrome-webidl/ChromeUtils.webidl
toolkit/content/browser-child.js
toolkit/content/widgets/browser.xml
--- a/docshell/test/browser/browser_browsingContext.js
+++ b/docshell/test/browser/browser_browsingContext.js
@@ -93,16 +93,17 @@ function getBrowsingContextById(id) {
 
 add_task(async function() {
   await BrowserTestUtils.withNewTab({ gBrowser, url: URL },
     async function(browser) {
       let topId = await getBrowsingContextId(browser, "");
       let topContext = getBrowsingContextById(topId);
       isnot(topContext, null);
       is(topContext.parent, null);
+      is(topId, browser.browsingContext.id, "<browser> has the correct browsingContext");
 
       let id0 = await addFrame(browser, "frame0");
       let browsingContext0 = getBrowsingContextById(id0);
       isnot(browsingContext0, null);
       is(browsingContext0.parent, topContext);
 
       let id1 = await addFrame(browser, "frame1", "frame0");
       let browsingContext1 = getBrowsingContextById(id1);
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -777,16 +777,22 @@ ChromeUtils::RequestIOActivity(GlobalObj
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
   MOZ_ASSERT(domPromise);
   mozilla::net::IOActivityMonitor::RequestActivities(domPromise);
   return domPromise.forget();
 }
 
+/* static */ already_AddRefed<BrowsingContext>
+ChromeUtils::GetBrowsingContext(GlobalObject& aGlobal, uint64_t id)
+{
+  return BrowsingContext::Get(id);
+}
+
 /* static */ void
 ChromeUtils::GetRootBrowsingContexts(GlobalObject& aGlobal,
                                      nsTArray<RefPtr<BrowsingContext>>& aBrowsingContexts)
 {
   BrowsingContext::GetRootBrowsingContexts(aBrowsingContexts);
 }
 
 } // namespace dom
--- a/dom/base/ChromeUtils.h
+++ b/dom/base/ChromeUtils.h
@@ -184,16 +184,19 @@ public:
   static void
   CreateError(const GlobalObject& global, const nsAString& message,
               JS::Handle<JSObject*> stack,
               JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv);
 
   static already_AddRefed<Promise>
   RequestIOActivity(GlobalObject& aGlobal, ErrorResult& aRv);
 
+  static already_AddRefed<BrowsingContext>
+  GetBrowsingContext(GlobalObject& aGlobal, uint64_t id);
+
   static void
   GetRootBrowsingContexts(GlobalObject& aGlobal,
                           nsTArray<RefPtr<BrowsingContext>>& aBrowsingContexts);
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/chrome-webidl/ChromeUtils.webidl
+++ b/dom/chrome-webidl/ChromeUtils.webidl
@@ -351,16 +351,25 @@ partial namespace ChromeUtils {
   Promise<sequence<PerformanceInfoDictionary>> requestPerformanceMetrics();
 
   /**
   * Returns a Promise containing a sequence of I/O activities
   */
   [Throws]
   Promise<sequence<IOActivityDataDictionary>> requestIOActivity();
 
+  /**
+   * Returns the BrowsingContext referred by the given id.
+   */
+  [ChromeOnly]
+  BrowsingContext? getBrowsingContext(unsigned long long id);
+
+  /**
+   * Returns all the root BrowsingContexts.
+   */
   [ChromeOnly]
   sequence<BrowsingContext> getRootBrowsingContexts();
 };
 
 /**
  * Dictionaries duplicating IPDL types in dom/ipc/DOMTypes.ipdlh
  * Used by requestPerformanceMetrics
  */
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -24,9 +24,10 @@ addEventListener("ImageContentLoaded", f
     sendAsyncMessage("ImageDocumentLoaded", { width: req.image.width,
                                               height: req.image.height });
   }
 }, false);
 
 // We may not get any responses to Browser:Init if the browser element
 // is torn down too quickly.
 var outerWindowID = docShell.outerWindowID;
-sendAsyncMessage("Browser:Init", {outerWindowID});
+var browsingContextId = docShell.browsingContext.id;
+sendAsyncMessage("Browser:Init", {outerWindowID, browsingContextId});
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -476,16 +476,28 @@
             if (e.result != Cr.NS_ERROR_NOT_AVAILABLE) {
               throw e;
             }
             return null;
           }
         ]]></getter>
       </property>
 
+      <field name="_browsingContextId">null</field>
+
+      <property name="browsingContext" readonly="true">
+        <getter><![CDATA[
+          if (!this.isRemoteBrowser) {
+            return this.docShell.browsingContext;
+          }
+
+          return ChromeUtils.getBrowsingContext(this._browsingContextId);
+        ]]></getter>
+      </property>
+
       <field name="_lastSearchString">null</field>
 
 
       <field name="_controller">null</field>
 
       <field name="_selectParentHelper">null</field>
 
       <field name="_remoteWebNavigation">null</field>
@@ -1276,16 +1288,17 @@
           if (!this.isRemoteBrowser) {
             return this._receiveMessage(aMessage);
           }
 
           let data = aMessage.data;
           switch (aMessage.name) {
             case "Browser:Init":
               this._outerWindowID = data.outerWindowID;
+              this._browsingContextId = data.browsingContextId;
               break;
             case "DOMTitleChanged":
               this._contentTitle = data.title;
               break;
             case "ImageDocumentLoaded":
               this._imageDocument = {
                 width: data.width,
                 height: data.height,