Chrome Extension: Adding Context menus

This is the final part of the “Buzz This” Chrome Extension series, in the first post I showed you how to create a basic Chrome Extension. We then expanded on it in the 2nd post showing you how to use XHR and some advanced features of browser_actions.

In this post, I will show you how to quickly integrate Context Menus into Chrome Extensions. Why am I integrating Context Menus? Because they are a powerful hook in to your extension, and I want to be able to let users “Buzz” about specific things on any page, for instance, if they find an interesting image, they can Buzz just that rather than the entire page. It is pretty powerful.

The code is pretty simple, and should show you how easy it is to get started.

Context menus are pretty powerful and have the ability to be present through-out the life time of a users browsing experience, as such you must declare in your manifest the intention to use Context Menus. It is a pretty simple addition to the “permissions” array in the manifest.

{
  "name": "Post to Google Buzz",
  "version" : "1.0.0.6",
  "icons" : {
    "16" : "buzz-little.png",
    "128" : "buzz-big.png"
  },
  "background_page" : "background.html",
  "browser_action": {
      "default_icon" : "buzz-little.png",
      "default_title" : "Post to Google Buzz"
    },
  "permissions" : [
    "tabs",
    "contextMenus",
    "http://www.google.com/buzz/api/buzzThis/buzzCounter"
    ]
}

Now that we have specified the requirement to use Context Menus, the user will be alerted to the fact when they install your extension.

Simply asking for permission is not enough, you need to also add some code that will tell the browser when to display the context menu and how to display the context menu. You, the developer, can define where the context menu appears by specifying “contexts”, you have a lot of flexibility, for instance you can say the context menu will only be active on text selections, or video and image elements or links.

Lets start by editing our background.html file. We are going to simply add a method call to chrome.contextMenus.create(), which takes an object that defines our context menu – and that is pretty much it.

chrome.contextMenus.create({
    "title": "Buzz This",
    "contexts": ["page", "selection", "image", "link"],
    "onclick" : clickHandler
  });

Seriously, that is it. The Context menu will be active on the page in general, on any text selection, image (or element that has a “src” attribute) and all links. There is a simple title “Buzz This” that is display when anyone of those elements is context clicked. An when the user selects our “Buzz This” menu item our “onclick” event handler is called.

So what do we do in “clickHandler” method? Well we handle the click obviously. In this case, I will detect what was clicked. The reason for detecting what element is the context is that the Buzz API that we are using allows you to pass in a few extra parameters such as the message (the selected text), an image (if the context was an image) or a url (if a link is the context).

var clickHandler = function(e) {
    var url = e.pageUrl;
    var buzzPostUrl = "http://www.google.com/buzz/post?";

    if (e.selectionText) {
        // The user selected some text, put this in the message.
        buzzPostUrl += "message=" + encodeURI(e.selectionText) + "&";
    }

    if (e.mediaType === "image") {
        buzzPostUrl += "imageurl=" + encodeURI(e.srcUrl) + "&";
    }

    if (e.linkUrl) {
        // The user wants to buzz a link.
        url = e.linkUrl;
    }

    buzzPostUrl += "url=" + encodeURI(url);

    // Open the page up.
    chrome.tabs.create(
          {"url" : buzzPostUrl });
};

It’s all pretty straight forward, we can get the url of the current page where the context menu was clicked, we can also detect if there is any text has been selected (e.selectionText) and pass that in to the “message” parameter of the Buzz API, likewise, if the e.mediaType == image, then we can add that to the imageurl parameter. Once we are happy, then we simply call the “chrome.tabs.create” API that we used in the first post in the tutorial.

And that is it. We now have context menu’s happily integrated in to our awesome extension. Unless I can think of any more subtle and useful things to include in the extension, then I think this is the last post…….. hmm, I hear the Omnibar API is released from experimental.

As always, the code is open and on http://github.com/PaulKinlan/BuzzThis have a play and see how easy it is to create Chrome Extensions. And if you do create one, let me know!!