Firefox Addons SDK - 如何从内容脚本访问简单存储?

ddl*_*ack 8 javascript firefox firefox-addon firefox-addon-sdk

我正在使用新的FireFox Addons SDK来开发扩展.我有一个小部件,附有一个面板.该面板用于控制首选项,因此我需要从面板的内容脚本中访问simple-storage api.我知道您无法直接访问API,因此我尝试使用消息传递.继承人我得到了什么:

exports.main = function() {
    var panel = require('panel');
    var ss = require('simple-storage');

    var prefPanel = panel.Panel({
        contentURL: self.data.url('prefPanel.html'),
        contentScriptFile: self.data.url('prefPanel.js'),
        contentScriptWhen: 'ready',
        onMessage: function(message) {
            switch(message.method) {
                case 'setValue':
                    ss.storage[message.key] = message.value;
            }
        },
    });

    prefPanel.postMessage(ss.storage);


    require('widget').Widget({
        id: 'ml-pref-button',
        content: 'ML',
        width: 30,
        panel: prefPanel,
    })
}
Run Code Online (Sandbox Code Playgroud)

在prefPanel.js我有:

self.on('message', function(storage) {

    storage.setValue = function(key, value) {
        this[key] = value;
        self.postMessage({
            method: 'setValue',
            'key': key,
            'value': value,
        });
    }

    // Do some stuff, using storage object

});
Run Code Online (Sandbox Code Playgroud)

问题是,我收到此错误:

Error: An exception occurred.
Traceback (most recent call last):
  File "resource://jid0-wdemwzahwzh3bsw0kkxlcjg9e7k-at-jetpack-api-utils-lib/content/worker.js", line 405, in postMessage
    throw new Error(ERR_DESTROYED);
Error: The page has been destroyed and can no longer be used.
Run Code Online (Sandbox Code Playgroud)

我想这是因为prefPanel DOM和内容脚本还没有加载.每次显示面板时是重新加载DOM和内容脚本,还是它们总是在后台运行?

Wla*_*ant 3

是的,我认为每次显示面板时都会重新加载 DOM 和内容脚本(您可以轻松测试这是否正确,只需调用console.log("loaded")内容脚本即可)。因此,您应该在显示面板时发送消息:

var prefPanel = panel.Panel({
    contentURL: self.data.url('prefPanel.html'),
    contentScriptFile: self.data.url('prefPanel.js'),
    contentScriptWhen: 'ready',
    onMessage: function(message) {
        switch(message.method) {
            case 'setValue':
                ss.storage[message.key] = message.value;
        }
    },
    onShow: function() {
        prefPanel.sendMessage(ss.storage);
    }
});
Run Code Online (Sandbox Code Playgroud)