Bug 1359855 - Inline jsonview main module to keep it working before user action. r=Honza,jdescottes
☠☠ backed out by d80f56061436 ☠ ☠
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 13 Jul 2017 15:33:38 +0200
changeset 419239 354080a171dc88a363e22dd473d56762b9d88bfb
parent 419238 44726932185aa82dbab1cea9a4b4bdc727f8fd5e
child 419240 8d68726f1c34cc18155d3be298611abd82fa3c21
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza, jdescottes
bugs1359855
milestone56.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 1359855 - Inline jsonview main module to keep it working before user action. r=Honza,jdescottes MozReview-Commit-ID: 3COOvQtYn0E
devtools/client/devtools-startup.js
devtools/client/framework/devtools.js
devtools/client/jsonview/main.js
devtools/client/jsonview/moz.build
--- a/devtools/client/devtools-startup.js
+++ b/devtools/client/devtools-startup.js
@@ -188,16 +188,17 @@ DevToolsStartup.prototype = {
       this.hookWindow(window);
 
       if (devtoolsFlag) {
         this.handleDevToolsFlag(window);
         // This listener is called for all Firefox windows, but we want to execute
         // that command only once
         devtoolsFlag = false;
       }
+      JsonView.initialize();
     };
     Services.obs.addObserver(onWindowReady, "browser-delayed-startup-finished");
   },
 
   /**
    * Register listeners to all possible entry points for Developer Tools.
    * But instead of implementing the actual actions, defer to DevTools codebase.
    * In most cases, it only needs to call this.initDevTools which handles the rest.
@@ -522,10 +523,72 @@ DevToolsStartup.prototype = {
             "                     a TCP port or Unix domain socket path. Defaults to TCP port\n" +
             "                     6000. Use WebSocket protocol if ws: prefix is specified.\n",
   /* eslint-disable max-len */
 
   classID: Components.ID("{9e9a9283-0ce9-4e4a-8f1c-ba129a032c32}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
 };
 
+/**
+ * Singleton object that represents the JSON View in-content tool.
+ * It has the same lifetime as the browser.
+ */
+const JsonView = {
+  initialized: false,
+
+  initialize: function () {
+    // Prevent loading the frame script multiple times if we call this more than once.
+    if (this.initialized) {
+      return;
+    }
+    this.initialized = true;
+
+    // Load JSON converter module. This converter is responsible
+    // for handling 'application/json' documents and converting
+    // them into a simple web-app that allows easy inspection
+    // of the JSON data.
+    Services.ppmm.loadProcessScript(
+      "resource://devtools/client/jsonview/converter-observer.js",
+      true);
+
+    // Register for messages coming from the child process.
+    // This is never removed as there is no particular need to unregister
+    // it during shutdown.
+    Services.ppmm.addMessageListener(
+      "devtools:jsonview:save", this.onSave);
+  },
+
+  // Message handlers for events from child processes
+
+  /**
+   * Save JSON to a file needs to be implemented here
+   * in the parent process.
+   */
+  onSave: function (message) {
+    let chrome = Services.wm.getMostRecentWindow("navigator:browser");
+    let browser = chrome.gBrowser.selectedBrowser;
+    if (message.data.url === null) {
+      // Save original contents
+      chrome.saveBrowser(browser, false, message.data.windowID);
+    } else {
+      // The following code emulates saveBrowser, but:
+      // - Uses the given blob URL containing the custom contents to save.
+      // - Obtains the file name from the URL of the document, not the blob.
+      let persistable = browser.QueryInterface(Ci.nsIFrameLoaderOwner)
+        .frameLoader.QueryInterface(Ci.nsIWebBrowserPersistable);
+      persistable.startPersistence(message.data.windowID, {
+        onDocumentReady(doc) {
+          let uri = chrome.makeURI(doc.documentURI, doc.characterSet);
+          let filename = chrome.getDefaultFileName(undefined, uri, doc, null);
+          chrome.internalSave(message.data.url, doc, filename, null, doc.contentType,
+            false, null, null, null, doc, false, null, undefined);
+        },
+        onError(status) {
+          throw new Error("JSON Viewer's onSave failed in startPersistence");
+        }
+      });
+    }
+  }
+};
+
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
   [DevToolsStartup]);
--- a/devtools/client/framework/devtools.js
+++ b/devtools/client/framework/devtools.js
@@ -19,17 +19,16 @@ loader.lazyImporter(this, "ScratchpadMan
 // Dependencies required for addon sdk compatibility layer.
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
 loader.lazyImporter(this, "BrowserToolboxProcess", "resource://devtools/client/framework/ToolboxProcess.jsm");
 
 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 {Task} = require("devtools/shared/task");
 const {getTheme, setTheme, addThemeObserver, removeThemeObserver} =
   require("devtools/client/shared/theme");
 
 const FORBIDDEN_IDS = new Set(["toolbox", ""]);
 const MAX_ORDINAL = 99;
 
@@ -39,19 +38,16 @@ const MAX_ORDINAL = 99;
  */
 function DevTools() {
   this._tools = new Map();     // Map<toolId, tool>
   this._themes = new Map();    // Map<themeId, theme>
   this._toolboxes = new Map(); // Map<target, toolbox>
   // List of toolboxes that are still in process of creation
   this._creatingToolboxes = new Map(); // Map<target, toolbox Promise>
 
-  // JSON Viewer for 'application/json' documents.
-  JsonView.initialize();
-
   AboutDevTools.register();
 
   EventEmitter.decorate(this);
 
   // Listen for changes to the theme pref.
   this._onThemeChanged = this._onThemeChanged.bind(this);
   addThemeObserver(this._onThemeChanged);
 
@@ -639,18 +635,16 @@ DevTools.prototype = {
       }
       AboutDevTools.unregister();
     }
 
     for (let [key, ] of this.getToolDefinitionMap()) {
       this.unregisterTool(key, true);
     }
 
-    JsonView.destroy();
-
     gDevTools.unregisterDefaults();
 
     removeThemeObserver(this._onThemeChanged);
 
     // Do not unregister devtools from the DevToolsShim if the destroy is caused by an
     // application shutdown. For instance SessionStore needs to save the Scratchpad
     // manager state on shutdown.
     if (!shuttingDown) {
deleted file mode 100644
--- a/devtools/client/jsonview/main.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- 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 { Ci } = require("chrome");
-const Services = require("Services");
-
-/**
- * Singleton object that represents the JSON View in-content tool.
- * It has the same lifetime as the browser. Initialization done by
- * DevTools() object from devtools/client/framework/devtools.js
- */
-var JsonView = {
-  initialize: function () {
-    // Load JSON converter module. This converter is responsible
-    // for handling 'application/json' documents and converting
-    // them into a simple web-app that allows easy inspection
-    // of the JSON data.
-    Services.ppmm.loadProcessScript(
-      "resource://devtools/client/jsonview/converter-observer.js",
-      true);
-
-    // Register for messages coming from the child process.
-    Services.ppmm.addMessageListener(
-      "devtools:jsonview:save", this.onSave);
-  },
-
-  destroy: function () {
-    Services.ppmm.removeMessageListener(
-      "devtools:jsonview:save", this.onSave);
-  },
-
-  // Message handlers for events from child processes
-
-  /**
-   * Save JSON to a file needs to be implemented here
-   * in the parent process.
-   */
-  onSave: function (message) {
-    let chrome = Services.wm.getMostRecentWindow("navigator:browser");
-    let browser = chrome.gBrowser.selectedBrowser;
-    if (message.data.url === null) {
-      // Save original contents
-      chrome.saveBrowser(browser, false, message.data.windowID);
-    } else {
-      // The following code emulates saveBrowser, but:
-      // - Uses the given blob URL containing the custom contents to save.
-      // - Obtains the file name from the URL of the document, not the blob.
-      let persistable = browser.QueryInterface(Ci.nsIFrameLoaderOwner)
-        .frameLoader.QueryInterface(Ci.nsIWebBrowserPersistable);
-      persistable.startPersistence(message.data.windowID, {
-        onDocumentReady(doc) {
-          let uri = chrome.makeURI(doc.documentURI, doc.characterSet);
-          let filename = chrome.getDefaultFileName(undefined, uri, doc, null);
-          chrome.internalSave(message.data.url, doc, filename, null, doc.contentType,
-            false, null, null, null, doc, false, null, undefined);
-        },
-        onError(status) {
-          throw new Error("JSON Viewer's onSave failed in startPersistence");
-        }
-      });
-    }
-  }
-};
-
-// Exports from this module
-module.exports.JsonView = JsonView;
--- a/devtools/client/jsonview/moz.build
+++ b/devtools/client/jsonview/moz.build
@@ -9,16 +9,15 @@ DIRS += [
     'css',
     'lib'
 ]
 
 DevToolsModules(
     'converter-child.js',
     'converter-observer.js',
     'json-viewer.js',
-    'main.js',
     'viewer-config.js'
 )
 
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'Developer Tools: JSON Viewer')