Chrome LogoSome Background

So I’ve been discovering a lot of new music using Plug.dj.  It is a site that is very similar to turntable.fm.  For those not familiar with either of these sites turntable no longer exists and Plug.dj has stepped in to takes it’s place.  The basic premise of the site is that users have an avatar and play music in a booth style to room with a particular genre/flavor of music.  People in the room can then vote whether they like the track being played or not. Built into the room is a chat for users to talk to one another.  As I have music playing in the background while I work and even have a bunch of coworkers that use it as well and we have our own room to share music throughout the day. As we had our own room I wanted to customize it with a custom background and the easiest way of doing some seemed to be a Chrome Extension. The background was super easy to accomplish as it only needed a tiny bit of CSS. I had some improvements I wanted to add such as sending a desktop notification with the song information every time a new song comes on so I don’t have to go to the room to see it. Also I was missing a lot of chats when people @mentioned me because all that happens is a small sound. So this extension for just my coworker and I to have a cool background in our room evolved to Notification Handler for Plug.dj called simply ‘Plug Notify‘.

The Extension

I had never built a Chrome extension before and assumed swapping a background-image on a single page would be a good start to get a barebones extension to test the waters out. So to get the basic or Extension development I checked out the documentation from google and got a local extension set up. The main things are getting developer mode on and setting up a manifest file to pull in the resources you will need. This will include the CSS, images and JavaScript. One thing to caveat is that I am manipulating the Plug.dj page with my JavaScript so I will only include a JavaScript file in my manifest to inject another JavaScript file to the page.

So I wanted to get my JavaScript to run on the page as usual. This is the only other real set-up step that is not typical of chrome extensions.  If you list a JavaScript file via the extensions resources it’s scope will be to the Extension. So in my extension I injected a script to the page. Now the script that is being injected has the same scope as the pages like on any web application.

The Guts of It

The only other obstacle I had to overcome was the fact that Plug.dj loads each room with AJAX and thus their API is loading after my injected script. The logic is simple and check with a setInterval whether the API is defined as an object or not.

The rest of the development for the project went very smoothly though using the Plug.dj API for event listeners when to fire off notifications.  I only used two events ‘ADVANCE’ and ‘CHAT’. These fire of the notification with the song information when a new songs starts playing and checks each line of chat for the users mention respectively.

The real fun part of this was playing with the Web Notifications API which is still in a Working Draft state. These worked with relatively no problem.  Also as this project is in a Chrome Extension it was a safe assumption that anyone installing it has current enough version of chrome which supports this. The Mozilla Developer Network has some documentation on this API which as of writing this seems to be accurate. I plan to write another blog post this week which will dive more in depth into this new API and a link will be posted when that is complete here.

Another feature specific to Chrome is the highlighting of a pinned tab.  This is triggered whenever the title attribute of a page is changed and can be seen if one pins a GMail or Facebook tab and gets a chat message. This is simple achieved by updating the title it will flash each time it’s changed so to have it continually flash a setInterval to change the title back and forth is used. If the tab isn’t pinned the title is changing so that is a still a good visual indicator of the notification.

What I’d Improve

There are a few feature requests I’ve had from users which are listed as I receive them in the readme of the repo.  One thing I did attempt and failed to accomplish was containing this in a self-invoking anonymous function as one would do with any plug-in.  This failed because I am using jQuery in my code and I can’t pass it through as one would usually because of a load order issue being created with Plug.dj’s use of Require.js. This I believe to be loading in all the needed libraries and the inject script I am dumping into the page is injected before jQuery can be defined. Not a problem when used in my main.js file because all the call of jQuery are happing after library is available but since the function is defined and invoked immediately passing through jQuery (ideally) it does not yet exist to pass through as a parameter.