Могу ли я загрузить собственные модули jsm в bootstrap.js перезапускаемого дополнения?
Я пытаюсь загрузить пользовательский модуль в перезапускаемом дополнении, используя следующее:
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;
}
Тем не менее, я получаю следующие типы сообщений WARN (это было для shutdown()
, но в основном идентичны для всех функций и в более ранней попытке в глобальной области видимости):
1409229174591 addons.xpi WARN исключения работает самозагрузка отключения метода на test@extensions.codifier.nl: [Exception... "Компонент возвращается код ошибки: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIXPCComponents_Utils.import]" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" местоположение: "JS frame:: resource://gre/modules/addons/XPIProvider.jsm -> file:///test/bootstrap.js:: shutdown:: line 21" data: no] Трассировка стека: shutdown()@resource://gre/modules/addons/XPIProvider.jsm -> file:///test/bootstrap.js:21
Являются chrome.manifest
директивы еще не доступны в bootstrap.js
? Или это то, что я пытаюсь нарушить, может быть? Или я просто делаю что-то тривиально неправильно?
То, чего я надеялся достичь, это то, что я мог сделать что-то вроде следующего:
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 );
Возможно, для начала это немного излишне, но мне просто нравится идея скрывать реализации в модулях и / или объектах и сохранять bootstrap.js
супер чистый.
Если у вас есть предложения о том, как этого добиться другими способами: я весь в ушах.
2 ответа
Да, возможно, ваш путь неверен.
Просто сделай это:
let test = Cu.import( 'chrome://test/content/modules/Test.jsm', {} ).Test;
обратите внимание на /content/
Вам не нужно делать .Test
если вы не хотите нижний регистр test
держать его. Вы можете просто сделать:
Cu.import( 'chrome://test/content/modules/Test.jsm');
и использовать как Test.blah
где бла все, что есть в модуле JSM.
Этот код может идти куда угодно, он не должен быть в install
функция.
Убедитесь, что выгрузили пользовательские модули JSM, иначе это может привести к появлению зомби-отсеков, что плохо сказывается на памяти. Читайте здесь:
- последний абзац здесь: https://developer.mozilla.org/en-US/docs/Extensions/Common_causes_of_memory_leaks_in_extensions
- больше читать, но не обязательно: https://developer.mozilla.org/en-US/docs/Zombie_compartments
Помимо ответа @Noitidart, вам не нужно использовать chrome.manifest'и регистрировать пакет контента, если ваша единственная задача - импортировать ваш модуль.
function install(data, reason) {
Components.utils.import(data.resourceURI.spec + "relative/path/to/your/module.jsm");
}