Now, if this file looks simple to you, that's the point. Extensions
can become complex, but they don't have to be, particularly if you're
doing something simple. Save the new version of manifest.json and
popup.html inside the extension directory, reload the extension,
and click on the extension icon. You should see the text pop up,
albeit in an ugly black-and-white window.

If you want to add some nice styling to popup.html, you can do so with
CSS. Create a file, popup.css, and place it (of course) in the
extension directory:

JavaScript in Extensions

All of this seems pretty straightforward—and it is. But if you're
thinking that you can just stick some JavaScript inside the HTML
file and have it execute, as would be the case in a normal HTML
file...well, that's where things become a bit tricky and different. For
security reasons (which I admittedly don't quite understand),
JavaScript needs to be in a separate file, referenced from the HTML
file. In such a case, the file looks like this:

What can be in your popup.js? Anything you want, actually. Here's a
really simple (and annoying!) one:

alert("You have loaded the popup!");

Now clicking on the extension icon will produce a JavaScript alert.
Once you have dismissed it by clicking the OK button, you will get
your beautifully formatted HTML page, in popup.html.

What can you do within popup.js? Truth be told, you can do just about
anything you want—modify text, retrieve content from other sites,
calculate things and send information elsewhere. If you can do it
in JavaScript, the odds are that you can do it within the
browser. You even can use a library, such as jQuery, so long as your
copy of jQuery is referenced and loaded from within the extension
directory.

So, let's try something a bit bolder. Let's retrieve data from a Web
site and insert it into the pop-up window, using jQuery. In order to
do this, you'll need to modify your popup.html a bit:

Notice how I've added the line referencing jquery.js in the extension
directory. You also can reference one of the copies that Google or
another company has put on-line, in order to improve caching and
download speeds. I've also given an ID attribute of
"paragraph" to the "p" tag in the HTML, which will make it easier
to grab the paragraph and do something with it.

The biggest difference will be in popup.js. No longer will you just
have a call to alert() in there. Instead, you'll actually use jQuery's
Ajax facilities to retrieve information from a Web site and stick it
into the pop-up window. You're going to do it in an ugly, brute-force
way here, in order to see the results more obviously, but you
easily can imagine an example that would go through the
contents of a Web site more gracefully (or, perhaps, its RSS/Atom feed), picking out
information that is of use and then displaying it. For example, you
could create a browser extension that displays the current weather.

For this example, let's just have the browser go to a Web site,
retrieve its contents and stick the raw content into the pop-up's
"p" tag. Here's the updated popup.js:

Now, the reason I put in the "before" and "after" alerts is not
because I enjoy annoying my users, but because I find it instructive
to see when things happen in the asynchronous Ajax world. (Hint:
remove the calls to "alert" before you unleash this amazing extension
on your users.) You define a function, showText, which adheres to
jQuery's definition of what a function should look like, namely that
it accepts (at least) one parameter, named "data", which contains the
contents of the URL you tried to retrieve. That's all you're going to
do here, using the "text" method to stick in the HTML source. That
means the end user will see the source; if you want something a bit
more aesthetic, you can use the html() method rather than the text()
method.

But, showText isn't invoked directly. Rather, it's invoked as a
callback function, executing when your invocation of $.get(), a
function that executes in the background (that is, asynchronously),
returns the contents of the Web site. This could take one second or ten,
but in most cases, it'll be pretty fast. However, the callback
almost certainly will be invoked only after your second call to alert().
That is, you'll see the first alert() call, the second alert() call
and then a change in the contents of the paragraph. Such event-based
coding is the norm in the JavaScript world, and it can take a little time
to get used to it. Notice that the second parameter is showText, the
function itself, which then is invoked after a successful Ajax call.

If you now reload the browser extension and click on the button,
you'll find...that nothing really happens. That is, you get the
first and second calls to alert, but the paragraph doesn't change its
contents. This is because you haven't told Chrome that it's okay to
retrieve data from lerner.co.il, or from any other URL. Because
retrieving data from an external URL is a potentially dangerous event,
exposing you to things in the outside world, you need to
allow its use explicitly. This is done by returning to manifest.json and adding
a "permissions" key:

The "permissions" key can contain a large variety of items, from URLs
(as in this case) to wild-card matches, to keywords that Google has
defined. For example, if you'll want your extension to use such HTML5
abilities as geolocation or local storage, you'll need to indicate
that here.

Now, all of this is nice if you want to modify popup.html, namely the
pop-up that you get with your browser extension. What if you actually want to
interact with the page itself, either reading from it or
writing to it? The answer is that you can do this by writing not a
"browser action", as it is known in the Chrome world, but a "content
script".

Now, a content script requires a different manifest.json, but it also
raises questions about how you can interact with a page that itself
might have some JavaScript executing. The answer is that Chrome
provides an interesting facility known as "isolated worlds", in which
two separate JavaScript environments—one on the page and the other
in the browser—can operate independently, each with its own
JavaScript library (and version of jQuery, if necessary), but interact
simultaneously with the DOM and the contents of the page. Such
isolation not only means that your content script can play with the
contents of the page in a number of ways without worrying about
interfering with existing JavaScript, but also that the page cannot
"break out" of its sandbox, infecting or otherwise affecting the
browser itself.

I should note that although I haven't used them in this article's examples,
Chrome provides a wide variety of JavaScript methods and functionality
through the "chrome" object, which you can access via the
permissions key in manifest.json. Such methods give you access to
(for example) the current tabs and windows, really allowing you to
control and use the browser as an application platform, rather than
just a mechanism for displaying content.

Conclusion

Chrome was designed to use Web technologies, and nowhere is that more
obvious than the extension mechanism, which uses a combination of
HTML, CSS and JavaScript to produce new user experiences. Now, browser
extensions aren't a panacea; they break the idea that the Web is
browser-independent and that everything can be downloaded on demand
from a server. But if your entire organization will be using Chrome,
or if you're looking for something that interacts with existing pages,
or if you want to add capabilities to your browser, Chrome's
extension mechanism makes it easy to experiment and try new ideas.