This article needs a technical review. How you can help.
This article needs an editorial review. How you can help.
Loading frame scripts
To load a frame script use the
This line of code loads a frame script into the currently selected tab. The frame script just write "foo" to the command line:
// chrome script var mm = gBrowser.selectedBrowser.messageManager; mm.loadFrameScript('data:,dump("foo\n")', true);
loadFrameScript() takes two mandatory parameters:
- a URL pointing to the frame script you want to load.
- a boolean flag
Extension developers can use a "chrome.manifest" file to register a chrome URL. This defines the mapping between the
chrome:// URL and a frame script packaged with the extension:
// chrome.manifest content my-e10s-extension content.js
// chrome script mm.loadFrameScript("chrome://my-e10s-extension/content/content.js", true);
Note that if the message manager is a
ChromeMessageBroadcaster (for example, a global frame message manager or a window message manager) then
loadFrameScript() may load the script multiple times, once into each applicable frame.
true, the frame script will be loaded into any new frames opened after the
loadFrameScript()call. For example:
var mm = window.messageManager; mm.loadFrameScript("chrome://my-e10s-extension/content/frame-script.js", true);
The script will be loaded into all tabs currently open in this window, and into any new tabs opened afterwards.
false, then the script will only be loaded into frames that are open when the call is made.
If the message manager is a browser message manager, you should just always pass
true here. Because a browser message manager only ever corresponds to a single browser tab, its
loadFrameScript() function will only ever load the frame script into that one tab. So passing
allowDelayedLoad is just a way to ensure that the script gets loaded properly, in case the tab is not ready when you make the call.
If you use
allowDelayedLoad, with a
ChromeMessageBroadcaster, you can cancel it using
var mm = window.messageManager;
This means that we will stop loading the script into new tabs. Note that this function will not remove any scripts that have already been loaded.
Frame script lifetime
Frame scripts are loaded as soon as
loadFrameScript() is called. If you've set
allowDelayedLoad, the script is loaded into a new tab as soon as it is created.
Frame scripts are associated with a browser tab, not with a page. So once you load them, they stay loaded until the tab is closed, even if you reload the document or navigate.
If you want a frame script to do something whenever a new document is loaded, you can listen for the
Unloading frame scripts
Frame scripts are automatically unloaded when the tab hosting them is closed. There is currently no way to unload them once you have loaded them, other than closing the tab they were loaded into.
When your add-on is uninstalled or disabled, you should:
- if you used
allowDelayedLoad, cancel it by calling
removeDelayedFrameScript, to ensure that the frame script is not loaded into any new tabs.
- disable any frame scripts that are already loaded. There is no mechanism to unload frame scripts that are already loaded, so you need to send a message to your frame scripts telling them to disable themselves (for example, by undoing any changes they've made or removing any event listeners).
Note: you might think that there is a race condition here due to the asynchronous nature of the message passing:
- your add-on is disabled for an upgrade
- your add-on broadcasts "disable" to your frame scripts
- your add-on is upgraded, and the new code loads new frame scripts
- the new frame scripts receive the "disable" message, and stop working
In fact, the message manager guarantees that
broadcastAsyncMessage are guaranteed to affect frame scripts in the order that they are called, so in this case "disable" will be received and consumed before the new frame scripts are loaded.
At the moment frame scripts are cached until the browser restarts: this problem is tracked as bug 1051238. This is especially a problem for restartless add-ons, because when a new version of the add-on is installed, the old frame scripts will not be unloaded. The workaround here is to randomize the frame script's URL, for example by appending
"?" + Math.random() to it.