5.3 KiB
Modifying the Page Hosted by a Tab
To follow this tutorial you'll need to have [installed the SDK](dev-guide/tutorials/installation.html) and learned the [basics of `cfx`](dev-guide/tutorials/getting-started-with-cfx.html).To modify the page hosted by a particular tab, load a script into it
using the attach()
method of the
tab object. Because their job is
to interact with web content, these scripts are called content scripts.
Here's a simple example:
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var widget = widgets.Widget({
id: "mozilla-link",
label: "Mozilla website",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
tabs.activeTab.attach({
contentScript:
'document.body.style.border = "5px solid red";'
})
}
});
This add-on creates a widget which contains the Mozilla favicon as an icon.
It has a click handler which fetches the active tab and loads a
script into the page hosted by the active tab. The script is specified using
contentScript
option, and just draws
a red border around the page. Try it out:
- create a new directory and navigate to it
- run
cfx init
- open the
lib/main.js
file, and add the code above - run
cfx run
, then runcfx run
again
You should see the Mozilla icon appear in the bottom-right corner of the browser:
Then open any web page in the browser window that opens, and click the Mozilla icon. You should see a red border appear around the page, like this:
Keeping the Content Script in a Separate File
In the example above we've passed in the content script as a string. Unless the script is extremely simple, you should instead maintain the script as a separate file. This makes the code easier to maintain, debug, and review.
For example, if we save the script above under the add-on's data
directory
in a file called my-script.js
:
document.body.style.border = "5px solid red";
We can load this script by changing the add-on code like this:
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var self = require("sdk/self");
var widget = widgets.Widget({
id: "mozilla-link",
label: "Mozilla website",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
tabs.activeTab.attach({
contentScriptFile: self.data.url("my-script.js")
});
}
});
You can load more than one script, and the scripts can interact directly with each other. So you can load jQuery, and then your content script can use that.
Communicating With the 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.
To send a
message from one side to the other, the sender calls port.emit()
and
the receiver listens using port.on()
.
- In the content script,
port
is a property of the globalself
object. - In the add-on script,
tab.attach()
returns a worker object containing theport
property you use to send messages to the content script.
Let's rewrite the example above to pass a message from the add-on to the content script. The content script now needs to look like this:
// "self" is a global object in content scripts
// Listen for a "drawBorder"
self.port.on("drawBorder", function(color) {
document.body.style.border = "5px solid " + color;
});
In the add-on script, we'll send the content script a "drawBorder" message
using the object returned from attach()
:
var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var self = require("sdk/self");
var widget = widgets.Widget({
id: "mozilla-link",
label: "Mozilla website",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
worker = tabs.activeTab.attach({
contentScriptFile: self.data.url("my-script.js")
});
worker.port.emit("drawBorder", "red");
}
});
The drawBorder
message isn't a built-in message, it's one that this
add-on defines in the port.emit()
call.
Injecting CSS
Unlike the page-mod
API,
tab.attach()
doesn't enable you to inject CSS directly into a page.
To modify the style of a page you have to use JavaScript, as in the example above.
Learning More
To learn more about working with tabs in the SDK, see the
Open a Web Page
tutorial, the
List Open Tabs
tutorial, and the tabs
API reference.
To learn more about content scripts, see the content scripts guide.