Building Cross-Browser Extensions with Kango and Backbone

A while ago I developed a service known as Mailican. The idea is simple. The service allows you to define aliases for your actual email. You can then control these aliases via Mailican. Unfortunately creating them can be a bit cumbersome at times as you have to create them through the service. As it happens there's a nice way to work around this problem: browser extensions!

I decided that the extension would create a popup with the list of current user emails. Here's an example:

Extension

To get list of available emails I had to connect to my application server via REST protocol. In order to make list flexible with ability to add new emails on the fly I decided to use a form in the top. And to manage all this things I included Backbone. It worked well for me and I must say it is great framework for such lightweight applications.

{{ screenshot: Kango }}

I chose Kango Extensions for creating extensions. Besides being free (except for IE), Kango is cross-browser. Unlike it's competitor Crossrider, Kango is just a build tool with a set of open APIs. In Crossrider you can develop only using a cloud IDE and all the apis are closed. I prefer to keep my code to myself and to work in local environment. Maybe Kango has less features, but at least I control and own everything I produce in this case.

Starting with Kango Extensions

Kango is easy to install. Just download it from official site and unzip somewhere.

From now on you can use kango console utility to execute tasks. We have only two here: create and build. But that's enough. Let's create a project:

~/kango/kango.py create ~/my_extension

By running this you will get folder my_extension filled with lots of folders and boilerplate code. Like on this screenshot (I added Backbone and Underscore later)

Files

We should stick to src/common folder which contains cross-browser code. Once you run

~/kango/kango.py build ~/my_extension

source code will be translated and placed to src/browsername folders of this dir. And packages will be stored in output dir.

Preparing Assets

The main extension file is src/common/main.js. I'm using it only to define popup style. In it you can store your background scripts which may stay alive all the time browser is running. But I need only popup to be shown. Nothing more.

It is important to notice that you need to set fixed width and height to your popup.

Currently only Chrome allows popups to be autosized. As defined a popup is taken from popup.html file.

Let's create it and include all required assets.

As you see we are using local path for JavaScript files. As you guessed that files should be placed into the same common directory. Kango APIs are available by default, but other libs you should download manually. You can take them from JSDelivr CDN for example.

I created popup.js file to place all JavaScript code in it. To use any of browser features we should stick to Kango API. For example, we need to use KangoAPI.onReady instead of the familiar jQuery.ready(). And to open links in a browser we need to access browser tabs apis.

Defining Models

For my extension I use 2 Backbone models: Mail and User. All their data were taken from 3rd party service. You can't use standard Backbone methods to run cross domain requests from extension. I redefined the fetch method of my models to work with Kango APIs. And here the User model I've got:

As you see, I'm rendering special SignIn view If user info can't be fetched.

Similarly I define model Mail model and MailCollection to represent a list of emails. They will be fetched and managed the same way.

I put corresponding fetch model into MailCollection. In final script this collection was too long, so I won't post it here.

Working with Views

At first we need to define all templates in popup.html. I'm using Underscore templates so nothing new here:

I attached events to represent model fetching, and creating a new emails over form. When new email is created I submit POST request via kango.xhr and attach email to list if everything is successful.

Make it work together

When models, templates, and views are defined we need to launch them. It can be done in cool async way:

To try your new extension in a browser you should execute ~/kango/kango.py build ~/my_extension. This will produce packaged extensions to all 4 browsers. I used Chromium as a primary tool to develop and debug my extension. Open Extensions tab then drag and drop your newly created *.crx file placed in output folder.

chromium

To debug your popup you can use Chrome DevTools. Launch them by right-clicking on your extension button.

menu

Yes, manage popup. Also consider using Backbone Debug script see all model views interactions in console.

Conclusion

I didn't use much of Kango Extensions API in these examples. I found them well documented, though. And you can use them as a wrapper for browser messaging or storage APIs. Kango Extensions works smoothly and output extensions worked well in all tested browsers. BackboneJS allowed me to keep my code structured and to work well with data.

The day I wrote this post Kango Extensions 1.2 were released. And that's great news! I wish good luck to this project, more features and more popularity. Thanks, Kango for my new Mailican extension. I still need to publish it in all the browser extension catalogs, but that's another story.