im developing a little firefox addon with the addon-sdk provided by mozilla. The addon should work on only one specific website and it needs to block a js-file from this website. I'm searching for hours on how to block such a request.
Hopefully someone knows the answer
Yeah, you'd have to do this mostly by hand. The SDK isn't going to help you much at all here but it is somewhat possible.
This is along the lines of what you'd need to do. Note that this isn't tested and won't work out of the box but just to give you an idea of what components are involved and where to find more resources.
const { Cc, Ci, Cm, components } = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
const CategoryManager = Cc["#mozilla.org/categorymanager;1"]
.getService(Ci.nsICategoryManager);
function PolicyComponent() { }
PolicyComponent.prototype = {
desc: "My nsIContentPolicy XPCOM Component",
classID: components.ID("{3ffd2f60-3784-11e1-b86c-0800200c9a66}"),
contractID: "#abc.def.com/policycomp;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy]),
shouldLoad: function(contentType, contentLocation, requestOrigin, aContext, mimeTypeGuess, extra) {
if (contentLocation.spec != BLOCKED_JS) { return return Ci.nsIContentPolicy.ACCEPT; }
else { return Ci.nsIContentPolicy.REJECT_REQUEST; }
},
shouldProcess: function() {
return CI.nsIContentPolicy.ACCEPT;
}
}
var pc = new PolicyComponent()
// Register the Interface
Cm.QueryInterface(Ci.nsIComponentRegistrar).registerFactory(pc.uuid, pc.desc, pc.contractID, pc);
// Add the content policy
CategoryManager.addCategoryEntry("content-policy",pc.className,pc.contractID, true, true); // not sure you should replace (last true statement)
See this post for more:
What is missing in my nsIContentPolicy Firefox/IceWeasel extension XPCOMponent implementation for the shouldLoad to be called?
Also take a look at these docs: https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads#Content_Policy
Related
On the "+17 more" link, I want it to open a url of my chosing for that specific date. I'm not finding the documentation to have an example, and I know this must be really easy (because everything else has been!).
Found it...
eventLimitClick: function(cellInfo) {
if (cellInfo.date) {
var newdate = moment(cellInfo.date).format('YYYY-MM-DD');
window.open('url-i-am-calling?variables, "_blank");
return false;
}
},
I am trying to write an addon for Firefox which displays the current percentage of a file being uploaded to a website (similar to how chrome does it). The problem I am having is that I have never worked with Addons for Firefox so I'm a little confused.
I have looked at the source of this Addon which was released in 2011, and this developer is referencing the following files:
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/PluralForm.jsm");
Another interesting piece of code I found when going through the source was:
Components.classes["#mozilla.org/network/http-activity-distributor;1"],
I've done a little research on these modules/classes, but I was wondering if in the last ~4 years there has been a change in the technology, and Firefox has made it a little easier to get file upload information.
I know from my experience in web development that you can use XMLHttpRequest() and addEventListener("progress", <function>, false); but is that possible with Firefox Addons? And would it work with any file uploaded to a site?
I'm pretty lost as you can see, any help would be greatly appreciated. Thank you so much!!
Actually it looks like all the code you need is right in that addon, i took this from that addon you posted from here: https://addons.mozilla.org/en-US/firefox/files/browse/125019/file/components/uploads.js#top
init: function() {
//dump(">>>>>>>>>>>>>>>>>>>>>> INITIALIZED\n");
// add observer
var hao = Ci.nsIHttpActivityObserver;
var _self = this;
this.observer = {
observeActivity: function(aHttpChannel, aActivityType,
aActivitySubtype, aTimestamp, aExtraSizeData, aExtraStringData) {
if ((aActivityType == hao.ACTIVITY_TYPE_SOCKET_TRANSPORT) &&
(aActivitySubtype == 0x804b0005)) { // STATUS_SENDING_TO
//dump("UPDATE STATUS: ["+aTimestamp+"] *" + aHttpChannel + "*\n");
_self.updateStatus(aHttpChannel, aTimestamp, aExtraSizeData);
}
if (aActivityType == hao.ACTIVITY_TYPE_HTTP_TRANSACTION) {
switch (aActivitySubtype) {
//case hao.ACTIVITY_SUBTYPE_RESPONSE_COMPLETE:
case hao.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE:
//dump("REMOVE: *" + aHttpChannel + "*\n");
_self.removeUpload(aHttpChannel);
break;
case hao.ACTIVITY_SUBTYPE_REQUEST_HEADER:
//dump("CREATE: *" + aHttpChannel + "*\n");
_self.createUpload(aHttpChannel);
break;
}
}
}
};
Cc["#mozilla.org/network/http-activity-distributor;1"]
.getService(Ci.nsIHttpActivityDistributor)
.addObserver(this.observer);
},
shutdown: function() {
Cc["#mozilla.org/network/http-activity-distributor;1"]
.getService(Ci.nsIHttpActivityDistributor)
.removeObserver(this.observer);
},
____ INTRO
Hello everyone, first of all, three clarifications:
My english is not good, so I beg your pardon in advance for my mistakes,
I'm a newbie so forgive me for inaccuracies,
I have previously searched and tried the solutions I found on the internet but still I can not solve the problem of embedding a prepopulated database.
____ THE GOAL
I want to develop an app for iOS and Android with a prepopulated database.
Just for example, the database consists of 15.000 records each one made of three key-value pair (id, firstname and lastname).
___ WHAT I DID
Steps:
ionic start myapp blank
cd myapp
ionic platform add ios
ionic platform add android
Then I created an sqlite database for testing purpose, named mydb.sqlite, made of one table people containing two id, firstname, lastname records.
I decided to use the following plugin: https://github.com/Antair/Cordova-SQLitePlugin
That's because it can be installed with cordova tool.
ionic plugin add https://github.com/Antair/Cordova-SQLitePlugin
(Alert: I think that the instructions on the website show an incorrect reference - "cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin" - which refers to another plugin).
Then, following the instructions on the plugin website, I copied the database to myapp/www/db/ so that it can now be found at myapp/www/db/mydb.sqlite
I modified the index.html including the SQLite plugin just after the default app.js script:
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="SQLitePlugin.js"></script>
I also write some lines of code in index.html file to show a button:
<ion-content ng-controller="MyCtrl">
<button class="button" ng-click="all()">All</button>
</ion-content>
Finally I had modified ./js/app.js:
// Ionic Starter App
var db = null;
angular.module('starter', ['ionic' /* What goes here? */ ])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// some predefined code has been omitted
window.sqlitePlugin.importPrepopulatedDatabase({file: "mydb.sqlite", "importIfExists": true});
db = window.sqlitePlugin.openDatabase({name: "mydb.sqlite"});
}); // $ionicPlatform.ready
}) // .run
.controller('MyCtrl', function($scope){
$scope.all = function(){
var query = "SELECT * FROM people";
// I don't know how to proceed
}; // $scope.all
}); // .controller
___ THE PROBLEM
I don't know how to proceed in the controller section to query all the records (just an example of query) and show the results in the console.log.
I think that the following code must be completed in some way:
angular.module('starter', ['ionic' /* What goes here? */ ])
And also the code inside controller section must be completed:
$scope.all = function(){
var query = "SELECT * FROM people";
// I don't know how to proceed
}; // $scope.all
___ FINAL THANKS
Thank you in advance for the help you will give to me.
So this guy's code has helped a lot to encapsulate my DAL. I highly recommend that you use he's code pretty much verbatim.
https://gist.github.com/jgoux/10738978
You'll see he has the following method:
self.query = function(query, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
var deferred = $q.defer();
self.db.transaction(function(transaction) {
transaction.executeSql(query, bindings, function(transaction, result) {
deferred.resolve(result);
}, function(transaction, error) {
deferred.reject(error);
});
});
return deferred.promise;
};
Let's break this down a bit. The query function takes a query string (the query param) and a list of possible bindings for ? in a query like "SELECT * FROM A_TABLE WHERE ID = ?". Because he's code is a service, the self value points to the service itself for all future invocations. The function will execute a transaction against the db, but it returns a promise that is only fulfilled once the db comes back.
His service provides a second helper function: fetchAll.
self.fetchAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
};
fetchAll will read the rows in their entirety into an array. The result param for fetchAll is the result variable passed in the query function's promise fulfillment.
If you copy and paste his code into your service file, you now have a bonafide DB service. You can wrap that service up in a DAL. Here's an example from my project.
.service('LocationService', function ($q, DB, Util) {
'use strict';
var self = this;
self.locations = [];
self.loadLocked = false;
self.pending = [];
self.findLocations = function () {
var d = $q.defer();
if (self.locations.length > 0) {
d.resolve(self.locations);
}
else if (self.locations.length === 0 && !self.loadLocked) {
self.loadLocked = true;
DB.query("SELECT * FROM locations WHERE kind = 'active'")
.then(function (resultSet) {
var locations = DB.fetchAll(resultSet);
self.locations.
push.apply(self.locations, locations);
self.loadLocked = false;
d.resolve(self.locations);
self.pending.forEach(function (d) {
d.resolve(self.locations);
});
}, Util.handleError);
} else {
self.pending.push(d);
}
return d.promise;
};
})
This example is a bit noisy since it has some "threading" code to make sure if the same promise is fired twice it only runs against the DB once. The general poin is to show that the DB.query returns a promise. The "then" following the query method uses the DB service to fetchAll the data and add it into my local memory space. All of this is coordinated by the self.findLocations returning the variable d.promise.
Yours would behalf similarly. The controller could have your DAL service, like my LocationService, injected into it by AngularJS. If you're using the AngularJS UI, you can have it resolve the data and pass it into the list.
Finally, the only issue I have with the guy's code is that the db should come from this code.
var dbMaker = ($window.sqlitePlugin || $window);
The reason for this is that the plugin does not work within Apache Ripple. Since the plugin does a fine job mirroring the Web SQL interface of the browser, this simple little change will enable Ripple to run your Ionic Apps while still allowing you to work your SQLite in a real device.
I hope this helps.
I am creating a firefox addon using the SDK. My goal is simple, to intercept a specific iframe and load my own HTML page (packaged as a resource with my addon) instead of the content that was requested originally.
So far I have the following code:
var httpRequestObserver =
{
observe: function(subject, topic, data)
{
var httpChannel, requestURL;
if (topic == "http-on-modify-request") {
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
var newRequestURL, i;
if (/someurl/.test(requestURL)) {
var ioService = Cc["#mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
httpChannel.redirectTo(ioService.newURI(self.data.url('pages/test.html'), undefined, undefined));
}
return;
}
}
};
var observerService = Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver, "http-on-modify-request", false);
This code works in that it detects the proper iframe loading and does the redirect correctly. However, I get the following error:
Security Error: Content at http://url.com may not load or link to
jar:file:///.../pages/test.html.
How can I get around this limitation?
actually man i was really over thinking this.
its already solved when I changed to using loadContext. Now when you get loadContext you get the contentWindow of whatever browser element (tab browser, or frame or iframe) and then just abort the http request like you are doing and then loadContext.associatedWindow.document.location = self.data('pages/tests.html');
done
ill paste the code here removing all the private stuff. you might need the chrome.manifest ill test it out and paste the code back here
Cu.import('resource://gre/modules/Services.jsm');
var httpRequestObserver = {
observe: function (subject, topic, data) {
var httpChannel, requestURL;
if (topic == "http-on-modify-request") {
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
var newRequestURL, i;
if (/someurl/.test(requestURL)) {
var goodies = loadContextGoodies(httpChannel);
if (goodies) {
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
goodies.contentWindow.location = self.data.url('pages/test.html');
} else {
//dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
}
}
return;
}
}
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
//httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
//start loadContext stuff
var loadContext;
try {
var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
//var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
try {
loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
} catch (ex) {
try {
loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
} catch (ex2) {}
}
} catch (ex0) {}
if (!loadContext) {
//no load context so dont do anything although you can run this, which is your old code
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var contentWindow = loadContext.associatedWindow;
if (!contentWindow) {
//this channel does not have a window, its probably loading a resource
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var gBrowser = aDOMWindow.gBrowser;
var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
return {
aDOMWindow: aDOMWindow,
gBrowser: gBrowser,
aTab: aTab,
browser: browser,
contentWindow: contentWindow
};
}
}
//end loadContext stuff
}
NOTE: Now try this first, I didn't test it yet, if you get a security error when it tries to redirect then create a chrome.manifest file and put it in the root directory. If it throws a security error than you definitely need a chrome.manifest file and that will without question fix it up. I'll test this myself later tonight when I get some time.
The chrome.manifest should look like this:
content kaboom-data ./resources/kaboom/data/ contentaccessible=yes
Then in the code way above change the redirect line from goodies.contentWindow.location = self.data.url('pages/test.html'); to goodies.contentWindow.location = 'chrome://kaboom-data/pages/test.html');.
see this addon here: https://addons.mozilla.org/en-US/firefox/addon/ghforkable/?src=search
in the chrome.manifest file we set the contentaccessible parameter to yes
you dont need sdk for this addon. its so simple, just ocpy paste that into a bootstrap skeleton as seen here:
Bootstrap With Some Features, Like chrome.manifest which you will need
Bootstrap Ultra Basic
if you want to really do a redirect of a page to your site, maybe you want to make a custom about page? if you would like ill throw togather a demo for you on making a custom about page. you can see a bit hard to understand demo here
posting my trials here so it can help all:
trail 1 failed - created chrome.manifest file with contents content kaboom-data resources/kaboom/data/ contentaccessible=yes
var myuri = Services.io.newURI('chrome://kaboom-data/content/pages/test.html', undefined, undefined);
httpChannel.redirectTo(myuri);
Error Thrown
Security Error: Content at http://digg.com/tools/diggthis/confirm? may
not load or link to
jar:file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ#jetpack.xpi!/resources/kaboom/data/pages/test.html.
trial 2 failed - created resource in bootstrap.js
alias.spec =
file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ#jetpack.xpi
alias updated to spec:
jar:file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ#jetpack.xpi!/
let resource = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
let alias = Services.io.newFileURI(data.installPath);
Cu.reportError('alias.spec = ' + alias.spec);
if (!data.installPath.isDirectory()) {
alias = Services.io.newURI("jar:" + alias.spec + "!/", null, null);
Cu.reportError('alias updated to spec: ' + alias.spec);
}
resource.setSubstitution("kaboom_data", alias);
...
var myuri = Services.io.newURI('resource://kaboom_data/resources/kaboom/data/pages/test.html', undefined, undefined);
httpChannel.redirectTo(myuri);
Error Thrown
Security Error: Content at http://digg.com/tools/diggthis/confirm? may
not load or link to
jar:file:///C:/Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/jid1-g4RtC8vdvPagpQ#jetpack.xpi!/resources/kaboom/data/pages/test.html.
CONCLUSION
in both trials above it was the weirdest thing, it wouldnt show the resource or chrome path in the security error thrown but it would give the full jar path. Leading me to believe that this has something to do with redirectTo function.
The solution that did work was your solution of
var gBrowser = utils.getMostRecentBrowserWindow().gBrowser;
var domWin = httpChannel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
var browser = gBrowser.getBrowserForDocument(domWin.document);
//redirect
browser.loadURI(self.data.url('pages/test.html'));
however I changed this to use loadContext instead of this method because it is the recommended way. also gBrowser to getMostRecentBrowserWindow will fail if the url load is slow and in that time the user swithces to another tab or window
I also changed to use Services.jsm as you had imported Cu anyways. Using Services.jsm is super fast not even blink fast. Its just a pointer.
Im still working on trying to the redirectTo method working its really bothering me. The changes I made are to my local copy.
Have you considered turning your local HTML file into a data URL and loading that?
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:
Is it possible to register the component from bootstrapped extension?
Is it possible to register the component from restartless extension?
Is it possible to use nsICategoryManager.addCategoryEntry "content-policy" without
component?
How to register the component in bootstrapped extension or somehow add
new "content-policy" category entry?
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:
The category manager is available via Cc["#mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).
The component registrar should be available by requiring also components from the chrome module and then components.manager.getService(Ci.nsIComponentRegistrar).
As Adblock Plus, you must unregister your component yourself on unload.
The unload part is unfortunely also a bit tricking, since you cannot synchronously unregister your component and the category entry, due to Bug 753687. Adblock Plus therefore does it async using 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.
Your code will register your component at runtime. You won't touch 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");