Modifying Web Pages Based on URL

开始本教程之前,您必须安装好 SDK,并且学习 cfx 的基本的使用方法。

要修改任何页面匹配特定的模式(比如,“http://example.org/”)当它们加载后,使用page-mod模块。

要创建 page-mod,您必须指定两件事:

  • 一个或多个 content scripts 运行,它们的工作将和网站内容进行交互
  • 一个或多个 patterns 去匹配您要修改的页面的 URLs

content scripts为内容脚本,只能使用普通浏览器支持的 JS,不能使用 add-on 的API

这里有一个范例。内容脚本提供contentScript选项,地址样本提供include选项:

// Import the page-mod API
var pageMod = require("sdk/page-mod");
 
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
  include: "*.org",
  contentScript: 'document.body.innerHTML = ' +
                 ' "<h1>Page matches ruleset</h1>";'
});

试试吧:

  • 创建新的目录并转到该目录下
  • 运行 cfx init
  • 打开 lib/main.js 文件,添加以上的代码
  • 运行 cfx run
  • 在打开的浏览器窗口中打开 ietf.org

您将看到:

指定匹配模式

匹配模式使用 match-pattern 语法。您可以通过单一的匹配字符串,或者数组。

把内容脚本放在独立的文件中

在上面的范例中我们通过字符串来实现内容脚本。除非是用作简单的例子,通常情况下您应该将内容脚本放在独立文件中,这将使您的代码更易维护、调式和查看。

要这样做,您需要:

  • 将脚本文件保存在 data 目录下
  • 使用 contentScriptFile 选项代替 contentScript 选项,并且指定脚本的路径。路径用 self.data.url() 取得

例如,如果我们将内容脚本保存在 data 目录下,命名为 my-script.js,在main.js中,我们应该这么写:

// Import the page-mod API
var pageMod = require("sdk/page-mod");
// Import the self API
var self = require("sdk/self");
 
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
  include: "*.org",
  contentScriptFile: self.data.url("my-script.js")
});

加载多个Content Scripts

您可以加载更多脚本,且脚本可以相互交互。所以,您可以使用jQuery重写 my-script.js:

$("body").html("<h1>Page matches ruleset</h1>");

然后下载 jQuery 库到您的扩展开发目录的 data 目录下,并且将 jQuery 和 my-script 一起加载(确保先加载 jQuery 库):

// Import the page-mod API,加载 add-on 的 page-mod API
var pageMod = require("sdk/page-mod");
// Import the self API, 加载 add-on 的 self API
var self = require("sdk/self");
 
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
// 创建 page mod,匹配 “.org” URL
pageMod.PageMod({
  include: "*.org",
  contentScriptFile: [self.data.url("jquery-1.7.min.js"), self.data.url("my-script.js")]
});

您也可以在同一 page-mod 中同时使用 contentScriptcontentScriptFile 。如果您这么做的话,contentScript的脚本将会先加载。(应该是contentScriptFile的先加载吧?)

// Import the page-mod API
var pageMod = require("sdk/page-mod");
// Import the self API
var self = require("sdk/self");
 
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
  include: "*.org",
  contentScriptFile: self.data.url("jquery-1.7.min.js"),
  contentScript: '$("body").html("<h1>Page matches ruleset</h1>");'
});

注意,您不能直接加载网站上的脚本。脚本必须从 data 目录中加载。

与 Content Script 通信

Your add-on script and the content script can't directly access each other's variables or call each other's functions, but they can send each other messages.

从 Content Script 与 main.js 通信,发送方使用 port.emit() ,接收方使用 port.on() 监听.

  • In the content script, port is a property of the global self object.
  • In the add-on script, you need to listen for the onAttach event to get passed a worker object that contains port.

Let's rewrite the example above to pass a message from the add-on to the content script. The message will contain the new content to insert into the document. The content script now needs to look like this:

// "self" is a global object in content scripts
// Listen for a message, and replace the document's
// contents with the message payload.
self.port.on("replacePage", function(message) {
  document.body.innerHTML = "<h1>" + message + "</h1>";
});

In the add-on script, we'll send the content script a message inside onAttach:

// Import the page-mod API
var pageMod = require("sdk/page-mod");
// Import the self API
var self = require("sdk/self");
 
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
  include: "*.org",
  contentScriptFile: self.data.url("my-script.js"),
  // Send the content script a message inside onAttach
  onAttach: function(worker) {
    worker.port.emit("replacePage", "Page matches ruleset");
  }
});

The replacePage message isn't a built-in message: it's a message defined by the add-on in the port.emit() call.

注入 CSS

请注意,本节中描述的功能是实验性的:我们很可能继续支持的功能,但可能需要改变的细节。

Rather than injecting JavaScript into a page, you can inject CSS by setting the page-mod's contentStyle option:

var pageMod = require("sdk/page-mod").PageMod({
  include: "*",
  contentStyle: "body {" +
                "  border: 5px solid green;" +
                "}"
});

As with contentScript, there's a corresponding contentStyleFile option that's given the URL of a CSS file in your "data" directory, and it is good practice to use this option in preference to contentStyle if the CSS is at all complex:

var pageMod = require("sdk/page-mod").PageMod({
  include: "*",
  contentStyleFile: require("sdk/self").data.url("my-style.css")
});

You can't currently use relative URLs in style sheets loaded with contentStyle or contentStyleFile. If you do, the files referenced by the relative URLs will not be found.

To learn more about this, and read about a workaround, see the relevant section in the page-mod API documentation.

Learning More

To learn more about page-mod, see its API reference page. In particular, the PageMod constructor takes several additional options to control its behavior:

  • By default, content scripts are not attached to any tabs that are already open when the page-mod is created, and are attached to iframes as well as top-level documents. To control this behavior use the attachTo option.

  • Define read-only values accessible to content scripts using the contentScriptOptions option.

  • By default, content scripts are attached after all the content (DOM, JS, CSS, images) for the page has been loaded, at the time the window.onload event fires. To control this behavior use the contentScriptWhen option.

To learn more about content scripts in general, see the content scripts guide.

文档标签和贡献者

 此页面的贡献者: addOn, ziyunfei, zhangby
 最后编辑者: addOn,