At the Forge - Firebug
During the past year or two, Web developers have witnessed what we might call the JavaScript renaissance. That's because all the fancy Ajax, Web 2.0, mashup, interactive, collaborative, desktop-like applications that are being developed are written in JavaScript. This is possible today not only because the JavaScript language has improved, but also because browsers are increasingly compliant with Web standards. And, of course, the availability of cross-platform JavaScript libraries, such as Prototype, has added many features to the language, while simultaneously ensuring cross-platform compatibility.
So, with all the JavaScript development happening today, what is the most popular way to debug programs? That's right, it's the built-in alert function:
alert("value of x = '" + x + "'");
Alerts might be unpleasant, ugly and downright annoying, but they have been the best and easiest way to debug JavaScript for several years. Sure, there have been a few JavaScript debuggers, but none of them has been all that exciting to use, let alone easy or productive.
Well, I'm happy to say that the situation has now changed. Firebug is an open-source plugin for the Firefox browser that aims to be a one-stop debugging tool not only for JavaScript, but also for everything that a Web developer needs. Written by Joe Hewitt, one of the founders of the small startup Parakey, Firebug 1.0 was released in early 2007. It already has become wildly popular among Web developers, and for good reason.
This month, we look at Firebug, so that we can debug, inspect and optimize modern Web pages. Firebug already has improved my ability to debug modern Web pages dramatically, and I wouldn't be surprised if this turns out to be the case for many other Web developers.
Firebug is distributed as an extension for the Firefox Web browser. It is most easily downloaded and installed from the Firebug site (www.getfirebug.com). To install it, click on the download Firebug button. If you already have told Firefox this is an allowed download site, you will be able to download and install this Mozilla extension. If not, you need to add getfirebug.com to your list of trusted download sites, and then repeat the download procedures. Once the extension is installed, restart Firefox.
Once you do this, your Web browser will look much the same as before, but with some small changes. First, there now will be an icon at the bottom of the screen in the status line. This icon will look like either a green V in a circle (to indicate that it is running) or a gray circle with a slash through it (to indicate that it is disabled). Firebug can be enabled all of the time, but you're probably interested in debugging only a small number of sites that you visit. Thus, it's useful that by clicking on the Firebug icon—or by going to Tools→Firebug in the Firefox menu—you can indicate the sites for which Firebug should be active.
You can add a new site to this list by selecting open Firebug from that same Tools→Firebug menu, or by adding it manually with the allowed sites dialog box from that same Firebug menu. In either case, the site you currently are visiting will be viewable in Firebug.
Now that we have started Firebug, what can we do with it? Let's have some fun by going to the Linux Journal site (www.linuxjournal.com). Activate Firebug for this site, and your browser window will be cut in half, with the top half still showing the Web page and the bottom half containing Firebug. I generally prefer to work with Firebug in this way, but if you prefer to keep your browser window separate from your debugging window, you might want to choose open Firebug in new window, rather than simply open Firebug.
The main menu for Firebug contains the Firebug icon, which offers most of the same menu options as the icon in the status line and Tools→Firebug menu, along with links to the Firebug documentation and home page. An Inspect button always sits next to that icon, and it lets you zoom in on a particular item on the page. The rest of that menu bar changes according to the context in which you are operating, which is determined by the second row of buttons, marked Console, HTML, CSS, Script, Dom and Net.
One of the first, and easiest, tasks to take on with Firebug is debugging HTML. Click on the HTML button and choose Inspect. You immediately will see the HTML source code for the current page highlighted in the Firebug window.
Now, here's where the magic begins: with HTML/Inspect selected in Firebug, move your cursor over the Web page (the upper frame). As you move the cursor, the HTML element over which it is passing is highlighted in blue. In the Firebug frame, the HTML source corresponding to that rendered content also is highlighted.
This functionality is particularly useful when I know something is going wrong with the rendering of my Web page, but I'm not quite sure which part of the HTML source is to blame. A few clicks of the mouse later, and you easily can know which part of the file you need to edit.
Firebug highlights the HTML source code that it displays, albeit using different colors than the View Source page that Web developers know and love. (I think that Firebug's color choices are better.) Moreover, Firebird displays the HTML source as a tree, including indentation. This, along with a display of all of the current element's parent tags (next to the edit button on the top row) provides a great sense of the current element's context in the document.
Inspecting the HTML certainly is useful and interesting, but it gets better. If you double-click on the text in the Firebug frame, you now can edit it. Obviously, your changes do not get saved back to the server, meaning you can return to the original content by refreshing the page. Nevertheless, it is quite useful (and fun!) to replace text on existing pages, right from your browser.
Replacing text in an HTML element is a good start, but what if we want to modify the markup itself, rather than only its text or attributes? Right-clicking on the tag (or any of the text within the tag) displays a pop-up menu, letting you copy the HTML, innerHTML or XPATH of the selected tag. You can ask for the selected tag to be displayed in the top frame, scrolling if necessary in order to reach it.
Finally, you can add new attributes to this element or ask to inspect the element in the DOM tab. And indeed, the DOM view provides another way of looking at the same document. While still inspecting one of the HTML elements, click on the DOM button in the second row of the Firebug frame. The frame changes its appearance, listing a large number of DOM attributes associated with the element. Thus, inspecting an image in the DOM tab shows that its type is IMG, while inspecting a link shows that it is of type A. As always, Firebug lets you edit any attribute you like by clicking on the value and replacing it.
So far, we have seen how Firebug can help inspect and modify HTML. But, of course, HTML provides only the basic content and structure for a page; if you know what you're doing, you can inspect and modify the CSS definitions as well.
One of the many amazing and clever things about CSS is the way it handles inheritance. If you have set some attributes for <p> in css1.css and others in css2.css, both will apply to <p> tags in your file. Things can become more complicated than that, such as when you have a <p> tag with an id attribute, with conflicting style information. In these cases, the most specific style (that is, the id tag) applies.
On a large site with many different styles, it sometimes can become difficult to keep track of which styles are being applied. Fortunately, Firebug provides some wonderful capabilities for inspecting the CSS associated with a site, and even for editing it.
To use this functionality, click on the CSS button (next to the HTML button we were using earlier), and then on the Inspect button above it. Firebug continues to show its tree representation of the current document, but the right-hand frame displays all of the CSS styles that apply to whatever you're pointing to. Moreover, it indicates which CSS file, and which line of that file was applied. And, as if that isn't enough, it crosses out any styles that were overridden by more specific ones.
As with the HTML inspector, you easily can edit the CSS associated with any element by double-clicking on a style declaration. For example, if you want to change text from roman to italic type, you merely click on CSS/Inspect, then point to the text you want to change. If there already is a font-style property in the CSS, you can change it to read italic. If not, you can right-click on the CSS pane, choose new property, and add the property and its value.
Firebug knows what the legal property names are for CSS styles, so it is able to complete the style name automatically when you begin typing.
The right-hand frame offers more than merely a textual indication of styles. It also has a graphical representation of the CSS box model, showing the number of pixels used by the element, padding, border, margin and offset.
Finally, we get to the JavaScript debugger. As I mentioned earlier, JavaScript is becoming a mainstream application programming language, which means people are writing increasingly complex programs with it. And, although I've long used print statements for much of my debugging during the years, there's no doubt that a good, interactive debugging environment can make it easier to solve certain issues.
Firebug provides several powerful tools for JavaScript debugging. It introduces a new logging system that makes it possible to produce debugging output without using the alert function. I still can't quite believe it took this long for someone to realize it would be helpful to have a method for logging that didn't produce a modal dialog box. Regardless of how long it took, we can now use console.log to write messages to the Firebug console, such as:
console.log("Now executing the 'foo' function.")
Or:
console.log("Username parameter was '" + username + "'")
Actually, Firebug makes it possible to do much better than this, with embedded, printf-like strings:
console.log("Username parameter was '%s'", username)
Firebug provides a set of logging functions, each of which produces output with a different warning level and color. These are:
console.debug
console.info
console.warn
console.error
The output from these methods appears in the Firebug console, which you can view by clicking on the Console button, right under the Firebug icon. Note that using these methods means your methods might be incompatible with browsers that lack Firebug.
The console is not only an area that receives messages though. As with Ruby's IRB and Python's interactive mode, Firebug's console allows you to execute JavaScript within the context of the page. Interested in getting a list of forms on the page? Simply type:
document.forms
and you will get a list of the forms. You also can use Prototype-style methods to retrieve information about much of the page, as in:
$('cvb_form')
which, on the Linux Journal home page, produces the following form header:
<form id="cvb_form" action="/" method="get">
Firebug also has extensive capabilities for monitoring functions, setting breakpoints and profiling functions. Go to the Script button, and you are greeted by the source code for an included JavaScript file. (You can change the file you're looking at by choosing from a menu.) Pointing to a line of code with the mouse cursor brings up information about the current state of those objects.
Clicking on the code allows you to set a breakpoint (including a conditional breakpoint) to copy the function (useful when trying to communicate with other programmers or even when writing a column about programming) or to handle a breakpoint by continuing or stepping through the code.
To find out which JavaScript functions have been taking the most time, and which are invoked most frequently, use Firebug's profiler. It's amazingly simple to use. Click on the Console/Profile button, and then go about your business, using the Web site as much or as little as you want. When you click the Profile button again, Firebug reports the number of times each JavaScript function was called, the time each call took and where each function is defined.
Finally, the Net button makes it easy to keep track of any Ajax calls embedded in the page. Clicking on Net and XHR produces a graphical indication of the Ajax calls that have been made on this page, as well as how long each took to execute. If you are developing an Ajax application, this is the best way to find out where your bottlenecks are.
It's rare for me to call a product revolutionary, but I am sorely tempted to do so in the case of Firebug. It puts a lot of information in one nicely designed, easy-to-use package. The ability to interact with my packages has a vaguely Lisp-like feel, in that I'm suddenly interacting with a live environment. Firebug has given me the ability to “see” what my pages are doing and to better understand them.
Firebug has become an indispensable tool in my arsenal, alongside the Web Developer extension. In this way, Firefox is beginning to demonstrate that it is indeed a platform for Internet applications, rather than merely a Web browser.
Resources
The Firebug home page is www.getfirebug.com. There is limited documentation, including a FAQ, on that site.
An introduction to Firebug by its author, Joe Hewitt, in Dr. Dobb's Journal: www.ddj.com/196802787.
Reuven M. Lerner, a longtime Web/database consultant, is a PhD candidate in Learning Sciences at Northwestern University in Evanston, Illinois. He currently lives with his wife and three children in Skokie, Illinois. You can read his Weblog at altneuland.lerner.co.il.