Google Chrome Extensions: How to build an extension


Uploaded by GoogleDevelopers on 07.12.2009

Transcript:
Hi, my name is Brian Kennish. I'm a developer advocate on the Google Chrome
team. And I'm going to show you how to build Google
Chrome Extensions. We'll start out with an overview of extension
building. Then, we'll walk through some code and put
together an example step by step. But before we get to the technical stuff,
let's talk about what extensions are. Google Chrome Extensions are mostly small
programs that add bits of functionality to Google Chrome.
They install instantly without a browser restart. And, like Google Chrome, they update silently
when new versions are available. We designed the extension system with web
developers in mind. If you can create webpages, you know pretty
much all you need to know to create Google Chrome extensions.
In fact, extensions are implemented with nothing but standard web technologies -- HTML, CSS,
JavaScript, and so on. An extension is a compressed directory --
a signed zip, to be exact -- with a bunch of web files in it.
The one file every extension has to have is a manifest file.
It's also the one file that has to have a particular name, which is "manifest.json".
As the name implies, the manifest file is JSON-formatted data -- specifically, metadata
that describes the extension, lists permissions, and points to the extension's other components.
Those components are what give the extension its functionality.
An extension includes one or more of the following components.
Browser actions and page actions are the two UI surfaces the extension system ships with
initially. A browser action appears in the toolbar of
every tab. A page action selectively appears in the omnibox
and can be toggled on or off for each tab. An extension can only have one UI surface
or the other. We'd like to encourage extension developers
to be as minimal in their design decisions as the Google Chrome team is.
Content scripts are arbitrary CSS and JavaScript that are injected into selected pages.
They're similar to user scripts and can be used as a UI alternative to browser and page
actions. Background pages are long-running scripts
that help you manage state and coordinate tasks across extension components.
As an extension gets more complex, it tends to need a background page.
In addition to these components that are specific to Google Chrome Extensions, you can bundle
any other web files with your extension -- images, JavaScript libraries, Flash movies,
whatever it is your extension needs. The extension API is small and easy to learn.
It currently defines about 40 objects and 40 methods.
"chrome" is the name of the top-level object automatically exposed to all extensions.
The API is split into six modules, which are represented by objects contained in the "chrome"
object. "chrome.extension" has properties and methods
that let you send messages to communicate between extension components and resolve the
URLs of extension files. "chrome.browserAction" lets you set the appearance
of browser actions and their badges, which are mini text areas overlaid on browser actions.
"chrome.pageAction" lets you enable and disable page actions.
"chrome.windows" lets you open, close, look up, and update browser windows.
It requires "tabs" permission in your manifest file.
That's not a typo -- windows and tabs are so closely related they share a common permission.
"chrome.tabs" lets you perform the same actions on tabs.
It also requires "tabs" permission. And "chrome.bookmarks" lets you read from
and write to the user's bookmark tree and requires "bookmarks" permission.
Now, let's try this stuff out by iteratively developing an extension.
Our extension will be a Google Chrome Twitter client, which we'll call Chritter.
First, we'll give the extension a basic, “hello world”-type UI.
Of course, we need a manifest file. In it, we specify the extension's name, version
number, description, and icon. For the UI part, we're going to pick a browser
action because, well, we want our tweets handy at all times!
We populate the browser-action fields with an icon that will appear in the toolbar, a
tooltip that will appear when the user mouses over the icon, and a popup bubble that will
appear when the user clicks on the icon. For now, the popup is a trivial HTML file.
After installing our extension, we get -- as advertised -- an icon, a tooltip, and
a popup. The popup asks: "Wouldn't it be nice to see
some tweets here?" And I think it would be nice, so let's add
some! We'll do so by fetching Twitter's public timeline
with XMLHttpRequest. Back in our manifest file, we ask for permission
to make cross-origin requests to twitter.com so we can access Twitter's API.
We ask for "tabs" permission, as well, so we can open UI links in new tabs.
And in our popup file, we beef up the HTML by inserting a title and a template to present
the attributes of each tweet -- a link to the user's profile, their image and name,
and the tweet itself. We also have new JavaScript for retrieving
and displaying the timeline. When the load event fires, we run an "init"
function to grab references to the different template elements via XPath.
That function hands control over to another function to do the XHR work.
"getTweets" issues a simple request for a JSON feed, and in turn, hands control over
to the callback function "processTweets". The processing function deserializes the incoming
JSON using V8's builtin JSON support and stores the result in an array.
Iterating through the array of tweets, the "update" function assigns each template attribute
and appends the marked-up tweet to the popup. Our extension has a lot more going on now,
with a polished UI and the most recent public tweets to show off.
Our implementation isn't ideal, though. As a last step, let's improve the extension's
performance and functionality by refactoring our code.
Namely, we should turn our popup into a dumb view so it only knows how to update its display
and offload the rest of the work to a background page.
We'll go ahead and add a background page to our manifest.
Then, we can strip the XHR code out of our popup.
In place of that code, we throw in a reference to the background page, which is returned
by the "getBackgroundPage" method. The popup doesn't collect tweets anymore,
so we use the background reference to iterate through the available tweets instead.
We move the XHR code to its new digs in the background page, but not without a couple
upgrades. I mentioned we could improve performance and
functionality and here's where we will. Since the background page isn't tied to any
DOM event, the page can fetch tweets on a continuous loop.
That way, we can batch tweets up and have them ready before the user even invokes the
popup. We specify a frequency for fetching -- 10
seconds for demo purposes -- and manage the process with the "setInterval" method.
While we're at it, we can also spiff up the UI.
We now have a variable number of batched tweets, which is a perfect candidate for display with
a browser-action badge. We style the badge with "setBadgeBackgroundColor"
and pass in the number of unread tweets with "setBadgeText".
Our extension doesn't look a whole lot different right away.
But if we let it think for a bit, we see a badge that dynamically updates the tweet count.
The popup should work identically, although we potentially have a lot more tweets to scroll
through now. While this version of Chritter makes for a
nice toy, there are some features we'd want to add for it to be truly useful.
On the top of that list would be incorporating the user's friend timeline -- rather than
the public timeline -- which would require baking OAuth into the extension.
Things can get a little hairy there. Luckily, we've already done the heavy lifting
for you and have an example of Chritter with OAuth support.
We also have a further example that handles custom autoupdating.
To download that code, the code you just saw, and more, go to code.google.com/chrome/extensions.
Thanks for watching and have fun building Google Chrome Extensions!