Comments On Code

Apr 16, 2014

Building a Browser Extension

I just finished cleaning up a relative's computer...again.  It seems nearly impossible; how can a computer that is barely ever used, and has had almost no software downloaded (almost!) be so corrupted with malware that it ceases to function?  I can solve this.

So many unwanted programs or unwanted newsletter subscriptions ride along with programs that are intentionally downloaded, just because the user neglects to uncheck the boxes before hitting the download button.  I'm convinced most people don't even see them there.  What if there was a browser setting that would remove default checked off boxes?  Sure would be nice.  Unfortunately, no such thing exists.  The Chrome extension store does offer a couple extensions that can uncheck or check all boxes on a given page, but it requires an intentional action on the part of the user, i.e. remembering to click the extension button.

Never having contemplated writing an extension before, I had no idea what the process might entail.  Surprisingly, Chrome extensions are mostly written in code I understand.  Depending on the purpose of the extension, you can supply CSS, HTML and/or Javascript.  While it took a little bit of experimenting to achieve the result I desired -- an unobtrusive script that ran on any form page without user input -- with a little help from a few websites, we were in business.

The Process

The first step was perfecting the script.  My script needed to identify that the page was a form, then go about removing any "checked" attributes that might exist* .  This is about as simple of a little JavaScript piece as they come.  I wrote a form with a few checkboxes and attached my script in the usual way, and tested to be sure I could still select the check box and send without any issues.  Once that was perfected, I removed the script and reset my form for testing when I installed the extension.

On to building the extension.  Chrome offers a very brief introduction to one type of extension.  While it is not exactly what I was interested in building it does introduce the most important, and most unfamiliar to me, piece of the extension puzzle, the manifest.json document.  This is the document that tells Chrome all about what you're building, where to locate the necessary files, and on which websites to run the extension.  Understanding the areas of this document is the key to building the type of extension you want and getting it to work.  Cory Gross has an excellent resource on Github that details aspects of these manifest settings.  Once you've decided what type of extension you are interested in building, you can start creating documents.

As intimidating as that sounds, this is actually the easiest step of all.  Alex Wolkov has written a tool that will build the extension's document structure, including inserting the default fields you need in the manifest.json document.  Each setting also includes a popup window on hovering over the (?) that offers a short explanation of the selection, and links to the Chrome developer page with more detailed instruction.  Upon downloading, open the manifest in a text editor and edit the fields.

In my example, I needed to edit only two documents, the manifest and the inject.js.  The trickiest bit was ensuring that my script would run on all web pages.  This setting falls under the content scripts->matches.  The tool automatically inserts a url to match all google pages, so editing that can be overlooked.  Google lists all the possible forms of match patterns for reference.  My script uses <all_urls>.

The next hurdle was placing the right section of code in the inject.js file.  The file is explicit about where the script should go.  Just strip the function call and drop in the actual script and it is all set.

Finally, create a set of icons to drop into the icon folder.  The icons are png files, so any image editor will do.  Create the largest size and then resize and save each smaller size.

Testing

Chrome makes it extremely easy to install an extension in development.  Navigate the settings -> tools -> extensions, just as you would install any extension.  At the top of the page is a checkbox to open the developer menu.  From there you can install an unpacked extension by navigating to your folder in which the extension lives.  On installation, Chrome will alert you to anything in the manifest that isn't formed correctly.  A little debugging and Google searching can help you fix those errors.

At this point, it's time to return to our test website we created when writing the script.  Be sure that you removed the link to the JavaScript file so that you can test the extension only.  It also may be helpful to disable any other extensions within the extension manager that you might be using because Chrome does not identify the extensions by name in the developer panels.  Using the Inspect Element tool (right click, Inspect Element), click the Sources tab and then the Content Scripts tab.  Reload the page if nothing shows up.  If still nothing appears, you need to return to the manifest.json and check that the matches section is properly formed to attach to the page as intended.

You should see a filename with a bunch of random letters.  If you've turned off all the other extensions, then you know this is your extension.  Opening the disclosure arrows will display files that make more sense.  If you are using an inject script as I have been, you will be able to navigate to the inject.js file and display your code (if creating another type of extension, the filename will be different, but you will still access it here).  You can debug this code, if necessary, just as you would debug any other JavaScript code in the browser.

Congratulations, you've built an extension!

Your extension can be installed and used as an unpacked extension with the files living locally on the computer.  It continues to function with the developer window in the extension manager closed, but may alert the user that a "possibly harmful" extension is installed every time the user opens the application.

Coming Soon...How to Publish your Extension.

*The actual script is beyond the scope of this piece, but I will update when the extension is available in the Chrome store for anyone interested.