To follow along with this tip you'll need a basic understanding of how extensions are built for Firefox. Fortunately, if you write JavaScript and HTML, you already have almost all the knowledge you need. For an overview of extension development, check out the Resources at the end of the tip. You'll only cover the basics of it in this tip. You will also need Firefox 3.0, which at the time of writing this is not yet released. If you don't have it installed, then download and install the latest release candidate or a nightly build. If you want to avoid anything from happening to your existing Firefox profile, set up a separate profile for developing. For further details on how to set up an extension development environment on Mozilla Developer Center, see Resources.
Create the extension framework
You'll use the extension wizard to build the basic structure for you. The file I generated is available from Downloads. Download and extract that file into your working directory if you want to follow along.
Rather than build the extension and install it, you'll map the working directory into the Firefox extension folder. Create a text file with the name hcardformfiller@rob.crowther and put it in the path to the extension files in your working directory (see Listing 1). Then save this file in the extensions directory of your development profile, which for me is /home/robert/.mozilla/firefox/r6z6s4yl.default30/extensions (see the Mozillazine knowledge base for more details).
Listing 1. The hcardformfiller@rob.crowther file
/home/robert/code/xpcom/hcardformfiller
|
After you've done this, restart your Firefox development version using the script built in Listing 1. The extension should install and you should be able to access the default Hello World elements.
Since you want the user to be able to trigger the extension functionality, you'll provide them with a couple of toolbar buttons. To add toolbar buttons you'll need to describe them in the XUL overlay. Open the file hcardformfiller/content/firefoxOverlay.xul and replace what's already there with the code in Listing 2.
Listing 2. The firefoxOverlay.xul file
<?xml-stylesheet href="chrome://hcardformfiller/skin/overlay.css"
type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://hcardformfiller/locale/hcardformfiller.dtd">
<overlay id="hcardformfiller-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="overlay.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="hcardformfiller-strings"
src="chrome://hcardformfiller/locale/hcardformfiller.properties"/>
</stringbundleset>
<toolbarpalette id="BrowserToolbarPalette">
<toolbarbutton id="hcardformfiller-toolbar-button-grab"
image="chrome://hcardformfiller/content/hcardformfiller16.png"
label="&hcardformfillerToolbar.grabLabel;"
tooltiptext="&hcardformfillerToolbar.grabTooltip;"
oncommand="hcardformfiller.onToolbarButtonGrabCommand()"
class="toolbarbutton-1 chromeclass-toolbar-additional"/>
<toolbarbutton id="hcardformfiller-toolbar-button-paste"
image="chrome://hcardformfiller/content/hcardformfiller16.png"
label="&hcardformfillerToolbar.pasteLabel;"
tooltiptext="&hcardformfillerToolbar.pasteTooltip;"
oncommand="hcardformfiller.onToolbarButtonPasteCommand()"
class="toolbarbutton-1 chromeclass-toolbar-additional"/>
</toolbarpalette>
</overlay>
|
Listing 2 gives you two toolbar buttons, a Grab button and a Paste button. For convenience, they both use the same icon, hcardformfiller.png, which is available in the Download file. If you save everything at this point and restart Firefox, you can drag the buttons onto your navigation toolbar if you right click on each of them and select Customize. Figure 1 shows the end results.
Figure 1. The toolbar buttons in place
Grabbing microformats from the page
Now that you have toolbar buttons, you need them to do something when users click them. This means you'll have to write the JavaScript functions that support toolbar buttons defined in Listing 2. First, when the user clicks the Grab toolbar button, you want it to search the current page for microformats and store the first one it finds. Open up hcardformfiller/content/overlay.js and replace the code with Listing 3.
Listing 3. The overlay.js file
Components.utils.import("resource://gre/modules/Microformats.js");
var hcardformfiller = {
onLoad: function() {
this.initialized = true;
this.strings = document.getElementById("hcardformfiller-strings");
this.uF = {};
},
onToolbarButtonGrabCommand: function(e) {
var uFcount =
Microformats.count('hCard', content.document, {recurseExternalFrames: true});
if (uFcount > 0) {
var uFlist =
Microformats.get('hCard', content.document, {recurseExternalFrames: true});
this.uF = uFlist[0];
}
}
};
window.addEventListener("load", function(e) { hcardformfiller.onLoad(e); }, false);
|
The first line of Listing 3 loads the microformats API, which is
needed for anything else to work. Further down, you define the onToolbarButtonGrabCommand, which is the code that runs when a user
clicks the Grab toolbar button. Next, call Microformats.count() to see if the page has any hCards. This method
accepts a microformats name, a document reference to start the search from, and an
optional array of parameters. Here you search for hCards anywhere in the current
window, and you allow the parser to recurse down through any frames it encounters.
After you determine that you have at least one hCard, you then get a list of all hCards
on the page using the Microformats.get() method. The
parameters are identical to your previous call, but this time the code returns an array
of objects of type hCard. To keep the example simple, you only grab the first one and store it in your global variable.
Inserting the hCard into a form
Now that you've grabbed the hCard you want to do something with it. I created a simple form in Listing 4 for the extension to populate with hCard details. Just put it into a standard HTML Web page and save it locally—you don't need to process the submit form for the purposes of this tip.
Listing 4. A simple target form for the extension
<h1>hCardFormFiller Target Form</h1>
<form action="#" method="post">
<label>Name: <input type="text" id="name" /></label><br />
<label>Email: <input type="text" id="email" /></label><br />
<label>Home page: <input type="text" id="homepage" /></label><br />
<label>Street Address: <input type="text" id="address1" /></label><br />
<label>City: <input type="text" id="address2" /></label><br />
<label>Region: <input type="text" id="city" /></label><br />
<label>Postcode: <input type="text" id="postcode" /></label><br />
<input type="submit" />
</form>
|
Now you need to define the function attached to the Paste button defined in Listing 2, so when the user clicks the button, the form is filled in. See the code for your extension to fill this form in Listing 5.
Listing 5. Adding the paste command to overlay.js
onToolbarButtonPasteCommand: function(e) {
if (this.uF.fn) {
content.document.getElementById('name').value = this.uF.fn;
content.document.getElementById('email').value = this.uF.email[0].value;
content.document.getElementById('homepage').value = this.uF.url[0];
content.document.getElementById('address1').value = this.uF.adr[0]['street-address'];
content.document.getElementById('address2').value = this.uF.adr[0].locality;
content.document.getElementById('city').value = this.uF.adr[0].region;
content.document.getElementById('postcode').value = this.uF.adr[0]['postal-code'];
}
}
|
The first step is to see if there is an hCard to paste—the fn is one of the two
required fields in an hCard microformats. If fn exists, then you have an hCard. You
then put that fn in the first field of the form. An hCard can have multiple e-mail
values, so the email property on hCard is an array—you just grab whatever the
first one is—and each email has two properties: type,
which can be internet, x400, or
pref for preferred; and value,
which is the actual e-mail address. The url property of
hCard is also an array but this time without subproperties, whereas the adr property is an array of the atomic adr microformat, which you can
also manipulate directly outside hCard. The main point to note on these adr properties is that I used the alternative reference syntax in JavaScript, because the hyphen gets treated as a minus otherwise. You can see the results in Figure 2.
Figure 2. Filling in the form from Listing 4 with a stored hCard
In Figure 2, I grabbed the hCard off the about page of my Web site, then used it to fill in the form—seven fields filled in with a couple of clicks of the mouse!
In this tip, you took a standard Firefox extension template and quickly gave it the ability to use the hCard microformats thanks to the new APIs in Firefox 3.0. You can see that the API makes manipulating microformats data very easy. With very little code, you can build an extension that is a massive time saver, and to add similar features to your own extensions will be very little work.
As a next step, you might consider generalizing the paste action to provide a mapping file for any form, and allow use of an hCard microformats to fill it. A shared repository of mappings can vastly simplify the process of filling in forms on the Web.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code | hcardformfillerfiles.zip | 24KB | HTTP |
Information about download methods
Learn
-
Mozilla Developer
Center documentation for Extensions: Read more on how to customize Mozilla apps to
fit the personal needs of each user and still keep your apps small.
-
The Mozillazine knowledge base: Learn about Firefox's profile folder.
-
Setting
up extension development environment: Find suggestions on how to set up your Mozilla application for extension development.
-
Browser extensions using
XUL, Part 1 and Browser extensions using
XUL Part 2 (Uche Ogbuji, developerWorks, October 2007): Get an introduction to
extension writing with the Mozilla project's XUL engine.
-
Firefox/Thunderbird Extension
Wizard: Kick-start your extension development the extension wizard.
-
Using microformats: Read about using microformats in Firefox 3.0.
-
hCard microformat: Learn more about the hCard microformat.
-
hCard and adr microformat objects: Check out the structure of these objects in Firefox.
-
IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
-
XML technical library: See the developerWorks XML library for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks. For a complete list of XML tips to date, check out the tips summary page.
-
developerWorks technical events and webcasts: Stay current with technology in these sessions.
- The technology
bookstore: Browse for books on these and other technical topics.
-
developerWorks
podcasts: Listen to interesting interviews and discussions for software developers.
Get products and technologies
-
IBM
trial software for product evaluation: Build your next project with trial software available for download directly from developerWorks, including application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
- Participate in the discussion forum.
-
Exploring Semantic
Web Technologies Forum: Discuss this tip and all things related to the Semantic Web.
-
XML zone discussion forums: Participate in any of several XML-related discussions.
-
developerWorks XML zone: Share your thoughts: After you read this article, post your comments and thoughts in this forum. The XML zone editors moderate the forum and welcome your input.
-
developerWorks blogs: Check out these blogs and get involved in the developerWorks community.

Rob Crowther is a Web Developer from London and is currently moderator of the Exploring Semantic Web Technologies forum on developerWorks. He has a keen interest in Web Standards and blogs sporadically at http://www.boogdesign.com/b2evo/.





