Print

Roll Your Own Browser
Pages: 1, 2

The Script

Let's look now at the source code that initializes the browser. We'll cover the basics just to get some browser functionality working. In my opinion, the best way to find out how Mozilla works is to look at the code. The way to do this is via LXR, the Mozilla Cross Reference. The particular files you should be looking at are navigator.js and help.js, the main JavaScript files associated with the Browser and Help windows respectively.



The following code is a generic way to set things up, but is loosely based on starting these windows and setting up the browser. This script is best placed in the function associated with the load handler of the XUL window.

The first step is to add a couple more attributes to the browser widget in the XUL file.

<browser id="browser-content" type="content-primary" src="about:blank" flex="1"/>

The type attribute is optional but in this instance it is important because it affects the way the content is treated in the application. The value of "content-primary" means that this is the main browser content area (for example, content.focus()), and should gain precedence over other areas. The content in this browser will be accessed when you use the content keyword in your script. The id attribute gives the browser a unique identifier within the XUL content.This allows you to easily get a handle on the browser widget from your script:

var myBrowser    // declare globally for re-use
myBrowser = document.getElementById("browser-content");

Next, we'll create the browser instance and set up browser window:

var appCore = null;  // declare globally for re-use
appCore = Components.classes["@mozilla.org/appshell/component/browser/instance;1"]
          .createInstance(Components.interfaces.nsIBrowserInstance);
appCore.setWebShellWindow(window);

The browser is initially blank (because of using the "about:blank" as the src attribute), so you'll have to load some content into the browser. Here an http URL is used:

const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
myBrowser.webNavigation.loadURI("http://www.mozdev.org", 
          nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);

This creates an instance of the nsIWebNavigation XPCOM interface, which exposes a number of handy utilities for changing and navigating through the content displayed in the browser. In this instance, to load a page, the loadURI method is used. Other methods of this interface include goBack(), goForward(), and reload(). nsIWebNaviagtion is just one of the interfaces available when you use the browser widget. Others include:

  • preferences
  • webBrowserFind
  • contentViewer
  • documentCharsetInfo

A full list can be found in the bindings file for the widget. The steps provided in this section will get you well on your way to creating a rich content browser in your Mozilla application and act as a foundation for adding some of the other bells and whistles associated with a browser.

The Art of Navigation

What follows is a brief description of adding Back and Forward widgets and functionality to your window. This is, after all, the key to any reasonable browser, so I'll illustrate the process for hooking up this functionality to your browser. The XUL file is the place to define your UI buttons. If you are proficient at XUL and CSS, you can make them into the style and appearance that you wish, but in this example the current navigator styles (using the Modern theme) are used.


Back and Forward Buttons

These are simple toolbar buttons. The Back and Forward buttons used in the Mozilla browser have an integrated menu that creates a list of the pages available for each one. Appearance is achieved by including the navigator CSS file and using a class specific to buttons (toolbarbutton-1). Here is the XUL code for the buttons:

...
<?xml-stylesheet href="chrome://navigator/skin" type="text/css"?>
...
<toolbarbutton id="back-button" class="toolbarbutton-1" 
              tooltiptext="Go Back"
              oncommand="goBack();"
              observes="canGoBack">
</toolbarbutton>

<toolbarbutton id="forward-button" class="toolbarbutton-1"
              tooltiptext="Go Forward"
              oncommand="goForward();"
              observes="canGoForward">
</toolbarbutton>

Apart from the class attribute on the buttons, others to watch for are oncommand, which bridges the functionality, and observes. The observes attribute determines if the button is active. There is a little bit of trickery involved to get the buttons to move to and from a disabled state. It depends on whether navigation can occur either Forward or Back. We will not go into that here, but the full source code for the XUL file and the JavaScript file used in this article is available for reference. Let's look at the code for the goBack() and goForward() functions.

function goBack()
{
    var webNavigation = myBrowser.webNavigation;
    if (webNavigation.canGoBack)
       webNavigation.goBack();
}

function goForward()
{
    var webNavigation = myBrowser.webNavigation;
    if (webNavigation.canGoForward)
       webNavigation.goForward();
}

Once again the webNavigation interface is accessed through the browser widget. After an efficiency check on the observer, the goBack() or goForward() routine from the interface is called. That's all there is to it--three lines of code. The foundations were laid in the initialization code, so now you reap the benefits.

Summary

The rest, as they say, is up to you. You can choose to make your browser as simple or as complex as you wish. Mozilla provides the widgets to hold your content, and as was illustrated in this article, it also gives you the source code to add rich functionality. I just touched the surface here. Other features you can hook in are context menus, events such as drag&drop and onclick on the content area, and view page source. If you are truly ambitious, you can even go one step further and use the tabbed browser. Integrated into the Mozilla browser and turned on by default, this has been a popular addition to the browsing experience, and has won over many new users. The <tabbrowser> widget is more complex than the basic browser, but could bring more rewards. And don't forget, if it doesn't exactly meet your needs, you can change the source code!

Brian King is an independent consultant who works with web and open source technologies.


Return to the Mozilla DevCenter.