是否有一种简单的方法可以为简单的内容脚本创建Firefox扩展,而无需使用Add-On SDK和PageMod?通过安装Python和SDK的麻烦,学习如何使用SDK和API,添加不必要的膨胀和抽象层,只是为了执行一个简单的内容脚本,这似乎有点过头了。
我已经尝试过使用XUL浏览器覆盖并在那里注入脚本,但是在browser.xul
上下文而不是document.body
中注入所有内容也会增加很多复杂性......
那么在html文档而不是XUL文档中注入一些脚本和css文件最简单,最轻量级的方法是什么?
答案 0 :(得分:7)
你的猜测是边界过于宽泛,所以我不会详细讨论所有内容,但会给出一般概述。
简单可能是夸大其词,但SDK内容脚本(实际上也是模块),Greasemonkey / Scriptish以及其他类似于内容脚本的内容在内部使用Sandbox
。即使bootstrap.js
在无重新启动的附加组件中也会在沙盒中执行。
基本思路如下:
Components
的访问权限)脚本将使用系统主体。Sandbox
。evalInSandbox
或subscript loader。以下是向窗口添加非特权内容脚本的有限示例:
// 1. get the content window, e.g. the currently selected tab window
var contentWindow = gBrowser.contentWindow;
// 2. Choose the principal, e.g. just use the content window again
var principal = contentWindow;
// 3. We want XRay wrappers, to keep our content script and the actual
// page scripts in their own corners.
var wantXrays = true;
// 4. Our prototype will be the window
var sbProto = contentWindow;
// 5. Putting it all together to create a sandbox
var sandbox = Cu.Sandbox(principal, {
sandboxPrototype: sbProto,
wantXrays: wantXrays
});
// 6. Adding a random helper function (e.g.)
sandbox.getRandomInt = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
// 7. Execute some content script, aka. the stupid example.
try {
var execute = function() {
var demo1 = document.querySelector('title').textContent;
var demo2 = getRandomInt(1, 1000);
alert(demo1 + " " + demo2);
}
Cu.evalInSandbox(
"(" + execute.toSource() + ")()",
sandbox
);
} catch(ex) {
console.error(ex);
}
PS:此示例将在Scratchpad with Environment/Browser中逐字运行。
关于样式:
执行SDK的功能,我想,这是简化的:
var wu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
var uri = Services.io.newURI(
"chrome://myaddon/style/content-style.css",
null,
null);
wu.loadSheet(uri, wu.USER_SHEET);