In addition to this core functionality, MediaPlus also has additional actions like stopping it, rescanning the page for dymanically adding content or simply turning off full screen. In case of the bookmarklet, these actions are initiated by clicking the bookmarklet again. In the case of an extension, these options can be available off an icon in the browser UI, outside the web page.
The Google Chrome extension does exactly this - the core functionality is handled by a content injected into the web page while the peripheral functions are displayed in a pop out panel as a part of the browser UI. Writing an extension using Opera is very similar to writing a Chrome extension. In short, the extenion has three basic parts
- A singleton background page with scripts, included in index.html and the background.js referred in the index file.
- Pop out button and corresponding popout.html, defined in the index.html
- Content script in the includes directory that are injected into all web pages.
There are also two differences and here is how they are solved for the Opera extension. First, passing messages between the pop out and the content script is not simple and requires a background script to broker the connection the first time. This article explains how it is achieved.
The second issue is that external stylesheets scripts are not injected into the page using API calls, but by placing the script inside the includes folder. This unfortunately means that it is harder to inject dynamic scripts in a page. The first version injects scripts by referring to external URL, but this practice is frowned upon. The latest version does the following. The scripts can be injected by reading them using XHR using paths relative to the extension root and inserting them as textContent of script tags in the web page. Since the content scripts seem to have access to the global window object of the web page, they can communicate with the injected scripts. Note that Google Chrome separates the execution context of the web page and the content script.
To load images dynamically, they are added as img elements in the background page, drawn on a canvas, and the base64 data:url returned by the canvas.toDataURL is passed back to the content script. The content script sets the data:uri as the source of the image to be drawn. Background images referred using external stylesheets are still not loaded. External stylesheets (like jquery UI css) have to be changed to have data:uri before building the runtime.
The Opera extension is available for download here and source code is available here. To follow MediaPlus, check out this page.