Day: August 21, 2012

Some things to remember when writing Chrome extensions (Part 2):

I recently built a chrome extension. It maps craigslist housing searches onto a map. This is a two part blog post on a few things I’ll keep in mind when writing more Chrome extensions. This is the second post and will talk about specifics about how different parts communicate with each other. Of course the official api reference probably does a better job, but this summary is as much for me as it is for you.

Message passing and organization:
This is the part that took the longest to understand because there a bunch of commands provided for sending messages between content scripts, background scripts, outside scripts, inside scripts, scripts that your grandma wrote and that doctor’s prescription for your hamster’s stress knee pain.

So here’s how I did it. Two parts to each message – sending, and receiving:
From a content script to a background script:
In the background.js, the following umbrella method:

"chrome.extension.onRequest.addListener"

.
In the content.js, the following single call:

chrome.extension.sendRequest('data', function (response) {/* do stuff if needed */});

From the background script to content:
In the background.js, a single call with:

chrome.tabs.sendMessage(tab.id, {message: 'addAdToMap', data: this.adData}, function() {/* do stuff if needed */});

The following umbrella method to handle them all in the content.js:

chrome.extension.onMessage.addListener( function(request, sender, response)

From content scripts to iframes that live inside the content
Whoa. Doube-you Tee Eff, mate. Why would you do this? Why, I’m glad you asked: The reason you’d want to is because Chrome is a bully that protects you from bullies. Seriously this made me refactor my whole extension.
From the content window to the iframe:
In the content.js:

mapAway = function(location, data) {  
  var iframe = document.getElementById('mapFrame');
  var message = {
    command: 'mapMe',
    mapData: {
      mapLocation: location,
      mapData: data
    }
  };
  iframe.contentWindow.postMessage(message, '*');
}

In the iframe’s js, the following umbrella method:

window.addEventListener("message", function(event) {

From iframe to content scripts the following:
In the iframe.js:

  var message = {
    command: 'ready'
  }
  window.parent.postMessage(message, '*');

In the content.js the following umbrella method:

window.addEventListener("message", function(event) {

More to come as I think. I almost feel like this post is therapy for me and help for you. And help for me the next time I write an extension. Also, here’s the code to my extension. It makes use of all the different types of message passing described above. So, I hope it helps!