Message-based Chrome Extension incorporating JQuery

by Paul Heath on May 9, 2010

I have a Twilio Tweet to thank for getting me involved in the whole idea of exploring chrome extensions.

Chrome Extension Popup

Chrome Extension Popup

Intrigued, I looked at a few videos on “how easy” it was to build a Chrome Extension, so I set forth.

In the end, it’s really not tough, although there was some fiddling to do and debugging was a bit of a challenge – this article nets out the key components.

In the past, I’ve developed some image-intensive vacation sites – it is well known that populating ALT and TITLE tags are good for SEO and user experience. With that in mind, I thought it would be (somewhat) useful, as an exercise, to be able to get a snapshot of all the images on a given page and examine the IMG tag attributes. Let’s call it the Image Grabber.

I also wanted to incorporate some JQuery code into the mix, since it offered another useful dimension when ultimately building a real extension.

Image Grabber – Pieces and Parts

The basic components for this exercise are:

Image Grabber Code Listing

Image Grabber Code Listing

  • A manifest.json file which serves as the “config file” to wire everything together.
  • Initial HTML file (popup.html) which is the display portion of the extension. This also some contains some Javascript – more on that later
  • A javascript file (contentscript.js) which contains the code to inspect the target web page you are on. This is known as a “Content Script” and is “injected” (see NOTE below) into the target page automatically
  • The JQuery core library which will also be injected into the target page.
  • An icon file (icon.png) to represent the existence of the extension (there is one in the included zip archive of the code)

NOTE: The content scripts are injected into any web page when it loads (according to certain rules in manifest.json). HOWEVER, they are not really injected into the page, they are injected into what Google calls an “isolated world” meaning the scripts have access to the target page’s DOM, but exist separately so that no damage can be done to the page – think of it as a parallel universe.

Image Grabber Basic Flow

Put a button on popup.html to initiate the business end of the extension and ultimately display the result

Create a “long-lived” (as opposed to one time) connection  between the popup.html page and the content script (contentscript.js) so that they can message back and forth with each other.

The contenscript.js has the job of (1) receiving instructions from popup.html (2) grabbing the dom elements and populating an array and (3) returning the array.

Image Grabber Code

manifest.json

{
"name": "Image Grabber",
"version": "1.0",
"description": "Pulls out the images and associated attributes from the page",
"browser_action": {
"default_icon": "icon.png",
"popup": "popup.html"
},
   "permissions": ["tabs"],       // This is needed to programmatically determine the current browser tab
   "content_scripts": [
      {
         "matches": ["http://*/*"],
         "js": ["jquery-1.4.2.min.js", "contentscript.js"]
      }
   ]
}

Popup.html

HTML Fragments

<input type="button" id="but1" name="but1" value="Get Page Images" />
<p>hello, this is the popup</p>

Javascript Fragments

function getDomElements(elemType) {
   chrome.tabs.getSelected(null,function(tab) {
      var port = chrome.tabs.connect( tab["id"] );
      port.postMessage({mycmd: elemType});
      port.onMessage.addListener(function(msg) {
         if (msg) {
            $('#output').html( formatOutput(msg.result) );
         }
         else {
            $('#output').html("Got Nothing");
         }
      });
   });
}

function formatOutput (a) {
   var j=0;
   var out="";

   out = "" + a.length + " IMAGES FOUND" + "<br><br>";
   while (j<a.length) {
      out +=  "ID= " + a[j].id + ", Name= " + a[j].name + ", Title= " + a[j].title + ", ALT= " + a[j].alt + "<br>" + "<img src=" + a[j].src + ">" ;
      j++;
   }
   return out;
}

$(document).ready(function() {
   $('#but1').live("click", function() {
      getDomElements("img");
   });
})

contentscript.js

// ”bean” to house the img attributes
function domobj(src,name, id, title, alt) {
   this.src = src;
   this.name = name;
   this.id = id;
   this.title = title;
   this.alt = alt;
}

// Scan the DOM for IMG tags and assemble the attributes into an array

function getImages () {
   var imgArray = new Array();
   var i=0;
   $.each($('img'),function() {
      imgArray[i++] = new domobj(this.src, this.name, this.id, this.title, this.alt);
   })
   return imgArray;
}

// Setup a “long-lived” connection with the extension (in our case, popup.html contains the other side)

var port = chrome.extension.connect();

chrome.extension.onConnect.addListener(function(port) {
   port.onMessage.addListener(function(msg) {
      if (msg["mycmd"] == "img") {
         var imgArray = getImages();
         port.postMessage({result: imgArray });
      }
      else {
         port.postMessage({result: []});
      }
   });
});

Now that you have an overview of the various pieces, you can download the Image Grabber Extension code and drop it into a directory. From there, launch the Chrome browser, click the Tools menu, and then Extensions. Click the leftmost button “Load Unpacked Extensions” and when asked, point to the directory containing your files. Once the extension is loaded, go to the tab containing a site with images and then click the icon in the top right of the browser. NOTE: You may need to reload the page, then click the extension icon.

The above is not a production extension – just an example of the components needed to construct one. I hope it accelerates your progress when cobbling yours together.

{ 1 comment… read it below or add one }

Molly June 9, 2010 at 11:21 am

I just built mine too, fabulous suggestion!

Leave a Comment

Previous post: