Bug 731779: Integrate the Add-on SDK loader and API libraries into Firefox (uplifting from addon-sdk a16bbd5772880b578a939eeb65102bca6560d494)
This commit is contained in:
153
addon-sdk/source/lib/sdk/addon/runner.js
Normal file
153
addon-sdk/source/lib/sdk/addon/runner.js
Normal file
@@ -0,0 +1,153 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 expandtab */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
module.metadata = {
|
||||
"stability": "experimental"
|
||||
};
|
||||
|
||||
const { Cc, Ci } = require('chrome');
|
||||
const { descriptor, Sandbox, evaluate, main, resolveURI } = require('toolkit/loader');
|
||||
const { once } = require('../system/events');
|
||||
const { exit, env, staticArgs, name } = require('../system');
|
||||
const { when: unload } = require('../system/unload');
|
||||
const { loadReason } = require('../self');
|
||||
const { rootURI } = require("@loader/options");
|
||||
const globals = require('../system/globals');
|
||||
|
||||
const NAME2TOPIC = {
|
||||
'Firefox': 'sessionstore-windows-restored',
|
||||
'Fennec': 'sessionstore-windows-restored',
|
||||
'SeaMonkey': 'sessionstore-windows-restored',
|
||||
'Thunderbird': 'mail-startup-done',
|
||||
'*': 'final-ui-startup'
|
||||
};
|
||||
|
||||
// Gets the topic that fit best as application startup event, in according with
|
||||
// the current application (e.g. Firefox, Fennec, Thunderbird...)
|
||||
const APP_STARTUP = NAME2TOPIC[name] || NAME2TOPIC['*'];
|
||||
|
||||
// Initializes default preferences
|
||||
function setDefaultPrefs(prefsURI) {
|
||||
const prefs = Cc['@mozilla.org/preferences-service;1'].
|
||||
getService(Ci.nsIPrefService).
|
||||
QueryInterface(Ci.nsIPrefBranch2);
|
||||
const branch = prefs.getDefaultBranch('');
|
||||
const sandbox = Sandbox({
|
||||
name: prefsURI,
|
||||
prototype: {
|
||||
pref: function(key, val) {
|
||||
switch (typeof val) {
|
||||
case 'boolean':
|
||||
branch.setBoolPref(key, val);
|
||||
break;
|
||||
case 'number':
|
||||
if (val % 1 == 0) // number must be a integer, otherwise ignore it
|
||||
branch.setIntPref(key, val);
|
||||
break;
|
||||
case 'string':
|
||||
branch.setCharPref(key, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// load preferences.
|
||||
evaluate(sandbox, prefsURI);
|
||||
}
|
||||
|
||||
function definePseudo(loader, id, exports) {
|
||||
let uri = resolveURI(id, loader.mapping);
|
||||
loader.modules[uri] = { exports: exports };
|
||||
}
|
||||
|
||||
function wait(reason, options) {
|
||||
once(APP_STARTUP, function() {
|
||||
startup(null, options);
|
||||
});
|
||||
}
|
||||
|
||||
function startup(reason, options) {
|
||||
if (reason === 'startup')
|
||||
return wait(reason, options);
|
||||
|
||||
// Inject globals ASAP in order to have console API working ASAP
|
||||
Object.defineProperties(options.loader.globals, descriptor(globals));
|
||||
|
||||
// Load localization manifest and .properties files.
|
||||
// Run the addon even in case of error (best effort approach)
|
||||
require('../l10n/loader').
|
||||
load(rootURI).
|
||||
then(null, function failure(error) {
|
||||
console.info("Error while loading localization: " + error.message);
|
||||
}).
|
||||
then(function onLocalizationReady(data) {
|
||||
// Exports data to a pseudo module so that api-utils/l10n/core
|
||||
// can get access to it
|
||||
if (data)
|
||||
definePseudo(options.loader, '@l10n/data', data);
|
||||
run(options);
|
||||
});
|
||||
}
|
||||
|
||||
function run(options) {
|
||||
try {
|
||||
// Try initializing HTML localization before running main module. Just print
|
||||
// an exception in case of error, instead of preventing addon to be run.
|
||||
try {
|
||||
// Do not enable HTML localization while running test as it is hard to
|
||||
// disable. Because unit tests are evaluated in a another Loader who
|
||||
// doesn't have access to this current loader.
|
||||
if (options.main !== 'test-harness/run-tests')
|
||||
require('../l10n/html').enable();
|
||||
}
|
||||
catch(error) {
|
||||
console.exception(error);
|
||||
}
|
||||
// Initialize inline options localization, without preventing addon to be
|
||||
// run in case of error
|
||||
try {
|
||||
require('../l10n/prefs');
|
||||
}
|
||||
catch(error) {
|
||||
console.exception(error);
|
||||
}
|
||||
|
||||
// TODO: When bug 564675 is implemented this will no longer be needed
|
||||
// Always set the default prefs, because they disappear on restart
|
||||
setDefaultPrefs(options.prefsURI);
|
||||
|
||||
// this is where the addon's main.js finally run.
|
||||
let program = main(options.loader, options.main);
|
||||
|
||||
if (typeof(program.onUnload) === 'function')
|
||||
unload(program.onUnload);
|
||||
|
||||
if (typeof(program.main) === 'function') {
|
||||
|
||||
program.main({
|
||||
loadReason: loadReason,
|
||||
staticArgs: staticArgs
|
||||
}, {
|
||||
print: function print(_) { dump(_ + '\n') },
|
||||
quit: exit
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.exception(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
exports.startup = startup;
|
||||
|
||||
// If add-on is lunched via `cfx run` we need to use `system.exit` to let
|
||||
// cfx know we're done (`cfx test` will take care of exit so we don't do
|
||||
// anything here).
|
||||
if (env.CFX_COMMAND === 'run') {
|
||||
unload(function(reason) {
|
||||
if (reason === 'shutdown')
|
||||
exit(0);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user