简体   繁体   English

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

[英]ContentScript in Firefox extension without using the Add-On SDK

Is there an easy way to create a Firefox extension for a simple content script WITHOUT having to use the Add-On SDK and PageMod? 有没有一种简单的方法可以为简单的内容脚本创建Firefox扩展,而无需使用Add-On SDK和PageMod? It really seems overkill to go through the hassle of installing Python and the SDK, learning how to use the SDK and API, and adding unnecessary bloat and abstraction layers, just to execute a simple content script. 通过安装Python和SDK的麻烦,学习如何使用SDK和API,添加不必要的膨胀和抽象层,只是为了执行简单的内容脚本,这似乎有点过分。

I already tried using a XUL browser overlay and injecting the scripts there, but having everything injected in the browser.xul context instead of document.body is also adding a lot of complexity... 我已经尝试过使用XUL浏览器覆盖并在那里注入脚本,但是在browser.xul上下文中注入所有内容而不是document.body也增加了很多复杂性......

So what's the easiest, lightweight way to inject a few scripts and css files in the html document instead of the XUL document? 那么在html文档而不是XUL文档中注入一些脚本和css文件最简单,最轻量级的方法是什么?

Your guestion is border-line too broad, so I won't be discussing everything in detail but give a general overview. 你的猜测是边界过于宽泛,所以我不会详细讨论所有内容,而是给出一般概述。

Easy might be an overstatement, but SDK content scripts (and actually modules too), Greasemonkey/Scriptish and everything else that resembles a content script uses Sandbox internally. 简单可能是夸大其词,但SDK内容脚本(实际上也是模块),Greasemonkey / Scriptish以及其他类似于内容脚本的内容都在内部使用Sandbox Even bootstrap.js in restartless add-ons are executed in a sandbox. 即使是无重启加载项中的bootstrap.js也会在沙箱中执行。

The basic idea is the following: 基本思路如下:

  1. Get a reference to the content window you want to attach too. 获取对要附加的内容窗口的引用。
  2. Choose a "principal" the script should run under. 选择脚本应在其下运行的“主体”。 The principal is essentially the security context/policy that also defines the same origin. 委托人本质上是安全上下文/政策,也定义了相同的起源。 An unprivileged content script would usually use the content window itself (which is a principal too), while a privileged script (chrome access to Components ) script would use the system principal. 非特权内容脚本通常使用内容窗口本身(也是主体),而特权脚本(对Components chrome访问)脚本将使用系统主体。
  3. Choose if you want XRay wrappers. 选择是否需要XRay包装器。 The docs tell you more about it. 文档告诉你更多关于它的信息。
  4. Choose the Sandbox prototype (the "global" or top-level this). 选择Sandbox原型(“全局”或顶​​级)。 Usually for content script stuff you'll choose the content window. 通常对于内容脚本,您将选择内容窗口。
  5. Create the Sandbox . 创建Sandbox
  6. Add any stuff your content script may need to the Sandbox. 将您的内容脚本可能需要的任何内容添加到沙箱中。
  7. Execute a script by either evalInSandbox or the subscript loader . 通过evalInSandbox下标加载器执行脚本。

Here is a limited example adding an unprivileged content script to a window: 以下是向窗口添加非特权内容脚本的有限示例:

// 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: This example will run verbatim in a Scratchpad with Environment/Browser . PS:这个例子将在带有环境/浏览器Scratchpad中逐字运行。

Regarding styles: 关于款式:

Do what the SDK does, I guess, which is simplified: 我想,做了什么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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM