Building Speed Dial Extension with Require.JS and Mustache
Saturday, April 28, 2012 8:42:44 PM
But today we are developing Opera extension. What does it mean? All JavaScript files are already on clients computer. Loading multiple files can still take little longer than loading one big js file, but the time necessary to establish connection and send the data is no longer a problem. This give us a chance to build our extension more cleverly.
One option is to use a plenty of script elements. Luckily, there is also other faster and more elegant way. It is called Require.JS. It provides API to load other js files as modules, have good grasp of dependencies and it prevents global pollution.
Let's take a glance at the simplest example. Only script tag you must have in index.html looks like this:
<script data-main="scripts/background" src="scripts/require.js"></script>
Where require.js is the file that does all the magic and you can download here: http://requirejs.org/docs/download.html
and scripts/background is background.js file where all your js stuff begins.
There is excellent short tutorial on how to use Require.JS on the official site. I sincerely recommend you to read it through as I am not going to explain much how to use it + I'm going to show you only basic usage. Require.JS can do more.
What we are going to do is a simple RSS Speead Dial extension. You can find the whole source on Github.
I let creating config.xml file on you as there isn't anything new. We have also already described the only important thing in index.html, otherwise it is just simple basic skeleton:
<!DOCTYPE html> <html lang="cs" dir="ltr"> <head> <meta charset="utf-8"> <title>RSS Speed Dial</title> <link rel="stylesheet" href="styles/sd.css"> <script data-main="scripts/background" src="scripts/require.js"></script> </head> <body> </body> </html>
Require.js and background.js are not the only files we need. Please download following files and put them all in the "scripts" folder.
- "Text" plugin for require.js to load Mustache templates
- "DomReady" plugin for Require.JS. Because Require.JS loads scripts asynchronously we can't use DOMContentLoaded event. Instead we can use this.
- Mustache adapted for Require.JS
Now is our part to program something. We will need to create four files. JS file with some simple AJAX library to load the RSS file. Template file for Mustache that will define the structure of data we are going to display. CSS file to define the looks. And finally the background.js file which will use it all and make it works together.
I'm not going to show you here the ajax and css file because they are not important. If you want to use the same files as I did you can download them on Github.
- CSS
- AJAX library
Template (item.tpl):
{{#items}}
<div class="item" data-url="{{url}}">
<div class="date">{{date}}</div>
<div class="title">{{title}}</div>
</div>
{{/items}}
backgrounds.js:
// load all dependencies
require(['ajax.mod', 'mustache', 'text!item.tpl', 'domReady!'], function(AJAX, Mustache, template, d) {
var
c = AJAX.create(), // use AJAX library to create new connection
sd = opera.contexts.speeddial,
b = d.body
;
loadRSS();
setInterval(loadRSS, 15e4); // load RSS file every 150 seconds
setInterval(scrollWindow, 1e4); // load next RSS item every 10 seconds
function loadRSS() {
try {
c.getData('http://feeds.feedburner.com/FavoriteBrowser', handleSuccess, handleError, false);
} catch(e) {
console.log('RSS Error: You are probably offline. Retry in 150s.');
}
}
function handleSuccess(e) {
// Prepare data object for Mustache
var data = { items: [] };
[].forEach.call(e.XML.querySelectorAll('item'), function(val, i) {
data.items[i] = {
title: val.querySelector('title').textContent,
date: val.querySelector('pubDate').textContent,
url: val.querySelector('link').textContent
};
});
// set url and title of speed dial item
sd.url = data.items[0].url;
sd.title = e.XML.querySelector('channel title').textContent;
// render Mustache template
b.innerHTML = Mustache.render(template, data);
}
function handleError(e) {
// File couldn't be loaded
console.log(e.text);
b.innerHTML = 'Error: RSS is not loaded';
}
function scrollWindow() {
// Move first element to last position - moves the second one to top
if (b.firstElementChild) {
b.appendChild(d.body.firstElementChild);
sd.url = b.firstElementChild.dataset.url;
}
}
});
The real work here is only the 50 lines above and you have working RSS Speed Dial extension for Opera.
Install the extension and the result should look like this:
Yes, we had to download and use quite a lot of files for extension as simple as that. But this is the ground for extensions of any size and complexity. And as will your extension grow you will more and more appreciate the possibility to use multiple files with dependencies.
This tutorial alone probably won't help you much you will need to study the Require.JS API and try to play with it a bit. I believe you will find it very exciting!














Martin KadlecBS-Harou # Saturday, April 28, 2012 8:51:50 PM
http://files.myopera.com/BS-Harou/files/RSS%20Speed%20Dial.oex
metude # Sunday, April 29, 2012 7:58:29 AM
Mağruf ÇolakoğluZAHEK # Sunday, April 29, 2012 9:25:21 AM
Nimesh nimeshthakkar # Sunday, April 29, 2012 5:01:51 PM