scopefirefox-addonpersistencefirefox-addon-restartlessjsm

What are the scopes and/or persistence of JavaScript Code Modules?


Experimenting with a bootstrapped extension, I'm trying to understand the scopes and/or persistence of jsm modules by setting a property, called baseUri, on a module object from bootstrap.js and reading it again from javascript in my options.xul (which is opened from the Add-ons Manager).

My current understanding is that JavaScript Code Modules are persisted, once loaded. However, when I try to access baseUri from options.xul, its value is undefined.

install.rdf:

<!-- just the relevant XML (this works as expected, by the way): -->
<em:optionsURL>chrome://test/content/options.xul</em:optionsURL>

/modules/Test.jsm:

var EXPORTED_SYMBOLS = [ 'Test' ];

Test = {
  baseUri: undefined
}

/bootstrap.js:

// this is done in global scope,
// not inside install() or startup() for instance, if that matters
let test = Components.utils.import( 'file:///absolute/path/to/Test.jsm', {} ).Test;
test.baseUri = someBaseUriIExtracted;

/chrome/content/options.js (included in /chrome/content/options.xul):

let test = Components.utils.import( 'file:///absolute/path/to/Test.jsm', {} ).Test;
console.log( test.baseUri ); // undefined

So, I guess what I'm failing to fully understand is what the exact scopes are from which I should be able to access object properties from exported jsm symbols and/or how and when exactly these objects are persisted.

Does my problem have anything to do with sand-boxing, perhaps? Does Firefox consider options.xul, when opened from the Add-ons Manager, to be a different security scope than bootstrap.js, perhaps?

Can you shed a thorough light on the actual scopes of jsm modules and when and where I should be able to access persisted properties on jsm modules?


Solution

  • The documentation is pretty straightforward about what and how is shared

    Each scope that imports a module receives a by-value copy of the exported symbols in that module. Changes to the symbol's value will not propagate to other scopes (though an object's properties will be manipulated by reference).

    I think the accompanying examples are clear.

    Maybe you should use getters/setters.