Every day I find myself in need to track four things: Github pull requests, Flowdock messages, continuous integration build status (by Travis-ci), emails.
When I discovered a cool Chrome extension for Gmail, I realized the potential extensions have in increasing my productivity. I decided to search for more extensions that will do the same.
Unfortunately, it was not an easy task.
Either an extension did not exist or it did not display the data in a way that helped much.
Changing the face of DevOps. Cloudify glues it all together. Go
However, all the services I use have an API that is accessible to me.
So I decided to take a small journey and investigate how hard would it be to write my own Chrome extension that would suit my needs.
Turns out that after a small learning curve you can feel right at home since chrome extensions use js, HTML and CSS. plus the Chrome API is very easy and simple to get started.
While there are many ways to actually write an extension, I will focus on one that suited me best and only mention the others briefly.
We will use the Flowdock’s example for the sake of this post. the code is available at: https://github.com/guy-mograbi-at-gigaspaces/flowdock-chrome-extension
Here at Cloudify we’ve actually done some more work on Flowdock. You can find the code on Github.
The three pages of a Chrome extension
Every Chrome extension has three pages available for its implementation
- Popup – the page displayed when you press the extension icon
- Options – the page displayed when you right click the icon and click ‘options’
- Background – a page which simply runs in the background and is only accessible from the ‘manage extensions’ section in chrome by clicking the ‘inspect <your background page name>’
The three pages can communicate by messages, and keep data by using the chrome api (or some online service).
Choose your favorite toolset
I also really like Yeoman and its generators, they really help kickstart a project, so I wrote one for my future Chrome extensions and it is available at: https://github.com/guy-mograbi-at-gigaspaces/generator-angular-chrome-extension
I also used the following libraries:
- Materialize.css for its exquisite taste in design and ease of use. thanks materialize!
- Lodash for processing data
I strongly recommend using Angular as it saves tons of time thanks to its amazing two way binding, plus it is really easy to set up for small projects.
Define you manifest file
In order to have a full work cycle, you first need to declare your files in the extension manifest
Not much happening here, pretty generic. the important thing to note is the definition of the three files mentioned above: options, popup and background.
The popup page
As you can see I have set up a regular HTML file with an Angular app. There are also comments for the Grunt build process to minimize files.
The special part is in
- scripts/chrome.js – this is a mock for chrome’s api which only works if the API is unavailable.
- scripts/popup.js – this is the actual Angular app
The page will paint messages from Flowdock on the page in a simple list.
Background and options HTML files will actually look the same, so I will allow myself to skip them. (the code is available in Github).
The popup.js script
On the surface this looks like a regular Angular app but there are several interesting things going on here:
- We are using the chrome API through a wrapper, injected as an Angular service. This service will actually work outside the extension environment as it mocks the API when needed.
- We are listening for messages and then update the data when a message with data arrives.
- We send a message requesting to get an update – this code will run once a popup is opened.
- We are also loading mockData for development.
So far things are pretty straightforward. Let’s have a look at the options script.
Thanks to Angular taking care of two-way binding, all we are left with is loading the data when the page loads, and saving it with a save click.
The HTML will define some inputs fields that will save stuff on scope.
The background.js script
The background.js differs from the others in that it sets an $interval to run every X time.
What Chrome does is start a process for each extension and run the background page on that process. so if your background page does a lot of computations, you will feel it. Make sure to make it do something every now and then, but mostly rest.
I have set it to get my messages from Flowdock every 10 minutes sounds harmless to me.
The method used to read Flowdock’s message is out of the scope for this post. you are welcome to check the code in Github.
The Chrome extension API
So far, all we’ve seen are regular HTML and js files that given a magical api for messages, badge text and save/read configuration look pretty normal.
The glue to make everything work together is the Chrome service.
This file basically wraps the chrome API and defaults to either log prints or some naive implementation.
For example, saveConfig will keep data in Chrome using chrome.storage.sync.set – but if that’s not available it will use the local storage. The same goes for readConfig.
This gives me a way to experience an almost complete flow in my extension while running it from a regular HTTP server.
I will spare you the reading of Grunt’s lengthy configuration. The Gruntfile basically does the following:
- Lints my js files with jshint
- Compiles my sass files when they change
- Copies files to dist folder
- Compresses dist folder to zip
It also updates the version in the manifest file.
Basically, everything it does on your everyday web project, plus some manifest maintenance for Chrome.
Putting it all together
Once you finished writing your extension, all you need to do is compress it, open the “manage extensions”, then drag and drop your zip file there, and you will get a new icon on your extensions bar.
If you run into any problem, you can easily debug your scripts by inspecting each page.
Popup and options are pretty straight forward to inspect, while background is available for inspection from the ‘extensions’ section in chrome (as shown above).
Pain & gain
OMG! This task is all gain and no pain. Perhaps some pain in making the Flowdock API work, but that’s actually my fault :).
Chrome’s API is so intuitive, by putting an effort of 10 hours of learning curve – and that’s a serious over-exaggeration now – and a couple of hours of coding the extension, you save yourself hours of work every week.
And now that I have a generator and working code samples, case closed! Just give me more things to track and monitor..