How to share code between content script and addon?

↘锁芯ラ 提交于 2019-12-23 08:54:04

问题


I'm writing an extension for Firefox 4+.

I have some code in a file named utils.js which 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.


回答1:


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?




回答2:


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.




回答3:


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;



回答4:


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?



来源:https://stackoverflow.com/questions/6425831/how-to-share-code-between-content-script-and-addon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!