我可以在不重新启动的附加组件的bootstrap.js中加载自定义jsm模块吗?

时间:2014-08-28 12:44:57

标签: firefox-addon firefox-addon-restartless jsm

我正在尝试使用以下内容在不重新启动的加载项中加载自定义模块:

铬/内容/模块/ 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运行bootstrap方法的异常   shutdown on test@extensions.codifier.nl:[Exception ...“Component   返回失败代码:0x80070057(NS_ERROR_ILLEGAL_VALUE)   [nsIXPCComponents_Utils.import]“nsresult:”0x80070057   (NS_ERROR_ILLEGAL_VALUE)“位置:”JS框架::   资源://gre/modules/addons/XPIProvider.jsm - >   file:///test/bootstrap.js :: shutdown :: line 21“data:no] Stack   trace:sh​​utdown()@ resources://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<   

chrome.manifest中尚未提供bootstrap.js指令吗?或者是我正在尝试某种安全违规,或许?或者我只是做了一些非常错误的事情?


我希望实现的目标是,我可以做以下事情:

铬/内容/模块/ 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 个答案:

答案 0 :(得分: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

并使用install,其中blah是JSM模块中的任何内容。

此代码可以放在任何地方,它不必在{{1}}函数中。

确保卸载自定义JSM模块,否则会导致僵尸隔离,这对内存不利。在这里阅读:

答案 1 :(得分:1)

除了@ Noitidart的回答,你不必使用chrome.manifest'如果您唯一关心的是如何导入模块,请注册内容包。

function install(data, reason) {
  Components.utils.import(data.resourceURI.spec + "relative/path/to/your/module.jsm");

}