Bug 1353045 - Remove SDK usage from RDM. r=pbro draft
authorJ. Ryan Stinnett <jryans@gmail.com>
Thu, 06 Apr 2017 21:42:21 -0500
changeset 557644 3aae58033e30a74367834aa291f98985e2e6f2ce
parent 557282 facaf90aeaaf6d7cf5e2966f9f918319536bddea
child 623104 0010537e4a21de7b147599bb676539cdaf506e89
push id52772
push userbmo:jryans@gmail.com
push dateFri, 07 Apr 2017 02:48:07 +0000
reviewerspbro
bugs1353045
milestone55.0a1
Bug 1353045 - Remove SDK usage from RDM. r=pbro MozReview-Commit-ID: I2dodBb9NHh
devtools/client/responsive.html/actions/screenshot.js
devtools/client/responsive.html/components/browser.js
devtools/client/responsive.html/index.js
devtools/client/responsive.html/manager.js
devtools/client/responsive.html/test/browser/browser_menu_item_01.js
devtools/client/responsive.html/test/browser/browser_menu_item_02.js
devtools/client/responsive.html/test/browser/head.js
devtools/client/responsive.html/utils/css.js
devtools/client/responsive.html/utils/moz.build
devtools/client/responsive.html/utils/window.js
--- a/devtools/client/responsive.html/actions/screenshot.js
+++ b/devtools/client/responsive.html/actions/screenshot.js
@@ -7,17 +7,17 @@
 "use strict";
 
 const {
   TAKE_SCREENSHOT_START,
   TAKE_SCREENSHOT_END,
 } = require("./index");
 
 const { getFormatStr } = require("../utils/l10n");
-const { getToplevelWindow } = require("sdk/window/utils");
+const { getToplevelWindow } = require("../utils/window");
 const { Task: { spawn } } = require("devtools/shared/task");
 const e10s = require("../utils/e10s");
 const Services = require("Services");
 
 const CAMERA_AUDIO_URL = "resource://devtools/client/themes/audio/shutter.wav";
 
 const animationFrame = () => new Promise(resolve => {
   window.requestAnimationFrame(resolve);
--- a/devtools/client/responsive.html/components/browser.js
+++ b/devtools/client/responsive.html/components/browser.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* eslint-env browser */
 
 "use strict";
 
 const { Task } = require("devtools/shared/task");
 const flags = require("devtools/shared/flags");
-const { getToplevelWindow } = require("sdk/window/utils");
+const { getToplevelWindow } = require("../utils/window");
 const { DOM: dom, createClass, addons, PropTypes } =
   require("devtools/client/shared/vendor/react");
 
 const Types = require("../types");
 const e10s = require("../utils/e10s");
 const message = require("../utils/message");
 
 module.exports = createClass({
--- a/devtools/client/responsive.html/index.js
+++ b/devtools/client/responsive.html/index.js
@@ -10,17 +10,17 @@ const { utils: Cu } = Components;
 const { BrowserLoader } =
   Cu.import("resource://devtools/client/shared/browser-loader.js", {});
 const { require } = BrowserLoader({
   baseURI: "resource://devtools/client/responsive.html/",
   window
 });
 const { Task } = require("devtools/shared/task");
 const Telemetry = require("devtools/client/shared/telemetry");
-const { loadSheet } = require("sdk/stylesheet/utils");
+const { loadAgentSheet } = require("./utils/css");
 
 const { createFactory, createElement } =
   require("devtools/client/shared/vendor/react");
 const ReactDOM = require("devtools/client/shared/vendor/react-dom");
 const { Provider } = require("devtools/client/shared/vendor/react-redux");
 
 const message = require("./utils/message");
 const App = createFactory(require("./app"));
@@ -37,19 +37,20 @@ let bootstrap = {
 
   telemetry: new Telemetry(),
 
   store: null,
 
   init: Task.async(function* () {
     // Load a special UA stylesheet to reset certain styles such as dropdown
     // lists.
-    loadSheet(window,
-              "resource://devtools/client/responsive.html/responsive-ua.css",
-              "agent");
+    loadAgentSheet(
+      window,
+      "resource://devtools/client/responsive.html/responsive-ua.css"
+    );
     this.telemetry.toolOpened("responsive");
     let store = this.store = Store();
     let provider = createElement(Provider, { store }, App());
     ReactDOM.render(provider, document.querySelector("#root"));
     message.post(window, "init:done");
   }),
 
   destroy() {
--- a/devtools/client/responsive.html/manager.js
+++ b/devtools/client/responsive.html/manager.js
@@ -3,18 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Ci } = require("chrome");
 const promise = require("promise");
 const { Task } = require("devtools/shared/task");
 const EventEmitter = require("devtools/shared/event-emitter");
-const { getOwnerWindow } = require("sdk/tabs/utils");
-const { startup } = require("sdk/window/helpers");
+const { startup } = require("./utils/window");
 const message = require("./utils/message");
 const { swapToInnerBrowser } = require("./browser/swap");
 const { EmulationFront } = require("devtools/shared/fronts/emulation");
 const { getStr } = require("./utils/l10n");
 
 const TOOL_URL = "chrome://devtools/content/responsive.html/index.xhtml";
 
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
@@ -140,17 +139,17 @@ const ResponsiveUIManager = exports.Resp
   /**
    * Returns true if responsive UI is active in any tab in the given window.
    *
    * @param window
    *        The main browser chrome window.
    * @return boolean
    */
   isActiveForWindow(window) {
-    return [...this.activeTabs.keys()].some(t => getOwnerWindow(t) === window);
+    return [...this.activeTabs.keys()].some(t => t.ownerGlobal === window);
   },
 
   /**
    * Return the responsive UI controller for a tab.
    *
    * @param tab
    *        The browser tab.
    * @return ResponsiveUI
@@ -204,17 +203,17 @@ const ResponsiveUIManager = exports.Resp
 
   removeMenuCheckListenerFor(window) {
     if (window && window.gBrowser && window.gBrowser.tabContainer) {
       let { tabContainer } = window.gBrowser;
       tabContainer.removeEventListener("TabSelect", this.handleMenuCheck);
     }
   },
 
-  setMenuCheckFor: Task.async(function* (tab, window = getOwnerWindow(tab)) {
+  setMenuCheckFor: Task.async(function* (tab, window = tab.ownerGlobal) {
     yield startup(window);
 
     let menu = window.document.getElementById("menu_responsiveUI");
     if (menu) {
       menu.setAttribute("checked", this.isActiveForTab(tab));
     }
   }),
 
--- a/devtools/client/responsive.html/test/browser/browser_menu_item_01.js
+++ b/devtools/client/responsive.html/test/browser/browser_menu_item_01.js
@@ -2,28 +2,28 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Test RDM menu item is checked when expected, on multiple tabs.
 
 const TEST_URL = "data:text/html;charset=utf-8,";
 
-const tabUtils = require("sdk/tabs/utils");
-const { startup } = require("sdk/window/helpers");
+const { startup } = require("devtools/client/responsive.html/utils/window");
 
 const activateTab = (tab) => new Promise(resolve => {
-  let { tabContainer } = tabUtils.getOwnerWindow(tab).gBrowser;
+  let { gBrowser } = tab.ownerGlobal;
+  let { tabContainer } = gBrowser;
 
   tabContainer.addEventListener("TabSelect", function listener({type}) {
     tabContainer.removeEventListener(type, listener);
     resolve();
   });
 
-  tabUtils.activateTab(tab);
+  gBrowser.selectedTab = tab;
 });
 
 const isMenuChecked = () => {
   let menu = document.getElementById("menu_responsiveUI");
   return menu.getAttribute("checked") === "true";
 };
 
 add_task(function* () {
--- a/devtools/client/responsive.html/test/browser/browser_menu_item_02.js
+++ b/devtools/client/responsive.html/test/browser/browser_menu_item_02.js
@@ -2,32 +2,30 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Test RDM menu item is checked when expected, on multiple windows.
 
 const TEST_URL = "data:text/html;charset=utf-8,";
 
-const { getMostRecentBrowserWindow } = require("sdk/window/utils");
-
 const isMenuCheckedFor = ({document}) => {
   let menu = document.getElementById("menu_responsiveUI");
   return menu.getAttribute("checked") === "true";
 };
 
 add_task(function* () {
   const window1 = yield BrowserTestUtils.openNewBrowserWindow();
   let { gBrowser } = window1;
 
   yield BrowserTestUtils.withNewTab({ gBrowser, url: TEST_URL },
     function* (browser) {
       let tab = gBrowser.getTabForBrowser(browser);
 
-      is(window1, getMostRecentBrowserWindow(),
+      is(window1, Services.wm.getMostRecentWindow("navigator:browser"),
         "The new window is the active one");
 
       ok(!isMenuCheckedFor(window1),
         "RDM menu item is unchecked by default");
 
       yield openRDM(tab);
 
       ok(isMenuCheckedFor(window1),
@@ -36,14 +34,14 @@ add_task(function* () {
       yield closeRDM(tab);
 
       ok(!isMenuCheckedFor(window1),
         "RDM menu item is unchecked with RDM closed");
     });
 
   yield BrowserTestUtils.closeWindow(window1);
 
-  is(window, getMostRecentBrowserWindow(),
+  is(window, Services.wm.getMostRecentWindow("navigator:browser"),
     "The original window is the active one");
 
   ok(!isMenuCheckedFor(window),
     "RDM menu item is unchecked");
 });
--- a/devtools/client/responsive.html/test/browser/head.js
+++ b/devtools/client/responsive.html/test/browser/head.js
@@ -31,17 +31,16 @@ Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js",
   this);
 
 const E10S_MULTI_ENABLED = Services.prefs.getIntPref("dom.ipc.processCount") > 1;
 const TEST_URI_ROOT = "http://example.com/browser/devtools/client/responsive.html/test/browser/";
 const OPEN_DEVICE_MODAL_VALUE = "OPEN_DEVICE_MODAL";
 
 const { _loadPreferredDevices } = require("devtools/client/responsive.html/actions/devices");
-const { getOwnerWindow } = require("sdk/tabs/utils");
 const asyncStorage = require("devtools/shared/async-storage");
 const { addDevice, removeDevice } = require("devtools/client/shared/devices");
 
 SimpleTest.requestCompleteLog();
 SimpleTest.waitForExplicitFinish();
 
 // Toggling the RDM UI involves several docShell swap operations, which are somewhat slow
 // on debug builds. Usually we are just barely over the limit, so a blanket factor of 2
@@ -67,28 +66,28 @@ registerCleanupFunction(() => {
 const { ResponsiveUIManager } = require("resource://devtools/client/responsivedesign/responsivedesign.jsm");
 
 /**
  * Open responsive design mode for the given tab.
  */
 var openRDM = Task.async(function* (tab) {
   info("Opening responsive design mode");
   let manager = ResponsiveUIManager;
-  let ui = yield manager.openIfNeeded(getOwnerWindow(tab), tab);
+  let ui = yield manager.openIfNeeded(tab.ownerGlobal, tab);
   info("Responsive design mode opened");
   return { ui, manager };
 });
 
 /**
  * Close responsive design mode for the given tab.
  */
 var closeRDM = Task.async(function* (tab, options) {
   info("Closing responsive design mode");
   let manager = ResponsiveUIManager;
-  yield manager.closeIfNeeded(getOwnerWindow(tab), tab, options);
+  yield manager.closeIfNeeded(tab.ownerGlobal, tab, options);
   info("Responsive design mode closed");
 });
 
 /**
  * Adds a new test task that adds a tab with the given URL, opens responsive
  * design mode, runs the given generator, closes responsive design mode, and
  * removes the tab.
  *
new file mode 100644
--- /dev/null
+++ b/devtools/client/responsive.html/utils/css.js
@@ -0,0 +1,18 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { getDOMWindowUtils } = require("./window");
+
+/**
+ * Synchronously loads an agent style sheet from `uri` and adds it to the list of
+ * additional style sheets of the document.  The sheets added takes effect immediately,
+ * and only on the document of the `window` given.
+ */
+function loadAgentSheet(window, url) {
+  let winUtils = getDOMWindowUtils(window);
+  winUtils.loadSheetUsingURIString(url, winUtils.AGENT_SHEET);
+}
+exports.loadAgentSheet = loadAgentSheet;
--- a/devtools/client/responsive.html/utils/moz.build
+++ b/devtools/client/responsive.html/utils/moz.build
@@ -1,11 +1,13 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DevToolsModules(
+    'css.js',
     'e10s.js',
     'l10n.js',
     'message.js',
+    'window.js',
 )
new file mode 100644
--- /dev/null
+++ b/devtools/client/responsive.html/utils/window.js
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { Ci } = require("chrome");
+const Services = require("Services");
+
+/**
+ * Returns the `nsIDOMWindow` toplevel window for any child/inner window
+ */
+function getToplevelWindow(window) {
+  return window.QueryInterface(Ci.nsIInterfaceRequestor)
+               .getInterface(Ci.nsIWebNavigation)
+               .QueryInterface(Ci.nsIDocShellTreeItem)
+               .rootTreeItem
+               .QueryInterface(Ci.nsIInterfaceRequestor)
+               .getInterface(Ci.nsIDOMWindow);
+}
+exports.getToplevelWindow = getToplevelWindow;
+
+function getDOMWindowUtils(window) {
+  return window.QueryInterface(Ci.nsIInterfaceRequestor)
+               .getInterface(Ci.nsIDOMWindowUtils);
+}
+exports.getDOMWindowUtils = getDOMWindowUtils;
+
+/**
+ * Check if the given browser window has finished the startup.
+ * @params {nsIDOMWindow} window
+ */
+const isStartupFinished = (window) =>
+  window.gBrowserInit &&
+  window.gBrowserInit.delayedStartupFinished;
+
+function startup(window) {
+  return new Promise(resolve => {
+    if (isStartupFinished(window)) {
+      resolve(window);
+      return;
+    }
+    Services.obs.addObserver(function listener({ subject }) {
+      if (subject === window) {
+        Services.obs.removeObserver(listener, "browser-delayed-startup-finished");
+        resolve(window);
+      }
+    }, "browser-delayed-startup-finished", false);
+  });
+}
+exports.startup = startup;