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

--HG--
extra : rebase_source : a58f03898c5eeabfb7b43052e7f65d715c3a5b1e
This commit is contained in:
Andrew McCreight 2017-03-28 11:32:34 -07:00
Родитель 6c3486e2e6
Коммит cb4bfc4017
3 изменённых файлов: 96 добавлений и 123 удалений

Просмотреть файл

@ -6,6 +6,7 @@
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cm = Components.manager;
const Cr = Components.results;
@ -26,11 +27,6 @@ XPCOMUtils.defineLazyGetter(this, "JsonViewService", function () {
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";
@ -39,6 +35,80 @@ const JSON_VIEW_CONTRACT_ID = "@mozilla.org/streamconv;1?from=" +
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
@ -98,9 +168,19 @@ ConverterObserver.prototype = {
},
register: function () {
JsonViewSniffer.register();
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,
@ -110,9 +190,16 @@ ConverterObserver.prototype = {
},
unregister: function () {
JsonViewSniffer.unregister();
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);
}

Просмотреть файл

@ -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
};

Просмотреть файл

@ -13,7 +13,6 @@ DIRS += [
DevToolsModules(
'converter-child.js',
'converter-observer.js',
'converter-sniffer.js',
'json-viewer.js',
'main.js',
'utils.js',