Bug 1297758 - Make the inspector self-loadable. r=bgrins
☠☠ backed out by ea0886a6ed22 ☠ ☠
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 26 Sep 2016 06:20:58 -0700
changeset 315375 1ac36ff4b601e5d2188456bb7c6f0d979d291c14
parent 315374 883ddedd5ec58d5cb5fa2f7bc4d36edacc7ba7ca
child 315376 fee0da9566185a4b6ea19bcb2c67f6fd3dcaf195
push id30748
push usercbook@mozilla.com
push dateWed, 28 Sep 2016 13:53:19 +0000
treeherdermozilla-central@8c84b7618840 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1297758
milestone52.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 1297758 - Make the inspector self-loadable. r=bgrins MozReview-Commit-ID: GsmNhW7CbNX
devtools/client/definitions.js
devtools/client/inspector/inspector-panel.js
devtools/client/inspector/inspector.xhtml
devtools/client/inspector/moz.build
devtools/client/inspector/panel.js
devtools/client/jar.mn
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -4,17 +4,17 @@
 
 "use strict";
 
 const Services = require("Services");
 const osString = Services.appinfo.OS;
 
 // Panels
 loader.lazyGetter(this, "OptionsPanel", () => require("devtools/client/framework/toolbox-options").OptionsPanel);
-loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/inspector-panel").InspectorPanel);
+loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/panel").InspectorPanel);
 loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/client/webconsole/panel").WebConsolePanel);
 loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/client/debugger/panel").DebuggerPanel);
 loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/client/styleeditor/styleeditor-panel").StyleEditorPanel);
 loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/client/shadereditor/panel").ShaderEditorPanel);
 loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/client/canvasdebugger/panel").CanvasDebuggerPanel);
 loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/client/webaudioeditor/panel").WebAudioEditorPanel);
 loader.lazyGetter(this, "MemoryPanel", () => require("devtools/client/memory/panel").MemoryPanel);
 loader.lazyGetter(this, "PerformancePanel", () => require("devtools/client/performance/panel").PerformancePanel);
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -1,16 +1,20 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* 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/. */
 
+/* global window */
+
 "use strict";
 
+var Cu = Components.utils;
+var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
 var Services = require("Services");
 var promise = require("promise");
 var defer = require("devtools/shared/defer");
 var EventEmitter = require("devtools/shared/event-emitter");
 const {executeSoon} = require("devtools/shared/DevToolsUtils");
 var {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
 var {Task} = require("devtools/shared/task");
 const {initCssProperties} = require("devtools/shared/fronts/css-properties");
@@ -76,21 +80,21 @@ const PORTRAIT_MODE_WIDTH = 700;
  * - computed-view-filtered
  *      Fired when the computed rules view is filtered
  * - rule-view-refreshed
  *      Fired when the rule view updates to a new node
  * - rule-view-sourcelinks-updated
  *      Fired when the stylesheet source links have been updated (when switching
  *      to source-mapped files)
  */
-function InspectorPanel(iframeWindow, toolbox) {
+function Inspector(toolbox) {
   this._toolbox = toolbox;
   this._target = toolbox.target;
-  this.panelDoc = iframeWindow.document;
-  this.panelWin = iframeWindow;
+  this.panelDoc = window.document;
+  this.panelWin = window;
   this.panelWin.inspector = this;
 
   this.telemetry = new Telemetry();
 
   this.nodeMenuTriggerInfo = null;
 
   this._handleRejectionIfNotDestroyed = this._handleRejectionIfNotDestroyed.bind(this);
   this._onBeforeNavigate = this._onBeforeNavigate.bind(this);
@@ -107,23 +111,21 @@ function InspectorPanel(iframeWindow, to
   this.onSidebarHidden = this.onSidebarHidden.bind(this);
 
   this._target.on("will-navigate", this._onBeforeNavigate);
   this._detectingActorFeatures = this._detectActorFeatures();
 
   EventEmitter.decorate(this);
 }
 
-exports.InspectorPanel = InspectorPanel;
-
-InspectorPanel.prototype = {
+Inspector.prototype = {
   /**
    * open is effectively an asynchronous constructor
    */
-  open: Task.async(function* () {
+  init: Task.async(function* () {
     // Localize all the nodes containing a data-localization attribute.
     localizeMarkup(this.panelDoc);
 
     this._cssPropertiesLoaded = initCssProperties(this.toolbox);
     yield this._cssPropertiesLoaded;
     yield this.target.makeRemote();
     yield this._getPageStyle();
     let defaultSelection = yield this._getDefaultNodeForSelection();
@@ -141,16 +143,20 @@ InspectorPanel.prototype = {
   get walker() {
     return this._toolbox.walker;
   },
 
   get selection() {
     return this._toolbox.selection;
   },
 
+  get highlighter() {
+    return this._toolbox.highlighter;
+  },
+
   get isOuterHTMLEditable() {
     return this._target.client.traits.editOuterHTML;
   },
 
   get hasUrlToImageDataResolver() {
     return this._target.client.traits.urlToImageDataResolver;
   },
 
@@ -270,17 +276,17 @@ InspectorPanel.prototype = {
     this._defaultNode = null;
     this.selection.setNodeFront(null);
     this._destroyMarkup();
     this.isDirty = false;
     this._pendingSelection = null;
   },
 
   _getPageStyle: function () {
-    return this._toolbox.inspector.getPageStyle().then(pageStyle => {
+    return this.inspector.getPageStyle().then(pageStyle => {
       this.pageStyle = pageStyle;
     }, this._handleRejectionIfNotDestroyed);
   },
 
   /**
    * Return a promise that will resolve to the default node for selection.
    */
   _getDefaultNodeForSelection: function () {
@@ -1811,8 +1817,77 @@ InspectorPanel.prototype = {
   copyAttributeLink: function (link) {
     // When the inspector menu was setup on click (see _getNodeLinkMenuItems), we
     // already checked that resolveRelativeURL existed.
     this.inspector.resolveRelativeURL(link, this.selection.nodeFront).then(url => {
       clipboardHelper.copyString(url);
     }, console.error);
   }
 };
+
+// URL constructor doesn't support chrome: scheme
+let href = window.location.href.replace(/chrome:/, "http://");
+let url = new window.URL(href);
+
+// Only use this method to attach the toolbox if some query parameters are given
+if (url.search.length > 1) {
+  const { targetFromURL } = require("devtools/client/framework/target-from-url");
+  const { attachThread } = require("devtools/client/framework/attach-thread");
+  const { BrowserLoader } =
+    Cu.import("resource://devtools/client/shared/browser-loader.js", {});
+
+  const { Selection } = require("devtools/client/framework/selection");
+  const { InspectorFront } = require("devtools/shared/fronts/inspector");
+  const { getHighlighterUtils } = require("devtools/client/framework/toolbox-highlighter-utils");
+
+  Task.spawn(function* () {
+    let target = yield targetFromURL(url);
+
+    let fakeToolbox = {
+      target,
+      hostType: "bottom",
+      doc: window.document,
+      win: window,
+      on() {}, emit() {}, off() {},
+      initInspector() {},
+      browserRequire: BrowserLoader({
+        window: window,
+        useOnlyShared: true
+      }).require,
+      get React() {
+        return this.browserRequire("devtools/client/shared/vendor/react");
+      },
+      get ReactDOM() {
+        return this.browserRequire("devtools/client/shared/vendor/react-dom");
+      },
+      isToolRegistered() {
+        return false;
+      },
+      // For attachThread:
+      highlightTool() {},
+      unhighlightTool() {},
+      selectTool() {},
+      raise() {},
+      getNotificationBox() {}
+    };
+
+    // attachThread also expect a toolbox as argument
+    fakeToolbox.threadClient = yield attachThread(fakeToolbox);
+
+    let inspector = InspectorFront(target.client, target.form);
+    let showAllAnonymousContent =
+      Services.prefs.getBoolPref("devtools.inspector.showAllAnonymousContent");
+    let walker = yield inspector.getWalker({ showAllAnonymousContent });
+    let selection = new Selection(walker);
+    let highlighter = yield inspector.getHighlighter(false);
+
+    fakeToolbox.inspector = inspector;
+    fakeToolbox.walker = walker;
+    fakeToolbox.selection = selection;
+    fakeToolbox.highlighter = highlighter;
+    fakeToolbox.highlighterUtils = getHighlighterUtils(fakeToolbox);
+
+    let inspectorUI = new Inspector(fakeToolbox);
+    inspectorUI.init();
+  }).then(null, e => {
+    window.alert("Unable to start the inspector:" + e.message + "\n" + e.stack);
+  });
+}
--- a/devtools/client/inspector/inspector.xhtml
+++ b/devtools/client/inspector/inspector.xhtml
@@ -20,16 +20,17 @@
 
 <!DOCTYPE html>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
   <script type="application/javascript;version=1.8"
           src="chrome://devtools/content/shared/theme-switching.js"></script>
+  <script type="application/javascript;version=1.8" src="inspector-panel.js" defer="true"></script>
 </head>
 <body class="theme-body" role="application">
   <div class="inspector-responsive-container theme-body inspector">
 
     <!-- Main Panel Content -->
     <div id="inspector-main-content" class="devtools-main-content">
       <div id="inspector-toolbar" class="devtools-toolbar" nowindowdrag="true"
                 data-localization-bundle="devtools/locale/inspector.properties">
--- a/devtools/client/inspector/moz.build
+++ b/devtools/client/inspector/moz.build
@@ -9,15 +9,15 @@ DIRS += [
     'markup',
     'rules',
     'shared'
 ]
 
 DevToolsModules(
     'breadcrumbs.js',
     'inspector-commands.js',
-    'inspector-panel.js',
     'inspector-search.js',
     'inspector.xhtml',
+    'panel.js',
     'toolsidebar.js',
 )
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/panel.js
@@ -0,0 +1,19 @@
+/* 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";
+
+function InspectorPanel(iframeWindow, toolbox) {
+  this._inspector = new iframeWindow.Inspector(toolbox);
+}
+InspectorPanel.prototype = {
+  open() {
+    return this._inspector.init();
+  },
+
+  destroy() {
+    return this._inspector.destroy();
+  }
+};
+exports.InspectorPanel = InspectorPanel;
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -20,16 +20,17 @@ devtools.jar:
     content/webconsole/webconsole.xul (webconsole/webconsole.xul)
 *   content/scratchpad/scratchpad.xul (scratchpad/scratchpad.xul)
     content/scratchpad/scratchpad.js (scratchpad/scratchpad.js)
     content/shared/splitview.css (shared/splitview.css)
     content/shared/theme-switching.js (shared/theme-switching.js)
     content/shared/frame-script-utils.js (shared/frame-script-utils.js)
     content/styleeditor/styleeditor.xul (styleeditor/styleeditor.xul)
     content/storage/storage.xul (storage/storage.xul)
+    content/inspector/inspector-panel.js (inspector/inspector-panel.js)
     content/inspector/fonts/fonts.js (inspector/fonts/fonts.js)
     content/inspector/markup/markup.xhtml (inspector/markup/markup.xhtml)
     content/animationinspector/animation-controller.js (animationinspector/animation-controller.js)
     content/animationinspector/animation-panel.js (animationinspector/animation-panel.js)
     content/animationinspector/animation-inspector.xhtml (animationinspector/animation-inspector.xhtml)
     content/sourceeditor/codemirror/addon/dialog/dialog.css (sourceeditor/codemirror/addon/dialog/dialog.css)
     content/sourceeditor/codemirror/addon/hint/show-hint.js (sourceeditor/codemirror/addon/hint/show-hint.js)
     content/sourceeditor/codemirror/addon/tern/tern.js (sourceeditor/codemirror/addon/tern/tern.js)