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:
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)
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: works well.
In popup.js
we should use Backbone Views to represent templates:
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.
To debug your popup you can use Chrome DevTools. Launch them by right-clicking on your extension button.
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.