The last two posts described MediaPlus as a Chrome and an Opera extension. To extend the browser matrix, MediaPlus is now ported to work as a Mozilla Firefox extension. As described in the previous post, the core functionality of MediaPlus is to interact and change the contents of the web page. The peripheral functionality like stopping the plugin, re-scanning the page, etc are invoked using the browser addon UI.
The MediaPlus add on for Firefox uses the new Jetpack way to write "no-restart" plugins. The concepts are very similar to writing extensions on Opera or Chrome -
- A singleton background page that runs as a background process. For firefox, this is the lib/main.js CommonJS module.
- Pop out icon and the corresponding pop out panel defined in the main.js file.
- Content Scripts, also defined in the background page.
First, there is no direct way to inject script into webpages dynamically. Though the page_mod allows script injections into the web page, the page_mod cannot be changed to add more scripts later. Unfortnately, page_mods also do not share the execution context and hence, cannot communicate in a straightforward way. Hence, scripts are added to the webpage when the pop out are clicked using the tabs.activeTab.attach method by adding a script tag to the page. The source of this script is obtained using the data.url method, relative to the extension.
To communicate with these added scripts, the (ugly) unsafeWindow method is used. Since no "trusted" addon methods are leaked while using the unsafeWindow, the security concerns should be addressed.
The scripts added in this way are inserted into the page immediatly. This turns out to be a problem if the target webpage is still loading. Once the web page finishes loading, all the injected scripts are replaced with the new content. The icon needs to be clicked again to start the add on. Though the tabs.on(ready) method exists, this is only invoked once the page has completed loading. Hence, we would need logic to re-load the scripts again, when the onReady (DOMContentLoaded) event is fired. I could also not find a way to unbind this event and hence, this seems to be fired for every navigation on the web page; another ugly solution. The onready could remember the all the tabs for which it was fired, but that it just too much housekeeping for now. For now, you would have to click on "Start MediaPlus" again, after the page has loaded to activate it.
Though the message passing was not as simple as Chrome, it looked better than the way things are done in Opera, with custom events in addition to the message channel.
The source for Firefox extension is available here and you can download the addon from here. Follow this space for updates on MediaPlus as a bookmarklet or as an extension for browsers. If you have suggestions or have found bugs, you can contact me here for help.
I have also made the statistics for the addon public and you could see the number of users, downloads, etc here.