Bug 1351385, part 2 - Lazily load JsonViewService. r=Honza draft
authorAndrew McCreight <continuation@gmail.com>
Tue, 28 Mar 2017 09:13:05 -0700
changeset 553743 3d2e225c8ee1a82f7c7fdd16c9193e73729a3e3b
parent 553221 d257ad6ed35b3cc7ca436c4e59d17fd3bbfe8d8c
child 553744 0ec522ded57624593b2388370fa3d290ebc6a4f6
push id51748
push userbmo:continuation@gmail.com
push dateThu, 30 Mar 2017 15:33:10 +0000
reviewersHonza
bugs1351385
milestone55.0a1
Bug 1351385, part 2 - Lazily load JsonViewService. r=Honza This avoids triggering the devtools loading system just to register a factory. MozReview-Commit-ID: BVMfCRlG9kv
devtools/client/jsonview/converter-child.js
devtools/client/jsonview/converter-observer.js
--- a/devtools/client/jsonview/converter-child.js
+++ b/devtools/client/jsonview/converter-child.js
@@ -1,18 +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 {Cc, Ci, Cu, Cm, Cr, components} = require("chrome");
-const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+const {Cc, Ci, Cu} = require("chrome");
 const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
 const Services = require("Services");
 
 loader.lazyRequireGetter(this, "NetworkHelper",
                                "devtools/shared/webconsole/network-helper");
 loader.lazyRequireGetter(this, "Events",
                                "sdk/dom/events");
 loader.lazyRequireGetter(this, "Clipboard",
@@ -23,22 +22,16 @@ loader.lazyRequireGetter(this, "JsonView
 const childProcessMessageManager =
   Cc["@mozilla.org/childprocessmessagemanager;1"]
     .getService(Ci.nsISyncMessageSender);
 
 // Amount of space that will be allocated for the stream's backing-store.
 // Must be power of 2. Used to copy the data stream in onStopRequest.
 const SEGMENT_SIZE = Math.pow(2, 17);
 
-const JSON_VIEW_MIME_TYPE = "application/vnd.mozilla.json.view";
-const JSON_VIEW_CONTRACT_ID = "@mozilla.org/streamconv;1?from=" +
-  JSON_VIEW_MIME_TYPE + "&to=*/*";
-const JSON_VIEW_CLASS_ID = components.ID("{d8c9acee-dec5-11e4-8c75-1681e6b88ec1}");
-const JSON_VIEW_CLASS_DESCRIPTION = "JSONView converter";
-
 // Localization
 loader.lazyGetter(this, "jsonViewStrings", () => {
   return Services.strings.createBundle(
     "chrome://devtools/locale/jsonview.properties");
 });
 
 /**
  * This object detects 'application/vnd.mozilla.json.view' content type
@@ -326,41 +319,11 @@ Converter.prototype = {
     Clipboard.set(value, "text");
   }
 };
 
 function createInstance() {
   return new Converter();
 }
 
-const JsonViewFactory = {
-  createInstance: function (outer, iid) {
-    if (outer) {
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    }
-    return createInstance();
-  }
+exports.JsonViewService = {
+  createInstance: createInstance,
 };
-
-function register() {
-  if (!registrar.isCIDRegistered(JSON_VIEW_CLASS_ID)) {
-    registrar.registerFactory(JSON_VIEW_CLASS_ID,
-      JSON_VIEW_CLASS_DESCRIPTION,
-      JSON_VIEW_CONTRACT_ID,
-      JsonViewFactory);
-    return true;
-  }
-
-  return false;
-}
-
-function unregister() {
-  if (registrar.isCIDRegistered(JSON_VIEW_CLASS_ID)) {
-    registrar.unregisterFactory(JSON_VIEW_CLASS_ID, JsonViewFactory);
-    return true;
-  }
-  return false;
-}
-
-exports.JsonViewService = {
-  register: register,
-  unregister: unregister
-};
--- a/devtools/client/jsonview/converter-observer.js
+++ b/devtools/client/jsonview/converter-observer.js
@@ -1,16 +1,19 @@
 /* -*- 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 = Components.interfaces;
+const Cm = Components.manager;
+const Cr = Components.results;
 const Cu = Components.utils;
 
 const {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
 const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
 
 // Load devtools module lazily.
 XPCOMUtils.defineLazyGetter(this, "devtools", function () {
   const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
@@ -25,16 +28,35 @@ XPCOMUtils.defineLazyGetter(this, "JsonV
 
 XPCOMUtils.defineLazyGetter(this, "JsonViewSniffer", function () {
   const {JsonViewSniffer} = devtools.require("devtools/client/jsonview/converter-sniffer");
   return JsonViewSniffer;
 });
 
 // Constants
 const JSON_VIEW_PREF = "devtools.jsonview.enabled";
+const JSON_VIEW_MIME_TYPE = "application/vnd.mozilla.json.view";
+const JSON_VIEW_CONTRACT_ID = "@mozilla.org/streamconv;1?from=" +
+  JSON_VIEW_MIME_TYPE + "&to=*/*";
+const JSON_VIEW_CLASS_ID = Components.ID("{d8c9acee-dec5-11e4-8c75-1681e6b88ec1}");
+const JSON_VIEW_CLASS_DESCRIPTION = "JSONView converter";
+
+/*
+ * Create instances of the JSON view converter.
+ * This is done in the .js file rather than a .jsm to avoid creating
+ * a compartment at startup when no JSON is being viewed.
+ */
+const JsonViewFactory = {
+  createInstance: function (outer, iid) {
+    if (outer) {
+      throw Cr.NS_ERROR_NO_AGGREGATION;
+    }
+    return JsonViewService.createInstance();
+  }
+};
 
 /**
  * Listen for 'devtools.jsonview.enabled' preference changes and
  * register/unregister the JSON View XPCOM services as appropriate.
  */
 function ConverterObserver() {
 }
 
@@ -72,22 +94,33 @@ ConverterObserver.prototype = {
       this.register();
     } else {
       this.unregister();
     }
   },
 
   register: function () {
     JsonViewSniffer.register();
-    JsonViewService.register();
+
+    const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    if (!registrar.isCIDRegistered(JSON_VIEW_CLASS_ID)) {
+      registrar.registerFactory(JSON_VIEW_CLASS_ID,
+        JSON_VIEW_CLASS_DESCRIPTION,
+        JSON_VIEW_CONTRACT_ID,
+        JsonViewFactory);
+    }
   },
 
   unregister: function () {
     JsonViewSniffer.unregister();
-    JsonViewService.unregister();
+
+    const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    if (registrar.isCIDRegistered(JSON_VIEW_CLASS_ID)) {
+      registrar.unregisterFactory(JSON_VIEW_CLASS_ID, JsonViewFactory);
+    }
   },
 
   isEnabled: function () {
     return Services.prefs.getBoolPref(JSON_VIEW_PREF);
   },
 };
 
 // Listen to JSON View 'enable' pref and perform dynamic