Bug 1351385, part 4 - Move the JSON sniffer out of its own file. r=Honza
The sniffer is always run. By moving it out of its own file we can
avoid importing the devtools loader system at startup, which uses a
number of compartments.
MozReview-Commit-ID: IoMIzZeRDo2
--- a/devtools/client/jsonview/converter-observer.js
+++ b/devtools/client/jsonview/converter-observer.js
@@ -1,16 +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 = Components.classes;
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", {});
@@ -21,29 +22,98 @@ XPCOMUtils.defineLazyGetter(this, "devto
});
// Load JsonView services lazily.
XPCOMUtils.defineLazyGetter(this, "JsonViewService", function () {
const {JsonViewService} = devtools.require("devtools/client/jsonview/converter-child");
return JsonViewService;
});
-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";
+const JSON_SNIFFER_CONTRACT_ID = "@mozilla.org/devtools/jsonview-sniffer;1";
+const JSON_SNIFFER_CLASS_ID = Components.ID("{4148c488-dca1-49fc-a621-2a0097a62422}");
+const JSON_SNIFFER_CLASS_DESCRIPTION = "JSONView content sniffer";
+const JSON_VIEW_TYPE = "JSON View";
+const CONTENT_SNIFFER_CATEGORY = "net-content-sniffers";
+
+/**
+ * This component represents a sniffer (implements nsIContentSniffer
+ * interface) responsible for changing top level 'application/json'
+ * document types to: 'application/vnd.mozilla.json.view'.
+ *
+ * This internal type is consequently rendered by JSON View component
+ * that represents the JSON through a viewer interface.
+ *
+ * This is done in the .js file rather than a .jsm to avoid creating
+ * a compartment at startup when no JSON is being viewed.
+ */
+function JsonViewSniffer() {}
+
+JsonViewSniffer.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentSniffer]),
+
+ get wrappedJSObject() {
+ return this;
+ },
+
+ isTopLevelLoad: function (request) {
+ let loadInfo = request.loadInfo;
+ if (loadInfo && loadInfo.isTopLevelLoad) {
+ return (request.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI);
+ }
+ return false;
+ },
+
+ getMIMETypeFromContent: function (request, data, length) {
+ if (request instanceof Ci.nsIChannel) {
+ // JSON View is enabled only for top level loads only.
+ if (!this.isTopLevelLoad(request)) {
+ return "";
+ }
+ try {
+ if (request.contentDisposition ==
+ Ci.nsIChannel.DISPOSITION_ATTACHMENT) {
+ return "";
+ }
+ } catch (e) {
+ // Channel doesn't support content dispositions
+ }
+
+ // Check the response content type and if it's a valid type
+ // such as application/json or application/manifest+json
+ // change it to new internal type consumed by JSON View.
+ const JSON_TYPES = ["application/json", "application/manifest+json"];
+ if (JSON_TYPES.includes(request.contentType)) {
+ return JSON_VIEW_MIME_TYPE;
+ }
+ }
+
+ return "";
+ }
+};
+
+/*
+ * Create instances of the JSON view sniffer.
+ */
+const JsonSnifferFactory = {
+ createInstance: function (outer, iid) {
+ if (outer) {
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ }
+ return new JsonViewSniffer();
+ }
+};
+
/*
* 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) {
@@ -93,31 +163,48 @@ ConverterObserver.prototype = {
if (this.isEnabled()) {
this.register();
} else {
this.unregister();
}
},
register: function () {
- JsonViewSniffer.register();
+ const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
- const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+ if (!registrar.isCIDRegistered(JSON_SNIFFER_CLASS_ID)) {
+ registrar.registerFactory(JSON_SNIFFER_CLASS_ID,
+ JSON_SNIFFER_CLASS_DESCRIPTION,
+ JSON_SNIFFER_CONTRACT_ID,
+ JsonSnifferFactory);
+ const categoryManager = Cc["@mozilla.org/categorymanager;1"]
+ .getService(Ci.nsICategoryManager);
+ categoryManager.addCategoryEntry(CONTENT_SNIFFER_CATEGORY, JSON_VIEW_TYPE,
+ JSON_SNIFFER_CONTRACT_ID, false, false);
+ }
+
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();
+ const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
- const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+ if (registrar.isCIDRegistered(JSON_SNIFFER_CLASS_ID)) {
+ registrar.unregisterFactory(JSON_SNIFFER_CLASS_ID, JsonSnifferFactory);
+ const categoryManager = Cc["@mozilla.org/categorymanager;1"]
+ .getService(Ci.nsICategoryManager);
+ categoryManager.deleteCategoryEntry(CONTENT_SNIFFER_CATEGORY,
+ JSON_VIEW_TYPE, false);
+ }
+
if (registrar.isCIDRegistered(JSON_VIEW_CLASS_ID)) {
registrar.unregisterFactory(JSON_VIEW_CLASS_ID, JsonViewFactory);
}
},
isEnabled: function () {
return Services.prefs.getBoolPref(JSON_VIEW_PREF);
},
deleted file mode 100644
--- a/devtools/client/jsonview/converter-sniffer.js
+++ /dev/null
@@ -1,113 +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 {Cc, Ci, Cu, Cm, Cr, components} = require("chrome");
-const registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-
-const categoryManager = Cc["@mozilla.org/categorymanager;1"]
- .getService(Ci.nsICategoryManager);
-
-// Constants
-const JSON_TYPES = ["application/json", "application/manifest+json"];
-const JSON_SNIFFER_CONTRACT_ID = "@mozilla.org/devtools/jsonview-sniffer;1";
-const JSON_SNIFFER_CLASS_ID = components.ID("{4148c488-dca1-49fc-a621-2a0097a62422}");
-const JSON_SNIFFER_CLASS_DESCRIPTION = "JSONView content sniffer";
-const JSON_VIEW_MIME_TYPE = "application/vnd.mozilla.json.view";
-const JSON_VIEW_TYPE = "JSON View";
-const CONTENT_SNIFFER_CATEGORY = "net-content-sniffers";
-
-function isTopLevelLoad(request) {
- let loadInfo = request.loadInfo;
- if (loadInfo && loadInfo.isTopLevelLoad) {
- return (request.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI);
- }
- return false;
-}
-
-/**
- * This component represents a sniffer (implements nsIContentSniffer
- * interface) responsible for changing top level 'application/json'
- * document types to: 'application/vnd.mozilla.json.view'.
- *
- * This internal type is consequently rendered by JSON View component
- * that represents the JSON through a viewer interface.
- */
-function JsonSniffer() {}
-
-JsonSniffer.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentSniffer]),
-
- get wrappedJSObject() {
- return this;
- },
-
- getMIMETypeFromContent: function (request, data, length) {
- if (request instanceof Ci.nsIChannel) {
- // JSON View is enabled only for top level loads only.
- if (!isTopLevelLoad(request)) {
- return "";
- }
- try {
- if (request.contentDisposition ==
- Ci.nsIChannel.DISPOSITION_ATTACHMENT) {
- return "";
- }
- } catch (e) {
- // Channel doesn't support content dispositions
- }
-
- // Check the response content type and if it's a valid type
- // such as application/json or application/manifest+json
- // change it to new internal type consumed by JSON View.
- if (JSON_TYPES.includes(request.contentType)) {
- return JSON_VIEW_MIME_TYPE;
- }
- }
-
- return "";
- }
-};
-
-const JsonSnifferFactory = {
- createInstance: function (outer, iid) {
- if (outer) {
- throw Cr.NS_ERROR_NO_AGGREGATION;
- }
- return new JsonSniffer();
- }
-};
-
-function register() {
- if (!registrar.isCIDRegistered(JSON_SNIFFER_CLASS_ID)) {
- registrar.registerFactory(JSON_SNIFFER_CLASS_ID,
- JSON_SNIFFER_CLASS_DESCRIPTION,
- JSON_SNIFFER_CONTRACT_ID,
- JsonSnifferFactory);
- categoryManager.addCategoryEntry(CONTENT_SNIFFER_CATEGORY, JSON_VIEW_TYPE,
- JSON_SNIFFER_CONTRACT_ID, false, false);
- return true;
- }
-
- return false;
-}
-
-function unregister() {
- if (registrar.isCIDRegistered(JSON_SNIFFER_CLASS_ID)) {
- registrar.unregisterFactory(JSON_SNIFFER_CLASS_ID, JsonSnifferFactory);
- categoryManager.deleteCategoryEntry(CONTENT_SNIFFER_CATEGORY,
- JSON_VIEW_TYPE, false);
- return true;
- }
- return false;
-}
-
-exports.JsonViewSniffer = {
- register: register,
- unregister: unregister
-};
--- a/devtools/client/jsonview/moz.build
+++ b/devtools/client/jsonview/moz.build
@@ -8,17 +8,16 @@ DIRS += [
'components',
'css',
'lib'
]
DevToolsModules(
'converter-child.js',
'converter-observer.js',
- 'converter-sniffer.js',
'json-viewer.js',
'main.js',
'utils.js',
'viewer-config.js'
)
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']