I have a bootstrapped extension for Firefox.
And now I want to implement nsIContentPolicy XPCOM component.
I wrote a component module code.
And now I want to register this component.
The reason I want to register component is that I want to add my component to nsICategoryManager.addCategoryEntry
with "content-policy" category.
var {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
//console.error("Running interceptor");
function Interceptor()
}
Interceptor.prototype = {
classDescription: "DeferredTo HTTP requests Interceptor",
classID: "{B5B3D9A0-08FC-11E3-8253-5EF06188709B}",
contractID: "@deferredto.com/Interceptor;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]),
shouldLoad : function dt_shouldLoad(aContentType, aContentLocation, aRequestOrigin, aContext, aMimeTypeGuess, aExtra) {
console.log("dt_shouldLoad");
if (contentLocation.scheme != "http" && contentLocation.scheme != "https")
return Ci.nsIContentPolicy.ACCEPT;
let result = Ci.nsIContentPolicy.ACCEPT;
// we should check for TYPE_SUBDOCUMENT as well if we want frames.
if ((Ci.nsIContentPolicy.TYPE_DOCUMENT == aContentType) &&
SOME_REGULAR_EXPRESSION.test(aContentLocation.spec)) {
// do stuff here, possibly changing result.
}
return result;
},
shouldProcess: function ILO_shouldProcess() Ci.nsIContentPolicy.ACCEPT,
_xpcom_categories: [
{ category: "content-policy", service: true }
],
classInfo: XPCOMUtils.generateCI(
{classID: Components.ID("{B5B3D9A0-08FC-11E3-8253-5EF06188709B}"),
contractID: "@deferredto.com/Interceptor;1",
classDescription: "Interceptor implements nsIContentPolicy to block images that are not yet at screen @DeferredTo",
interfaces: [
Ci.nsIContentPolicy,
],
flags: Ci.nsIClassInfo.SINGLETON})
}
var components = [Interceptor];
var NSGetFactory = XPCOMUtils.generateNSGetFactory([Interceptor]);
Questions:
I've added to harness-options.js
"requirements": {
"sdk/page-mod": "sdk/page-mod",
"sdk/self": "sdk/self",
"chrome": "chrome"},
That is how I try to import module:
var {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://deferredto/lib/interceptor.js");
I' ve tried many paths ))) But none works. resource entry in chrome.manifest file does not allowed for bootstrapped extensions. The path to component module file is:
resources/deferredto/lib/interceptor.js
Adblock Plus, which is restartless but not using the SDK, registers an nsIContentPolicy
implementation at runtime, just like your SDK would. There are probably a few SDK add-ons registering components at run time, but I don't know any open source ones that I would recommend to look at off the top of my head.
A few points regarding that ABP implementation and what to change to make it work with the SDK:
Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)
.components
from the chrome
module and then components.manager.getService(Ci.nsIComponentRegistrar)
.Util.runAsync
, which just dispatches a runnable (event, if you like) to the main thread. I don't think you can use any SDK stuff here, as the SDK will clean up before any async code gets a chance to run, so you'd need to use a low-level XPCOM runnable (or timer) yourself.harness-options
or anything like that.(I also implemented a generic component register function myself, but that again is not SDK code, and would need to be adapted to run in the SDK, just like the ABP one. It is also very similar to the ABP one.)
Now my nsIContentPolicy
sdk-based component look like this. File interceptor.js
:
'use strict';
var { Class } = require('sdk/core/heritage');
var xpcom = require('sdk/platform/xpcom');
var { Cc, Ci, Cu, Cm } = require('chrome');
var categoryManager = Cc["@mozilla.org/categorymanager;1"]
.getService(Ci.nsICategoryManager);
// nsIDOMNode
const TYPE_DOCUMENT_NODE = Ci.nsIDOMNode.DOCUMENT_NODE;
/// Interceptor
var contractId = "@deferredto.com/Interceptor;1";
var Interceptor = Class({
extends: xpcom.Unknown,
interfaces: [ 'nsIContentPolicy' ],
get wrappedJSObject() this,
shouldLoad : function dt_shouldLoad(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) {
let result = Ci.nsIContentPolicy.ACCEPT;
return result;
},
shouldProcess: function () Ci.nsIContentPolicy.ACCEPT
});
var factory = xpcom.Factory({
contract: contractId,
Component: Interceptor,
unregister: false // see https://bugzilla.mozilla.org/show_bug.cgi?id=753687
});
/// unload
var unload = require("sdk/system/unload");
unload.when(function() {
function trueUnregister() {
categoryManager.deleteCategoryEntry("content-policy", contractId, false);
try {
console.log("xpcom.isRegistered(factory)=" + xpcom.isRegistered(factory));
console.log("trueUnregister");
xpcom.unregister(factory);
console.log("xpcom.isRegistered(factory)=" + xpcom.isRegistered(factory));
} catch (ex) {
Cu.reportError(ex);
}
}
if ("dispatch" in Cu) {
console.log('"dispatch" in Cu');
Cu.dispatch(trueUnregister, trueUnregister);
} else {
console.log('"dispatch" not! in Cu');
Cu.import("resource://gre/modules/Services.jsm");
Services.tm.mainThread.dispatch(trueUnregister, 0);
}
});
//xpcom.register(factory);
var interceptor = Cc[contractId].createInstance(Ci.nsIContentPolicy);
categoryManager.deleteCategoryEntry("content-policy", contractId, false);
categoryManager.addCategoryEntry("content-policy", contractId, contractId, false, true);
And you can use it from sdk like this:
var interceptor = require("./interceptor");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With