Bug 1359855 - Inline jsonview main module to keep it working before user action. r=Honza,jdescottes
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 13 Jul 2017 15:33:38 +0200
changeset 419348 469ff13c773da7290d92c81f922c2a5a4de3cdb5
parent 419347 ef8587aca0585647617db2c25d24c68620a46c2e
child 419349 eb206956401ce32a0a4117244f44839a54a261d7
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')