Reputation: 354
I'm trying to load a custom module in a restartless add-on, using the following:
chrome/content/modules/Test.jsm:
var EXPORTED_SYMBOLS = [ 'Test' ];
let Test = {};
chrome.manifest:
content test chrome/content/
bootstrap.js:
const Cu = Components.utils;
// Tried this first, but figured perhaps chrome directives aren't loaded here yet
// let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
function install() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function uninstall() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function startup() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function shutdown() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
However, I get the following types of WARN messages (this one was for shutdown()
, but basically identical for all functions and in the earlier attempt in the global scope):
1409229174591 addons.xpi WARN Exception running bootstrap method shutdown on test@extensions.codifier.nl: [Exception... "Component returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIXPCComponents_Utils.import]" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: resource://gre/modules/addons/XPIProvider.jsm -> file:///test/bootstrap.js :: shutdown :: line 21" data: no] Stack trace: shutdown()@resource://gre/modules/addons/XPIProvider.jsm -> file:///test/bootstrap.js:21 < XPI_callBootstrapMethod()@resource://gre/modules/addons/XPIProvider.jsm:4232 < XPI_updateAddonDisabledState()@resource://gre/modules/addons/XPIProvider.jsm:4347 < AddonWrapper_userDisabledSetter()@resource://gre/modules/addons/XPIProvider.jsm:6647 < uninstall()@extensions.xml:1541 < oncommand()@about:addons:1 <
Are chrome.manifest
directives not yet available in bootstrap.js
? Or is what I am attempting some kind of security violation, perhaps? Or am I simply doing something trivially wrong?
What I was hoping to achieve, is that I could do something like the following:
chrome/content/modules/Test.jsm:
var EXPORTED_SYMBOLS = [ 'Test' ];
let Test = {
install: function( data, reason ) {
},
/* etc */
bootstrap: function( context ) {
context.install = this.install;
context.uninstall = this.uninstall;
context.startup = this.startup;
context.shutdown = this.shutdown;
}
}
bootstrap.js:
const Cu = Components.utils;
Cu.import( 'chrome://test/modules/Test.jsm' );
Test.bootstrap( this );
Perhaps it's a bit over the top to begin with, but I just kind of like the idea of hiding implementations in modules and/or objects and keeping bootstrap.js
super clean.
If you happen to have suggestions on how to achieve this by other means: I'm all ears.
Upvotes: 2
Views: 1050
Reputation: 37328
Yes you can your path is wrong though.
Just do this:
let test = Cu.import( 'chrome://test/content/modules/Test.jsm', {} ).Test;
notice the /content/
You don't have to do the .Test
unless you want the lower case test
to hold it. You can just do:
Cu.import( 'chrome://test/content/modules/Test.jsm');
and use as Test.blah
where blah is whatever is in the JSM module.
This code can go anywhere, it does not have to be in the install
function.
Make sure to unload the custom JSM modules or else it can lead to zombie compartments which is bad for memory. Read here:
Upvotes: 2
Reputation: 5054
Beyond @Noitidart's answer, you don't have to use chrome.manifest' and register a content package if your only concern is how to import your module.
function install(data, reason) {
Components.utils.import(data.resourceURI.spec + "relative/path/to/your/module.jsm");
}
Upvotes: 1