Firefox扩展中的ContentScript,不使用附加SDK

Vin*_*ghe 3 javascript firefox firefox-addon content-script

有没有一种简单的方法可以为简单的内容脚本创建Firefox扩展,而无需使用Add-On SDK和PageMod?通过安装Python和SDK的麻烦,学习如何使用SDK和API,添加不必要的膨胀和抽象层,只是为了执行简单的内容脚本,这似乎有点过分.

我已经尝试过使用XUL浏览器覆盖并在那里注入脚本,但是在browser.xul上下文中注入所有内容而不是document.body增加了很多复杂性......

那么在html文档而不是XUL文档中注入一些脚本和css文件最简单,最轻量级的方法是什么?

nma*_*ier 7

你的猜测是边界过于宽泛,所以我不会详细讨论所有内容,而是给出一般概述.

简单可能是夸大其词,但SDK内容脚本(实际上也是模块),Greasemonkey/Scriptish以及类似内容脚本的所有其他Sandbox内部使用.即使bootstrap.js在重新启动时,附加组件也会在沙箱中执行.

基本思路如下:

  1. 获取对要附加的内容窗口的引用.
  2. 选择脚本应在其下运行的"主体".委托人本质上是安全上下文/政策,也定义了相同的起源.无特权内容脚本通常使用内容窗口本身(也是主体),而特权脚本(chrome访问Components)脚本将使用系统主体.
  3. 选择是否需要XRay包装器.文档告诉你更多关于它的信息.
  4. 选择Sandbox原型("全局"或顶​​级).通常对于内容脚本,您将选择内容窗口.
  5. 创建Sandbox.
  6. 将您的内容脚本可能需要的任何内容添加到沙箱中.
  7. 通过任一evalInSandbox下标加载器执行脚本.

以下是向窗口添加非特权内容脚本的有限示例:

// 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);
}
Run Code Online (Sandbox Code Playgroud)

PS:这个例子将在带有环境/浏览器Scratchpad中逐字运行.

关于款式:

我想,做了什么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);
Run Code Online (Sandbox Code Playgroud)