在使用附加 SDK 构建附加组件时,内容脚本由 main.js 管理。没有内置方法可以访问所有附加组件的内容脚本。要将消息发送到所有选项卡,您需要手动跟踪内容脚本。
单向消息很容易由现有的API https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/page-mod.html。不过,回调不是内置的。
My 浏览器动作 SDK 库 https://github.com/Rob--W/browser-action-jplib包含一个名为“消息传递 https://github.com/Rob--W/browser-action-jplib/blob/master/lib/messaging.js”,它实现了 Chrome 消息传递 API。在以下示例中,内容脚本和主脚本使用一个名为“extension”的对象。该对象公开了onMessage
and sendMessage
方法,模仿 Chrome 扩展消息传递 https://developer.chrome.com/extensions/messaging.html APIs.
The following example adds a content script to every page on Stack Overflow, and upon click, the titles of the tabs are logged to the console (the one opened using Ctrl + Shift + J).
lib/main.js
// https://github.com/Rob--W/browser-action-jplib/blob/master/lib/messaging.js
const { createMessageChannel, messageContentScriptFile } = require('messaging');
const { PageMod } = require('sdk/page-mod');
const { data } = require('sdk/self');
// Adds the message API to every page within the add-on
var ports = [];
var pagemod = PageMod({
include: ['http://stackoverflow.com/*'],
contentScriptWhen: 'start',
contentScriptFile: [messageContentScriptFile, data.url('contentscript.js')],
contentScriptOptions: {
channelName: 'whatever you want',
endAtPage: false
},
onAttach: function(worker) {
var extension = createMessageChannel(pagemod.contentScriptOptions, worker.port);
ports.push(extension);
worker.on('detach', function() {
// Remove port from list of workers when the content script is deactivated.
var index = ports.indexOf(extension);
if (index !== -1) ports.splice(index, 1);
});
}
});
function sendMessageToTabs(message, callbackFunc) {
for (var i=0; i<ports.length; i++) {
ports[i].sendMessage(message, callbackFunc);
}
}
// Since we've included the browser-action module, we can use it in the demo
var badge = require('browserAction').BrowserAction({
default_title: 'Click to send a message to all tabs on Stack Overflow'
});
badge.onClicked.addListener(function() {
sendMessageToTabs('gimme title', function(response) {
// Use console.error to make sure that the log is visible in the console.
console.error(response);
});
});
作为记录,有趣的部分main.js
是在里面onAttach
event.
data/contentscript.js
extension.onMessage.addListener(function(message, sender, sendResponse) {
if (message === 'gimme title') {
sendResponse(document.title);
}
});