Bug 1291049 - Load the inspector in a content tab draft
authorJulian Descottes <jdescottes@mozilla.com>
Tue, 11 Oct 2016 19:51:10 +0200
changeset 423861 d5808547937e
parent 423860 288988b82fa5
child 423862 37332fcb08c1
push id32011
push userjdescottes@mozilla.com
push dateTue, 11 Oct 2016 20:09:36 +0000
bugs1291049
milestone52.0a1
Bug 1291049 - Load the inspector in a content tab MozReview-Commit-ID: 3y9Oi5GWNTY
devtools/client/framework/devtools.js
devtools/client/framework/selection.js
devtools/client/framework/target.js
devtools/client/inspector/computed/computed.js
devtools/client/inspector/inspector.js
devtools/client/inspector/inspector.xhtml
devtools/client/inspector/markup/markup.xhtml
devtools/client/inspector/markup/views/html-editor.js
devtools/client/inspector/rules/views/rule-editor.js
devtools/client/inspector/toolsidebar.js
devtools/client/shared/widgets/MdnDocsWidget.js
devtools/client/shared/widgets/tooltip/TooltipToggle.js
devtools/client/sourceeditor/editor.js
devtools/client/themes/inspector.css
devtools/client/themes/rules.css
devtools/client/webpack.config.js
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -10,19 +10,19 @@ const defer = require("devtools/shared/d
 
 // Load gDevToolsBrowser toolbox lazily as they need gDevTools to be fully initialized
 loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
 loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
 
 const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} =
   require("devtools/client/definitions");
 const EventEmitter = require("devtools/shared/event-emitter");
-const {JsonView} = require("devtools/client/jsonview/main");
-const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
-const {when: unload} = require("sdk/system/unload");
+// const {JsonView} = require("devtools/client/jsonview/main");
+// const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
+// const {when: unload} = require("sdk/system/unload");
 
 const FORBIDDEN_IDS = new Set(["toolbox", ""]);
 const MAX_ORDINAL = 99;
 
 /**
  * DevTools is a class that represents a set of developer tools, it holds a
  * set of tools and keeps track of open toolboxes in the browser.
  */
@@ -30,31 +30,31 @@ this.DevTools = function DevTools() {
   this._tools = new Map();     // Map<toolId, tool>
   this._themes = new Map();    // Map<themeId, theme>
   this._toolboxes = new Map(); // Map<target, toolbox>
 
   // destroy() is an observer's handler so we need to preserve context.
   this.destroy = this.destroy.bind(this);
 
   // JSON Viewer for 'application/json' documents.
-  JsonView.initialize();
+  // JsonView.initialize();
 
-  AboutDevTools.register();
+  // AboutDevTools.register();
 
   EventEmitter.decorate(this);
 
-  Services.obs.addObserver(this.destroy, "quit-application", false);
+  // Services.obs.addObserver(this.destroy, "quit-application", false);
 
   // This is important step in initialization codepath where we are going to
   // start registering all default tools and themes: create menuitems, keys, emit
   // related events.
   this.registerDefaults();
 };
 
-DevTools.prototype = {
+this.DevTools.prototype = {
   // The windowtype of the main window, used in various tools. This may be set
   // to something different by other gecko apps.
   chromeWindowType: "navigator:browser",
 
   registerDefaults() {
     // Ensure registering items in the sorted order (getDefault* functions
     // return sorted lists)
     this.getDefaultTools().forEach(definition => this.registerTool(definition));
@@ -509,14 +509,14 @@ DevTools.prototype = {
    */
   *[Symbol.iterator ]() {
     for (let toolbox of this._toolboxes) {
       yield toolbox;
     }
   }
 };
 
-const gDevTools = exports.gDevTools = new DevTools();
+const gDevTools = exports.gDevTools = new this.DevTools();
 
 // Watch for module loader unload. Fires when the tools are reloaded.
-unload(function () {
-  gDevTools._teardown();
-});
+// unload(function () {
+//   gDevTools._teardown();
+// });
--- a/devtools/client/framework/selection.js
+++ b/devtools/client/framework/selection.js
@@ -1,17 +1,17 @@
 /* -*- 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/. */
 
 "use strict";
 
-const { Cu } = require("chrome");
+// const { Cu } = require("chrome");
 const nodeConstants = require("devtools/shared/dom-node-constants");
 const { getRootBindingParent } = require("devtools/shared/layout/utils");
 var EventEmitter = require("devtools/shared/event-emitter");
 
 /**
  * API
  *
  *   new Selection(walker=null)
@@ -179,19 +179,19 @@ Selection.prototype = {
 
   isNode: function () {
     if (!this._nodeFront) {
       return false;
     }
 
     // As long as tools are still accessing node.rawNode(),
     // this needs to stay here.
-    if (this._node && Cu.isDeadWrapper(this._node)) {
-      return false;
-    }
+    // if (this._node && Cu.isDeadWrapper(this._node)) {
+    //   return false;
+    // }
 
     return true;
   },
 
   isLocal: function () {
     return !!this._node;
   },
 
--- a/devtools/client/framework/target.js
+++ b/devtools/client/framework/target.js
@@ -652,18 +652,18 @@ TabTarget.prototype = {
  */
 function TabWebProgressListener(aTarget) {
   this.target = aTarget;
 }
 
 TabWebProgressListener.prototype = {
   target: null,
 
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
-                                         Ci.nsISupportsWeakReference]),
+  // QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+  //                                        Ci.nsISupportsWeakReference]),
 
   onStateChange: function (progress, request, flag) {
     let isStart = flag & Ci.nsIWebProgressListener.STATE_START;
     let isDocument = flag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
     let isNetwork = flag & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
     let isRequest = flag & Ci.nsIWebProgressListener.STATE_IS_REQUEST;
 
     // Skip non-interesting states.
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -28,16 +28,29 @@ const clipboardHelper = require("devtool
 
 const STYLE_INSPECTOR_PROPERTIES = "devtools-shared/locale/styleinspector.properties";
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
 
 const FILTER_CHANGED_TIMEOUT = 150;
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
+const ITERATOR_DONE_ERROR = "Iterator done";
+const _Iterator = function (array) {
+  let nextIndex = 0;
+  return {
+    next: function () {
+      if (nextIndex < array.length) {
+        return [false, array[nextIndex++]];
+      }
+      throw new Error(ITERATOR_DONE_ERROR);
+    }
+  };
+};
+
 /**
  * Helper for long-running processes that should yield occasionally to
  * the mainloop.
  *
  * @param {Window} win
  *        Timeouts will be set on this window when appropriate.
  * @param {Generator} generator
  *        Will iterate this generator.
@@ -87,17 +100,17 @@ UpdateProcess.prototype = {
   },
 
   _timeoutHandler: function () {
     this._timeout = null;
     try {
       this._runBatch();
       this.schedule();
     } catch (e) {
-      if (e instanceof StopIteration) {
+      if (e instanceof StopIteration || e.message === ITERATOR_DONE_ERROR) {
         this.onBatch();
         this.onDone();
         return;
       }
       console.error(e);
       throw e;
     }
   },
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -28,16 +28,18 @@ const {FontInspector} = require("devtool
 const {HTMLBreadcrumbs} = require("devtools/client/inspector/breadcrumbs");
 const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
 const {LayoutViewTool} = require("devtools/client/inspector/layout/layout");
 const MarkupView = require("devtools/client/inspector/markup/markup");
 const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
 const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
 const {ViewHelpers} = require("devtools/client/shared/widgets/view-helpers");
 const clipboardHelper = require("devtools/shared/platform/clipboard");
+const InspectorTabPanelClass = require("devtools/client/inspector/components/inspector-tab-panel");
+const SplitBoxClass = require("devtools/client/shared/components/splitter/split-box");
 
 const {LocalizationHelper, localizeMarkup} = require("devtools/shared/l10n");
 const INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.properties");
 const TOOLBOX_L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
 
 // Sidebar dimensions
 const INITIAL_SIDEBAR_SIZE = 350;
 
@@ -115,16 +117,17 @@ function Inspector(toolbox) {
   EventEmitter.decorate(this);
 }
 
 Inspector.prototype = {
   /**
    * open is effectively an asynchronous constructor
    */
   init: Task.async(function* () {
+    this.panelDoc.querySelector("#mount").remove();
     // 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();
@@ -420,19 +423,17 @@ Inspector.prototype = {
   },
 
   get browserRequire() {
     return this._toolbox.browserRequire;
   },
 
   get InspectorTabPanel() {
     if (!this._InspectorTabPanel) {
-      this._InspectorTabPanel =
-        this.React.createFactory(this.browserRequire(
-        "devtools/client/inspector/components/inspector-tab-panel"));
+      this._InspectorTabPanel = this.React.createFactory(InspectorTabPanelClass);
     }
     return this._InspectorTabPanel;
   },
 
   /**
    * Check if the inspector should use the landscape mode.
    *
    * @return {Boolean} true if the inspector should be in landscape mode.
@@ -442,18 +443,17 @@ Inspector.prototype = {
     return clientWidth > PORTRAIT_MODE_WIDTH;
   },
 
   /**
    * Build Splitter located between the main and side area of
    * the Inspector panel.
    */
   setupSplitter: function () {
-    let SplitBox = this.React.createFactory(this.browserRequire(
-      "devtools/client/shared/components/splitter/split-box"));
+    let SplitBox = this.React.createFactory(SplitBoxClass);
 
     let splitter = SplitBox({
       className: "inspector-sidebar-splitter",
       initialWidth: INITIAL_SIDEBAR_SIZE,
       initialHeight: INITIAL_SIDEBAR_SIZE,
       splitterSize: 1,
       endPanelControl: true,
       startPanel: this.InspectorTabPanel({
@@ -607,20 +607,20 @@ Inspector.prototype = {
    * @param {boolean} selected true if the panel should be selected
    */
   addSidebarTab: function (id, title, panel, selected) {
     this.sidebar.addTab(id, title, panel, selected);
   },
 
   setupToolbar: function () {
     this.teardownToolbar();
+    const SidebarToggleClass = require("devtools/client/shared/components/sidebar-toggle");
 
     // Setup the sidebar toggle button.
-    let SidebarToggle = this.React.createFactory(this.browserRequire(
-      "devtools/client/shared/components/sidebar-toggle"));
+    let SidebarToggle = this.React.createFactory(SidebarToggleClass);
 
     let sidebarToggle = SidebarToggle({
       onClick: this.onPaneToggleButtonClicked,
       collapsed: false,
       expandPaneTitle: INSPECTOR_L10N.getStr("inspector.expandPane"),
       collapsePaneTitle: INSPECTOR_L10N.getStr("inspector.collapsePane"),
     });
 
@@ -1322,17 +1322,17 @@ Inspector.prototype = {
     this._markupFrame.setAttribute("tooltip", "aHTMLTooltip");
     this._markupFrame.addEventListener("contextmenu", this._onContextMenu);
 
     // This is needed to enable tooltips inside the iframe document.
     this._markupFrame.addEventListener("load", this._onMarkupFrameLoad, true);
 
     this._markupBox.setAttribute("collapsed", true);
     this._markupBox.appendChild(this._markupFrame);
-    this._markupFrame.setAttribute("src", "chrome://devtools/content/inspector/markup/markup.xhtml");
+    this._markupFrame.setAttribute("src", "markup/markup.xhtml");
     this._markupFrame.setAttribute("aria-label",
       INSPECTOR_L10N.getStr("inspector.panelLabel.markupView"));
   },
 
   _onMarkupFrameLoad: function () {
     this._markupFrame.removeEventListener("load", this._onMarkupFrameLoad, true);
 
     this._markupFrame.contentWindow.focus();
@@ -1864,25 +1864,24 @@ Inspector.prototype = {
   }
 };
 
 // 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", {});
+if (false) {
+  // const { targetFromURL } = require("devtools/client/framework/target-from-url");
+  // const { attachThread } = require("devtools/client/framework/attach-thread");
+  // const { BrowserLoader } = require("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");
+  // 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 notImplemented = function () {
       throw new Error("Not implemented in a tab");
     };
     let fakeToolbox = {
@@ -1945,8 +1944,76 @@ if (url.search.length > 1) {
     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);
   });
 }
+
+window.buildFakeToolbox = Task.async(function* (target) {
+
+  const { InspectorFront } = require("devtools/shared/fronts/inspector");
+  const { Selection } = require("devtools/client/framework/selection");
+  const React = require("devtools/client/shared/vendor/react");
+  const ReactDOM = require("devtools/client/shared/vendor/react-dom");
+  const { getHighlighterUtils } = require("devtools/client/framework/toolbox-highlighter-utils");
+
+  let notImplemented = function () {
+    throw new Error("Not implemented in a tab");
+  };
+  let fakeToolbox = {
+    target,
+    hostType: "bottom",
+    doc: window.document,
+    win: window,
+    on() {}, emit() {}, off() {},
+    initInspector() {},
+    get browserRequire() {
+      //
+    },
+    React: React,
+    ReactDOM: ReactDOM,
+    isToolRegistered() {
+      return false;
+    },
+    currentToolId: "inspector",
+    getCurrentPanel() {
+      return "inspector";
+    },
+    get textboxContextMenuPopup() {
+      notImplemented();
+    },
+    getPanel: notImplemented,
+    openSplitConsole: notImplemented,
+    viewCssSourceInStyleEditor: notImplemented,
+    viewJsSourceInDebugger: notImplemented,
+    viewSource: notImplemented,
+    viewSourceInDebugger: notImplemented,
+    viewSourceInStyleEditor: notImplemented,
+
+    // For attachThread:
+    highlightTool() {},
+    unhighlightTool() {},
+    selectTool() {},
+    raise() {},
+    getNotificationBox() {}
+  };
+  fakeToolbox.threadClient = {paused: false};
+
+  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.highlighterUtils = getHighlighterUtils(fakeToolbox);
+
+  fakeToolbox.inspector = inspector;
+  fakeToolbox.walker = walker;
+  fakeToolbox.selection = selection;
+  fakeToolbox.highlighter = highlighter;
+  // fakeToolbox.highlighterUtils = getHighlighterUtils(fakeToolbox);
+  return fakeToolbox;
+});
+
+window.Inspector = Inspector;
--- a/devtools/client/inspector/inspector.xhtml
+++ b/devtools/client/inspector/inspector.xhtml
@@ -1,105 +1,115 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/inspector.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/rules.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/computed.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/fonts.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/boxmodel.css" type="text/css"?>
-<?xml-stylesheet href="chrome://devtools/skin/animationinspector.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/shared/components/sidebar-toggle.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/shared/components/tabs/tabs.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/shared/components/tabs/tabbar.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/inspector/components/side-panel.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/inspector/components/inspector-tab-panel.css" type="text/css"?>
-<?xml-stylesheet href="resource://devtools/client/shared/components/splitter/split-box.css" type="text/css"?>
-
 <!DOCTYPE html>
 
-<html xmlns="http://www.w3.org/1999/xhtml" dir="">
+<html xmlns="http://www.w3.org/1999/xhtml" dir="" class="theme-light" platform="mac">
 <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>
+  let appendScriptTag = function (src) {
+    let script = document.createElement("script");
+    script.setAttribute("type", "application/javascript;version=1.8");
+    script.setAttribute("defer", "true");
+    script.src = src;
+    document.head.appendChild(script);
+  };
+
   let loadInChrome = window.location.href.includes("chrome:");
-  let inspectorScript = document.createElement("script");
-  inspectorScript.setAttribute("type", "application/javascript;version=1.8");
-  inspectorScript.setAttribute("defer", "true");
-
   if (loadInChrome) {
     var Cu = Components.utils;
     var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
-    inspectorScript.src = "inspector.js";
+    appendScriptTag("inspector.js");
   } else {
-    inspectorScript.src = "inspector.bundle.js";
+    appendScriptTag("inspector.bundle.js");
+    appendScriptTag("inspector.html/main.js");
   }
-  document.head.appendChild(inspectorScript);
+  </script>
+
+  <link rel="stylesheet" type="text/css" href="chrome://global/skin/">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/light-theme.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/widgets.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/inspector.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/rules.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/computed.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/fonts.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/boxmodel.css">
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/animationinspector.css">
+  <link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/widgets/widgets.css">
+  <link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/components/sidebar-toggle.css">
+  <link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/components/tabs/tabs.css">
+  <link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/components/tabs/tabbar.css">
+  <link rel="stylesheet" type="text/css" href="resource://devtools/client/inspector/components/inspector-tab-panel.css">
+  <link rel="stylesheet" type="text/css" href="resource://devtools/client/shared/components/splitter/split-box.css">
+  <script type="text/javascript">
+    for (let link of [...document.head.querySelectorAll("link")]) {
+      link.href = link.href.replace(/\w+\:\/\//, "");
+    }
   </script>
 </head>
 <body class="theme-body" role="application">
+  <div id="mount"></div>
   <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">
         <button id="inspector-element-add-button" class="devtools-button"
-                     data-localization="title=inspectorAddNode.label"/>
-        <div class="devtools-toolbar-spacer" />
-        <span id="inspector-searchlabel" />
+                     data-localization="title=inspectorAddNode.label"></button>
+        <div class="devtools-toolbar-spacer"></div>
+        <span id="inspector-searchlabel"></span>
         <div id="inspector-search" class="devtools-searchbox has-clear-btn">
           <input id="inspector-searchbox" class="devtools-searchinput"
                       type="search"
-                      data-localization="placeholder=inspectorSearchHTML.label3"/>
+                      data-localization="placeholder=inspectorSearchHTML.label3"></input>
           <button id="inspector-searchinput-clear" class="devtools-searchinput-clear" tabindex="-1"></button>
         </div>
         <button id="inspector-eyedropper-toggle"
                      data-localization="title=inspector.eyedropper.label"
-                     class="devtools-button command-button-invertable" />
-        <div id="inspector-sidebar-toggle-box" />
+                     class="devtools-button command-button-invertable" ></button>
+        <div id="inspector-sidebar-toggle-box" ></div>
       </div>
-      <div id="markup-box" />
+      <div id="markup-box"></div>
       <div id="inspector-breadcrumbs-toolbar" class="devtools-toolbar">
         <div id="inspector-breadcrumbs" class="breadcrumbs-widget-container"
-                  role="group" data-localization="aria-label=inspector.breadcrumbs.label" tabindex="0" />
+                  role="group" data-localization="aria-label=inspector.breadcrumbs.label" tabindex="0" ></div>
       </div>
     </div>
 
     <!-- Splitter -->
     <div
       xmlns="http://www.w3.org/1999/xhtml"
       id="inspector-splitter-box">
     </div>
 
     <!-- Sidebar Container -->
     <div id="inspector-sidebar-container">
       <div
         xmlns="http://www.w3.org/1999/xhtml"
         id="inspector-sidebar"
-        hidden="true" />
+        hidden="true"></div>
     </div>
 
     <!-- Sidebar panel definitions -->
     <div id="tabpanels" style="visibility:collapse">
       <div id="sidebar-panel-ruleview" class="devtools-monospace theme-sidebar inspector-tabpanel"
                 data-localization-bundle="devtools/locale/inspector.properties">
         <div id="ruleview-toolbar-container" class="devtools-toolbar">
           <div id="ruleview-toolbar">
             <div class="devtools-searchbox has-clear-btn">
               <input id="ruleview-searchbox"
                           class="devtools-filterinput devtools-rule-searchbox"
                           type="search"
-                          data-localization="placeholder=inspector.filterStyles.placeholder"/>
+                          data-localization="placeholder=inspector.filterStyles.placeholder"></input>
               <button id="ruleview-searchinput-clear" class="devtools-searchinput-clear"></button>
             </div>
             <div id="ruleview-command-toolbar">
               <button id="ruleview-add-rule-button" data-localization="title=inspector.addRule.tooltip" class="devtools-button"></button>
               <button id="pseudo-class-panel-toggle" data-localization="title=inspector.togglePseudo.tooltip" class="devtools-button"></button>
             </div>
           </div>
           <div id="pseudo-class-panel" hidden="true">
@@ -124,35 +134,35 @@
                         type="search"
                         data-localization="placeholder=inspector.filterStyles.placeholder"/>
             <button id="computedview-searchinput-clear" class="devtools-searchinput-clear"></button>
           </div>
           <input id="browser-style-checkbox"
                       type="checkbox"
                       class="includebrowserstyles"/>
           <label id="browser-style-checkbox-label" for="browser-style-checkbox"
-                        data-localization="content=inspector.browserStyles.label"/>
+                        data-localization="content=inspector.browserStyles.label"></label>
         </div>
 
         <div id="computedview-container">
           <div id="computedview-container-focusable" tabindex="-1">
             <div id="boxmodel-wrapper" tabindex="0"
               data-localization-bundle="devtools/locale/boxmodel.properties">
               <div id="boxmodel-header">
                 <div id="boxmodel-expander" class="expander theme-twisty expandable" open=""></div>
-                <span data-localization="content=boxmodel.title"/>
+                <span data-localization="content=boxmodel.title"></span>
               </div>
 
               <div id="boxmodel-container">
                 <div id="boxmodel-main">
-                  <span class="boxmodel-legend" data-box="margin" data-localization="content=boxmodel.margin;title=boxmodel.margin"/>
+                  <span class="boxmodel-legend" data-box="margin" data-localization="content=boxmodel.margin;title=boxmodel.margin"></span>
                   <div id="boxmodel-margins" data-box="margin" data-localization="title=boxmodel.margin">
-                    <span class="boxmodel-legend" data-box="border" data-localization="content=boxmodel.border;title=boxmodel.border"/>
+                    <span class="boxmodel-legend" data-box="border" data-localization="content=boxmodel.border;title=boxmodel.border"></span>
                     <div id="boxmodel-borders" data-box="border" data-localization="title=boxmodel.border">
-                      <span class="boxmodel-legend" data-box="padding" data-localization="content=boxmodel.padding;title=boxmodel.padding"/>
+                      <span class="boxmodel-legend" data-box="padding" data-localization="content=boxmodel.padding;title=boxmodel.padding"></span>
                       <div id="boxmodel-padding" data-box="padding" data-localization="title=boxmodel.padding">
                         <div id="boxmodel-content" data-box="content" data-localization="title=boxmodel.content">
                         </div>
                       </div>
                     </div>
                   </div>
 
                   <p class="boxmodel-margin boxmodel-top"><span data-box="margin" class="boxmodel-editable" title="margin-top"></span></p>
@@ -188,17 +198,17 @@
                   <p id="boxmodel-dummy"></p>
                 </div>
               </div>
             </div>
 
             <div id="propertyContainer" class="theme-separator" tabindex="0">
             </div>
 
-            <div id="computedview-no-results" hidden="" data-localization="content=inspector.noProperties"/>
+            <div id="computedview-no-results" hidden="" data-localization="content=inspector.noProperties"></div>
           </div>
         </div>
       </div>
 
       <div id="sidebar-panel-layoutview" class="devtools-monospace theme-sidebar inspector-tabpanel"
            data-localization-bundle="devtools/locale/inspector.properties">
         <div id="layout-root"></div>
       </div>
@@ -207,45 +217,45 @@
                 data-localization-bundle="devtools/locale/font-inspector.properties">
         <div class="devtools-toolbar">
           <div class="devtools-searchbox">
             <input id="font-preview-text-input" class="devtools-textinput" type="search"
                         data-localization="placeholder=fontinspector.previewText"/>
           </div>
           <label id="font-showall" class="theme-link"
                       data-localization="content=fontinspector.seeAll;
-                                         title=fontinspector.seeAll.tooltip"/>
+                                         title=fontinspector.seeAll.tooltip"></label>
         </div>
 
         <div id="font-container">
           <ul id="all-fonts"></ul>
         </div>
 
         <div id="font-template">
           <section class="font">
             <div class="font-preview-container">
               <img class="font-preview"></img>
             </div>
             <div class="font-info">
               <h1 class="font-name"></h1>
-              <span class="font-is-local" data-localization="content=fontinspector.system"/>
-              <span class="font-is-remote" data-localization="content=fontinspector.remote"/>
+              <span class="font-is-local" data-localization="content=fontinspector.system"></span>
+              <span class="font-is-remote" data-localization="content=fontinspector.remote"></span>
               <p class="font-format-url">
                 <input readonly="readonly" class="font-url"></input>
                 <span class="font-format"></span>
               </p>
               <p class="font-css">
-                <span data-localization="content=fontinspector.usedAs"/> "<span class="font-css-name"></span>"
+                <span data-localization="content=fontinspector.usedAs"></span> "<span class="font-css-name"></span>"
               </p>
               <pre class="font-css-code"></pre>
             </div>
           </section>
         </div>
       </div>
 
       <div id="sidebar-panel-animationinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
-        <iframe class="devtools-inspector-tab-frame" />
+        <iframe class="devtools-inspector-tab-frame" ></iframe>
       </div>
     </div>
 
   </div>
 </body>
 </html>
--- a/devtools/client/inspector/markup/markup.xhtml
+++ b/devtools/client/inspector/markup/markup.xhtml
@@ -1,22 +1,28 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- 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/. -->
 <!DOCTYPE html>
 
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" class="theme-light" platform="mac">
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+
+  <link rel="stylesheet" type="text/css" href="chrome://devtools/skin/light-theme.css">
   <link rel="stylesheet" href="chrome://devtools/skin/markup.css" type="text/css"/>
   <link rel="stylesheet" href="chrome://devtools/content/sourceeditor/codemirror/lib/codemirror.css" type="text/css"/>
   <link rel="stylesheet" href="chrome://devtools/content/sourceeditor/codemirror/addon/dialog/dialog.css" type="text/css"/>
   <link rel="stylesheet" href="chrome://devtools/content/sourceeditor/codemirror/mozilla.css" type="text/css"/>
-
+  <script type="text/javascript">
+    for (let link of [...document.head.querySelectorAll("link")]) {
+      link.href = link.href.replace(/\w+\:\/\//, "../");
+    }
+  </script>
   <script type="application/javascript;version=1.8"
           src="chrome://devtools/content/shared/theme-switching.js"></script>
   <script type="application/javascript;version=1.8"
           src="chrome://devtools/content/sourceeditor/codemirror/codemirror.bundle.js"></script>
 
 </head>
 <body class="theme-body devtools-monospace" role="application">
 
--- a/devtools/client/inspector/markup/views/html-editor.js
+++ b/devtools/client/inspector/markup/views/html-editor.js
@@ -52,17 +52,17 @@ function HTMLEditor(htmlDocument) {
   config.extraKeys[ctrl("Enter")] = this.hide;
   config.extraKeys.F2 = this.hide;
   config.extraKeys.Esc = this.hide.bind(this, false);
 
   this.container.addEventListener("click", this.hide, false);
   this.editorInner.addEventListener("click", stopPropagation, false);
   this.editor = new Editor(config);
 
-  this.editor.appendToLocalElement(this.editorInner);
+  // this.editor.appendToLocalElement(this.editorInner);
   this.hide(false);
 }
 
 HTMLEditor.prototype = {
 
   /**
    * Need to refresh position by manually setting CSS values, so this will
    * need to be called on resizes and other sizing changes.
--- a/devtools/client/inspector/rules/views/rule-editor.js
+++ b/devtools/client/inspector/rules/views/rule-editor.js
@@ -113,17 +113,17 @@ RuleEditor.prototype = {
     });
     this.source.addEventListener("click", function () {
       if (this.source.hasAttribute("unselectable")) {
         return;
       }
       let rule = this.rule.domRule;
       this.ruleView.emit("ruleview-linked-clicked", rule);
     }.bind(this));
-    let sourceLabel = this.doc.createElementNS(XUL_NS, "label");
+    let sourceLabel = this.doc.createElementNS(HTML_NS, "span");
     sourceLabel.setAttribute("crop", "center");
     sourceLabel.classList.add("ruleview-rule-source-label");
     this.source.appendChild(sourceLabel);
 
     this.updateSourceLink();
 
     let code = createChild(this.element, "div", {
       class: "ruleview-code"
--- a/devtools/client/inspector/toolsidebar.js
+++ b/devtools/client/inspector/toolsidebar.js
@@ -67,18 +67,18 @@ ToolSidebar.prototype = {
 
   get InspectorTabPanel() {
     return this._toolPanel.InspectorTabPanel;
   },
 
   // Rendering
 
   render: function () {
-    let Tabbar = this.React.createFactory(this.browserRequire(
-      "devtools/client/shared/components/tabs/tabbar"));
+    const TabbarClass = require("devtools/client/shared/components/tabs/tabbar")
+    let Tabbar = this.React.createFactory(TabbarClass);
 
     let sidebar = Tabbar({
       toolbox: this._toolPanel._toolbox,
       showAllTabsMenu: true,
       onSelect: this.handleSelectionChange.bind(this),
     });
 
     this._tabbar = this.ReactDOM.render(sidebar, this._tabbox);
--- a/devtools/client/shared/widgets/MdnDocsWidget.js
+++ b/devtools/client/shared/widgets/MdnDocsWidget.js
@@ -264,21 +264,21 @@ function MdnDocsWidget(tooltipContainer)
     info: tooltipContainer.querySelector(".mdn-property-info"),
     linkToMdn: tooltipContainer.querySelector(".mdn-visit-page")
   };
 
   // get the localized string for the link text
   this.elements.linkToMdn.textContent = L10N.getStr("docsTooltip.visitMDN");
 
   // listen for clicks and open in the browser window instead
-  let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
+  // let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
   this.elements.linkToMdn.addEventListener("click", (e) => {
     e.stopPropagation();
     e.preventDefault();
-    mainWindow.openUILinkIn(e.target.href, "tab");
+    // mainWindow.openUILinkIn(e.target.href, "tab");
     this.emit("visitlink");
   });
 }
 
 exports.MdnDocsWidget = MdnDocsWidget;
 
 MdnDocsWidget.prototype = {
   /**
--- a/devtools/client/shared/widgets/tooltip/TooltipToggle.js
+++ b/devtools/client/shared/widgets/tooltip/TooltipToggle.js
@@ -65,17 +65,17 @@ TooltipToggle.prototype = {
    *          An optional delay (in ms) that will be observed before showing
    *          and before hiding the tooltip. Defaults to DEFAULT_TOGGLE_DELAY.
    *        - {Boolean} interactive
    *          If enabled, the tooltip is not hidden when mouse leaves the
    *          target element and enters the tooltip. Allows the tooltip
    *          content to be interactive.
    */
   start: function (baseNode, targetNodeCb,
-                   {toggleDelay = DEFAULT_TOGGLE_DELAY, interactive = false} = {}) {
+                   {toggleDelay = 50, interactive = false} = {}) {
     this.stop();
 
     if (!baseNode) {
       // Calling tool is in the process of being destroyed.
       return;
     }
 
     this._baseNode = baseNode;
--- a/devtools/client/sourceeditor/editor.js
+++ b/devtools/client/sourceeditor/editor.js
@@ -41,23 +41,23 @@ const L10N = new LocalizationHelper("dev
 
 const { OS } = Services.appinfo;
 
 // CM_STYLES, CM_SCRIPTS and CM_IFRAME represent the HTML,
 // JavaScript and CSS that is injected into an iframe in
 // order to initialize a CodeMirror instance.
 
 const CM_STYLES = [
-  "chrome://devtools/content/sourceeditor/codemirror/lib/codemirror.css",
-  "chrome://devtools/content/sourceeditor/codemirror/addon/dialog/dialog.css",
-  "chrome://devtools/content/sourceeditor/codemirror/mozilla.css"
+  "devtools/content/sourceeditor/codemirror/lib/codemirror.css",
+  "devtools/content/sourceeditor/codemirror/addon/dialog/dialog.css",
+  "devtools/content/sourceeditor/codemirror/mozilla.css"
 ];
 
 const CM_SCRIPTS = [
-  "chrome://devtools/content/sourceeditor/codemirror/codemirror.bundle.js",
+  "devtools/client/sourceeditor/codemirror/codemirror.bundle.js",
 ];
 
 const CM_IFRAME =
   "data:text/html;charset=utf8,<!DOCTYPE html>" +
   "<html dir='ltr'>" +
   "  <head>" +
   "    <style>" +
   "      html, body { height: 100%; }" +
@@ -304,17 +304,17 @@ Editor.prototype = {
    */
   _setup: function (el, doc) {
     doc = doc || el.ownerDocument;
     let win = el.ownerDocument.defaultView;
 
     let scriptsToInject = CM_SCRIPTS.concat(this.config.externalScripts);
     scriptsToInject.forEach(url => {
       if (url.startsWith("chrome://")) {
-        Services.scriptloader.loadSubScript(url, win, "utf8");
+        // Services.scriptloader.loadSubScript(url, win, "utf8");
       }
     });
 
     // Replace the propertyKeywords, colorKeywords and valueKeywords
     // properties of the CSS MIME type with the values provided by the CSS properties
     // database.
     const {
       propertyKeywords,
--- a/devtools/client/themes/inspector.css
+++ b/devtools/client/themes/inspector.css
@@ -82,18 +82,18 @@ window {
 
 #inspector-toolbar.devtools-toolbar .devtools-toolbar-spacer {
   flex-grow: 1;
   display: inline-block;
 }
 
 /* Add element toolbar button */
 #inspector-element-add-button::before {
-  background-image: url("chrome://devtools/skin/images/add.svg");
-  list-style-image: url("chrome://devtools/skin/images/add.svg");
+  background-image: url(images/add.svg);
+  list-style-image: url(images/add.svg);
   -moz-user-focus: normal;
 }
 
 #inspector-searchlabel {
   overflow: hidden;
   margin-inline-end: 2px;
 }
 
--- a/devtools/client/themes/rules.css
+++ b/devtools/client/themes/rules.css
@@ -379,33 +379,33 @@
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   z-index: -1;
 }
 
 .ruleview-bezierswatch {
-  background: url("chrome://devtools/skin/images/cubic-bezier-swatch.png");
+  background: url(images/cubic-bezier-swatch.png);
   background-size: 1em;
 }
 
 .ruleview-filterswatch {
-  background: url("chrome://devtools/skin/images/filter-swatch.svg");
+  background: url(images/filter-swatch.svg);
   background-size: 1em;
 }
 
 .ruleview-angleswatch {
-  background: url("chrome://devtools/skin/images/angle-swatch.svg");
+  background: url(images/angle-swatch.svg);
   background-size: 1em;
 }
 
 @media (min-resolution: 1.1dppx) {
   .ruleview-bezierswatch {
-    background: url("chrome://devtools/skin/images/cubic-bezier-swatch@2x.png");
+    background: url(images/cubic-bezier-swatch@2x.png);
     background-size: 1em;
   }
 }
 
 .ruleview-overridden {
   text-decoration: line-through;
 }
 
@@ -476,38 +476,38 @@
 
 .theme-firebug .ruleview-selector > .ruleview-selector-matched,
 .theme-firebug .ruleview-selector > .ruleview-selector-separator,
 .theme-firebug .ruleview-selector > .ruleview-selector-unmatched {
   color: inherit;
 }
 
 .ruleview-selectorhighlighter {
-  background: url("chrome://devtools/skin/images/vview-open-inspector.png") no-repeat 0 0;
+  background: url(images/vview-open-inspector.png) no-repeat 0 0;
   padding-left: 16px;
   margin-left: 5px;
   cursor: pointer;
 }
 
 .ruleview-selectorhighlighter:hover {
   filter: url(images/filters.svg#checked-icon-state);
 }
 
 .ruleview-selectorhighlighter:active,
 .ruleview-selectorhighlighter.highlighted {
   filter: url(images/filters.svg#checked-icon-state) brightness(0.9);
 }
 
 #ruleview-add-rule-button::before {
-  background-image: url("chrome://devtools/skin/images/add.svg");
+  background-image: url(images/add.svg);
   background-size: cover;
 }
 
 #pseudo-class-panel-toggle::before {
-  background-image: url("chrome://devtools/skin/images/pseudo-class.svg");
+  background-image: url(images/pseudo-class.svg);
   background-size: cover;
 }
 
 .ruleview-overridden-rule-filter {
   opacity: 0.8;
 }
 .ruleview-overridden-rule-filter:hover {
   opacity: 1;
@@ -518,17 +518,17 @@
 }
 
 /* Firebug theme disable/enable CSS rule. Firebug theme uses its own
   icons to indicate when CSS rules can be disabled or enabled. */
 
 .theme-firebug .ruleview-rule .theme-checkbox {
   background-repeat: no-repeat;
   background-size: 12px 12px;
-  background-image: url(chrome://devtools/skin/images/firebug/disable.svg);
+  background-image: url(images/firebug/disable.svg);
   background-position: 0 0;
 }
 
 .theme-firebug .ruleview-rule .theme-checkbox:not([checked]){
   filter: grayscale(1);
 }
 
 .theme-firebug .ruleview-rule .theme-checkbox[checked] {
--- a/devtools/client/webpack.config.js
+++ b/devtools/client/webpack.config.js
@@ -40,17 +40,17 @@ module.exports = [{
     library: "CodeMirror",
   },
 }, {
   bail: true,
 
   entry: './inspector/inspector.js',
   output: {
     filename: './inspector/inspector.bundle.js',
-    library: 'Inspector',
+    library: 'InspectorBundle',
   },
   module: {
     // Disable handling of unknown requires
     unknownContextRegExp: /$^/,
     unknownContextCritical: false,
 
     // Disable handling of requires with a single expression
     exprContextRegExp: /$^/,
@@ -91,17 +91,17 @@ module.exports = [{
     },
   },
 
   plugins: [
     new webpack.DefinePlugin({
       "isWorker": JSON.stringify(false),
       "reportError": "console.error",
       "AppConstants": "{ DEBUG: true, DEBUG_JS_MODULES: true }",
-      "loader": "{ lazyRequireGetter: () => {} }",
+      "loader": "{ lazyRequireGetter: () => {}, lazyGetter: () => {} }",
       "dump": "console.log",
     }),
   ],
 
   externals: [
     /codemirror\//,
     {
       "promise": "var Promise",