开发者

How to share code between content script and addon?

I'm writing an extension for Firefox 4+.

I have some code in a file named utils.js wh开发者_运维问答ich I'd like to call from both the addon's main.js and from the page-mod's content script.

Is it possible to refer from both to the same utils.js? If so, how?

Edit: Even better would be a solution allowing me to use the same code in a Google Chrome extension, too.


I've run into this same problem. You'd think there'd be an obvious solution. Here's what I've been doing for firefox (haven't worked with chrome):

I have a file lib/dbg.js containing my basic debug functions that I want to use everywhere.

In each content scriptable module in my main.js, I have this:

contextMenu.Item({
...
contentScript: export_internals(require('dbg')),
contentScriptFile: my-actual-scripts.js
...

and then in main I have a function

function export_internals(module) {
    var code = '';
    for (name in module) {
        var val = module[name];
        if (val.constructor === String)
            code += name + ' = "' + val + '";';
        else
            code += val;
    }
    return code;
}

which basically just cycles through the exported properties (variables, functions, etc) and makes use of things like Function.toString() to basically build a stringified version of the dbg module and pass it as an inline content script. This function probably isn't hugely general as I just wrote it to handle simple functions and strings (the only two data types I needed) but the principle should be easily applied even if you were to just do something like

contentScript: require('dbg').my_function.toString()

It's clearly a bit of a hack but a pretty reliable one so far. Is that what you were looking for?


My solution was to

  1. put all the "logic" (and my "utils" module) in the addon code
  2. keep the content script as simple as possible
  3. and whenever content script needs information that would require the utils module I use the asynchronous communication system between content script (self.port.emit, self.on...) and addon code (worker.port.on...)

The solution has lead to a better design of my addon. But I don't know if the async approach would work in your situation.


Since I couldn't find an existing solution I'm now just copying the same file to multiple directories (as part of the build/debug process).

This seems to work best for now especially since most part of the source code is reused in a Google Chrome implementation of the extension, too.

To make utils.js usable in Firefox content scripts and in Chrome (both have no CommonJS) I'm importing it like this:

var Utils = Utils || require('utils').Utils; 

The relevant parts of utils.js look like this:

function initUtils() {
    var result = {
        // ..define exported object...
    };
    return result;
};

// Chrome
var Utils = initUtils();
var exports = exports || {}; 
// Firefox
exports.Utils = Utils;


Thanks for the pointer to Implementing Reusable Modules at Mozilla's add-on SDK reference site. I'm still not quite clear on how to do the exports invocation. In their example they use the same name for the function and the file. So, in the line exports.translate = translate; does the translate on the left refer to the function translate() while the one on the right refers to the file translate.js, or maybe vice versa?

magnoz' reply above (in which the function name and file name differ due to caSE sENSITiVitY) seems to suggest I should just use the function name twice and ignore the file name. Is this the case?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜