Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firefox Addons SDK - How to access simple storage from content script?

I am using the new FireFox Addons SDK to develop an extension. I have a widget, with a panel attached. The panel is used for controlling preferences, so I need to access simple-storage api from the panel's content script. I'm aware that you cannot access the API directly, so I have attempted to use message passing. Heres what I've got:

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,
    })
}

and in prefPanel.js I've got:

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

});

The problem is, I get this error:

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.

I guess that this is because the prefPanel DOM and content scripts havn't loaded yet. Are the DOM and content scripts reloaded every time the panel is shown, or are they always running in the background?

like image 522
Cameron Martin Avatar asked Jan 04 '12 18:01

Cameron Martin


1 Answers

Yes, I think that the DOM and content scripts are reloaded every time the panel is shown (you can easily test whether that's correct, just put a console.log("loaded") call into your content script). So you should simply send your message when the panel is shown:

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);
    }
});
like image 103
Wladimir Palant Avatar answered Nov 14 '22 23:11

Wladimir Palant