Annotation of books/www/articles/roll_your_own.html, revision 1.6

1.1       brian       1: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
                      2: <html>
                      3: <head>
1.6     ! brian       4:                                     
1.2       brian       5:   <meta http-equiv="content-type"
                      6:  content="text/html; charset=ISO-8859-1">
1.1       brian       7:   <title>Roll Your Own Browser</title>
                      8: </head>
1.2       brian       9: <body>
1.1       brian      10:      
                     11: <h1> Rolling Your Own Browser</h1>
                     12:     The browser is dead. It is a two dimensional piece of software that is
1.6     ! brian      13:  slowing  the evolution of the Web. Are you shocked by these statements,
        !            14: reading this article from the comfort of your browser of choice? Well you
        !            15:   should be because no matter what some people lead you to believe, browsers
        !            16:   will be around for a while longer. The purpose of this article is to introduce
        !            17:   you to the concept of customisating, or creating your own browser, and
        !            18: how   you can do it with the wonderful toolkit that is Mozilla.<br>
1.1       brian      19:      
                     20: <h2> Why your own browser?</h2>
1.2       brian      21:     Before proceeding, it must be noted that the rest of this article focuses
1.6     ! brian      22: on the technical issues involved in getting a XUL browser up and running
        !            23: in the application framework. This is distinct from embedding Gecko, which
        !            24: was discussed in a previous article on the DevCenter, '<a
        !            25:  href="http://www.oreillynet.com/pub/a/mozilla/2002/09/12/mozilla_browsers.html">Let
        !            26: One Hundred Browsers Bloom</a>'.<a
        !            27:  href="http://www.mozilla.org/newlayout/faq.html">Gecko </a>is the Mozilla
1.2       brian      28: layout rendering engine. The merits of having multiple browser projects has
1.6     ! brian      29: been touched on already, so lets look at some of the practical uses that
        !            30: an integrated browser can bring to your application, apart form the traditional
1.2       brian      31: usage for web navigation.<br>
                     32:     <br>
                     33: <ul>
                     34:   <li>    Create some HTML or XML help pages for your  application  and load
                     35: them up in a ready made help browser.</li>
1.6     ! brian      36:   <li>    Previewer &#8211; test your XML, HTML or CSS layout   and styling in
        !            37: Gecko, one of the most standards compliant browsers around.</li>
1.2       brian      38:   <li>    A slight variation of the previous use, you  could  have mini &#8211;
                     39: versions inline in dialogs to load up examples that will  change  depending
                     40: on the slection of the user from a number of choices. For  example,  a font
                     41: previewer.</li>
                     42:   <li>    Pop-up&#8217;s contained in a window for display of  web content</li>
                     43: </ul>
                     44: <br>
1.6     ! brian      45: Of course, when you have the raison d'etre for your browser, you have to
        !            46: start putting the pieces in place to get it up and running. This will take
        !            47: the form of a full blown Mozilla application, complete with the XPFE toolkit
        !            48: for building your own UI, or perhaps just an add-on to the existing suite
        !            49: that can be distributed in the form of an XPI. The term XPI refers to Cross-Platform
1.2       brian      50: Install, the native installer for Mozilla.<br>
1.1       brian      51:          
                     52: <h2> The Widgets</h2>
1.2       brian      53: To get you started straight away, lets look at two if the most straightforward
                     54: content widgets available in the Mozilla toolkit, namely the <i>browser</i>
1.6     ! brian      55: and the <i>iframe</i>. These are marked up with tags of the same name, <span
        !            56:  style="font-style: italic;">&lt;browser&gt;</span>and <span
        !            57:  style="font-style: italic;">&lt;iframe&gt;</span>, and placed within your
        !            58: XUL window or binding. Both are essentially designed for holding web content,
        !            59: which can be anything from HTML and XML to just text and images in formats
        !            60: recognised by Gecko such as jpeg, png, gif and bmp. Here is a look at a browser
        !            61: in its simplest form:<br>
1.2       brian      62: <br>
                     63: <font face="Helvetica, Arial, sans-serif"><small>&lt;?xml version="1.0"?&gt;</small><br>
                     64: <small>&lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;</small><br>
                     65: <small>&lt;window id="browser-window" title="Simple Browser Widget Display"</small><br>
                     66: <small>&nbsp;&nbsp;&nbsp; xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</small><br>
                     67: <small>&nbsp;&nbsp;&nbsp; width="640"</small><br>
                     68: <small>&nbsp;&nbsp;&nbsp; height="480"&gt;</small><br>
                     69: <small>&lt;browser src="http://mozdev.org" flex="1"/&gt;</small><br>
                     70: <small>&lt;/window&gt;</small></font><br>
                     71: <br>
                     72: The code to look out for here is the line with the browser tag which creates
1.6     ! brian      73: a content area. It is the sole markup in the XUL window. It takes up all the
        !            74: available space because of the flex attribute, and into is loaded the index
        !            75: page of mozdev.org. This is the result, a window with web content.<br>
1.5       brian      76: <br>
                     77: <div align="center"><img
                     78:  src="http://books.mozdev.org/articles/simplebrowser.png"
                     79:  alt="SimpleBrowser" width="640" height="480"><br>
1.2       brian      80: </div>
                     81: <br>
1.6     ! brian      82: <div align="center"><i>Simple Browser Window</i><br>
1.2       brian      83: </div>
                     84: <br>
1.6     ! brian      85: What is missing in the picture and the example code for it is some sort of
        !            86: context. It is lacking an application space, and has no accompanying widgets
        !            87: to carry out any complimentary functionality for the browser. In traditional
        !            88: browsers, including the Mozilla browser that comes with the application suite,
        !            89: there is a menubar and a toolbar, each containing easy access to functionality
1.5       brian      90: such as Back, Forward, Reload, View Source, and so on. <br>
1.2       brian      91: <br>
1.6     ! brian      92: The <span style="font-style: italic;">&lt;iframe&gt;</span> widget is a more
        !            93: lightweight version of the <span style="font-style: italic;">&lt;browser&gt;</span>,
1.3       brian      94: yet is just as useful if your needs are just to display some somple we content.
                     95: It was designed to act much like the HTML iframe widget, to be an inner frame
                     96: within a document. It too has a <i>src</i> atribute to specify the content.
                     97: It is useful mainly for dislaying one-off content such as a preview of content,
                     98: or a results page.<br>
                     99: <br>
                    100: <small><font face="Helvetica, Arial, sans-serif">&lt;iframe class="results"
                    101: id="resultsframe" type="content" src="results.xul" flex="1"/&gt;</font></small><br>
                    102: <br>
1.6     ! brian     103: Remember that XUL content can be loaded into the content areas, as for example
        !           104: is the case in the Mozilla suite global preferences which has a right frame
1.3       brian     105: into which the various preferences panels are loaded into when selected.<br>
1.1       brian     106: <h2>The Script</h2>
1.6     ! brian     107:     Let's look now at the source code that enables the initialization of the
        !           108: browser. These are the basics to get some browser functionality working. I
        !           109: find the best way to find out how Mozilla works is to look at the code. The
        !           110: perfect way to do this is via <a href="http://lxr.mozilla.org">LXR</a>, the
        !           111: Mozilla Cross Reference. The particular files you should be looking  at are
        !           112: <a
1.2       brian     113:  href="http://lxr.mozilla.org/seamonkey/source/xpfe/browser/resources/content/navigator.js">navigator.js</a>
                    114: and <a
                    115:  href="http://lxr.mozilla.org/seamonkey/source/extensions/help/resources/content/help.js">help.js</a>,
                    116: the main JavaScript files associated with the Browser and Help  windows respectively.
                    117: The following code is a generic way of setting things up but is based loosely
                    118: around the starting up of these windows and setting up of the browser. This
                    119: script is best placed in the function associated with the load handler of
                    120: the XUL window.<br>
                    121: <br>
1.3       brian     122: The first step is to give the browser widget in the XUL file a couple more
                    123: attributes added to it.<br>
                    124: <font face="Helvetica, Arial, sans-serif" size="-1"><br>
                    125: &lt;browser </font><font face="Helvetica, Arial, sans-serif" size="-1">id="browser-content"
                    126: </font><font face="Helvetica, Arial, sans-serif" size="-1">type="content-primary"
                    127: <br>
                    128: &nbsp; &nbsp; &nbsp; &nbsp; src="about:blank" flex="1"/&gt;</font><br>
                    129: <br>
                    130: The <i>type</i> attribute is optional but in this instance is important because
                    131: it affects the way the content is treated in the application. The value of
1.4       brian     132: "content-primary" means that this is the main browser content area (e.g.<small><font
                    133:  face="Helvetica, Arial, sans-serif">content.focus()</font></small>), and
1.6     ! brian     134: should gain precedence over other areas. When you use the <i>content</i>
        !           135: keyword in your script, it is the content in this browser that will be accessed.
        !           136: The<i> id</i> attribute gives the browser a unique identifier within the
        !           137: XUL content.This allows you to easily get a handle on the browser widget
        !           138: from your script:<br>
1.3       brian     139: <pre><font face="Helvetica, Arial, sans-serif">var myBrowser    // declare globally for re-use<br>myBrowser = document.getElementById("browser-content");<br></font></pre>
1.2       brian     140: Next is to create the browser instance and set up browser window:<br>
                    141: <br>
1.3       brian     142: <small><font face="Helvetica, Arial, sans-serif">var appCore = null; &nbsp;
                    143: &nbsp;// declare globally for re-use<br>
1.2       brian     144: appCore = Components.classes["@mozilla.org/appshell/component/browser/instance;1"]<br>
                    145:             .createInstance(Components.interfaces.nsIBrowserInstance);<br>
                    146: appCore.setWebShellWindow(window);<br>
                    147: </font></small><br>
                    148: The browser is initially blank (the use of &nbsp;"about:blank" as the <i>src</i>
                    149: attribute), so you have to load some content into the browser. Here a http
                    150: URL is used:<br>
1.3       brian     151: <pre><font face="Helvetica, Arial, sans-serif">const nsIWebNavigation = Components.interfaces.nsIWebNavigation;<br>myBrowser.webNavigation.loadURI("http://www.mozdev.org", nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);</font></pre>
1.6     ! brian     152: This creates an instance of the <i>nsIWebNavigation</i> XPCOM interface, which
        !           153: exposes a number if handy utilities for changing and navigating through the
        !           154: content displayed in the browser. In this instance, to load a page, the<i>loadURI</i>
        !           155: method is being used. Other methods of this interface include<span
        !           156:  style="font-style: italic;">goBack()</span>, <span
        !           157:  style="font-style: italic;">goForward()</span>, and <span
        !           158:  style="font-style: italic;">reload()</span>. <i>nsIWebNaviagtion</i> is
        !           159: just one of the interfaces available when you use the browser widget. Other
        !           160: include:<br>
1.2       brian     161: <ul>
                    162:   <li>preferences</li>
                    163:   <li>webBrowserFind</li>
                    164:   <li>contentViewer</li>
                    165:   <li>documentCharsetInfo<br>
                    166:   </li>
                    167: </ul>
                    168: A full list can be found in the <a
                    169:  href="http://lxr.mozilla.org/seamonkey/source/xpfe/global/resources/content/bindings/browser.xml">bindings
                    170: file</a> for the widget. These few steps provided in this section will send
                    171: you well on your way to getting a rich content browser set up in your Mozilla
                    172: application and act as a foundation for adding some of the other bells and
1.4       brian     173: whistles associated with a browser.<br>
1.1       brian     174:  
1.2       brian     175: <h3>The Art of Navigation</h3>
1.4       brian     176: What follows is a brief description of adding Back and Forward widgets and
                    177: functionality to your window. This is after all the basis of any reasonable
                    178: browser, but is used here to illustrate the process for hooking up functionality
1.6     ! brian     179: to your browser. The XUL file is the place to define your UI buttons. If
        !           180: you are proficient at XUL and CSS, you can make them into the style and appearance
1.4       brian     181: that you wish, but in this example the current navigator styles (using the
                    182: Modern theme) are used.<br>
                    183: <br>
1.5       brian     184: <div align="center"><img
                    185:  src="http://books.mozdev.org/articles/buttons.png"
                    186:  alt="Back and Forward Buttons" width="134" height="84"><br>
1.4       brian     187: </div>
1.6     ! brian     188: <div align="center"><i>Back and Forward Buttons</i><br>
1.4       brian     189: </div>
                    190: <br>
                    191: These are simple toolbar buttons. The back and forward buttons used in the
                    192: Mozilla browser have an integrated menu that creates a list of pages that
                    193: are available for each one. Appearance is achieved by including the <i>communicator</i>
1.6     ! brian     194: CSS file and using a class specific to buttons (toolbarbutton-1). Here is
        !           195: the XUL code for the buttons. <br>
1.4       brian     196: <br>
                    197: <small><font face="Helvetica, Arial, sans-serif">...<br>
                    198: &lt;?xml-stylesheet href="chrome://navigator/skin" type="text/css"?&gt;<br>
                    199: ...<br>
                    200: &lt;toolbarbutton id="back-button" class="toolbarbutton-1"<br>
                    201: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1.5       brian     202: tooltiptext="Go Back"<br>
1.4       brian     203: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    204: oncommand="goBack();"<br>
                    205: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    206: observes="canGoBack"&gt;<br>
                    207: &lt;/toolbarbutton&gt;<br>
1.5       brian     208: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
1.4       brian     209: &lt;toolbarbutton id="forward-button" class="toolbarbutton-1"<br>
1.5       brian     210: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font></small><small><font
                    211:  face="Helvetica, Arial, sans-serif">tooltiptext</font></small><small><font
                    212:  face="Helvetica, Arial, sans-serif">="Go Forward"<br>
1.4       brian     213: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    214: oncommand="goForward();"<br>
                    215: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    216: observes="canGoForward"&gt;<br>
                    217: &lt;/toolbarbutton&gt;</font></small><br>
                    218: <br>
1.5       brian     219: Apart from the <i>class</i> attribute on the buttons, the other main ones
1.6     ! brian     220: to watch for are <i>oncommand</i>, which bridges the functionality, and <i>observes</i>.
1.5       brian     221: The <i>observes</i> atribute determines if the button is active. There is
                    222: a little bit more trickery involved to get the buttons to move to and from
                    223: a disabled state depending on whether navigation can occur either forward
                    224: and back. We will not go into that here, but the full source code for the
                    225: <a href="http://books.mozdev.org/articles/browser.xul.txt">XUL file</a> and
1.6     ! brian     226: the <a href="http://books.mozdev.org/articles/browser.js.txt">JavaScript
        !           227: file</a>used in this article are available for reference. Lets look at the
        !           228: code for the <i>goBack()</i> and <i>goForward()</i> functions.<br>
1.5       brian     229: <br>
                    230: <small><font face="Helvetica, Arial, sans-serif">function goBack()<br>
                    231: {<br>
                    232: &nbsp;&nbsp;&nbsp; var webNavigation = myBrowser.webNavigation;<br>
                    233: &nbsp;&nbsp;&nbsp; if (webNavigation.canGoBack)<br>
                    234: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; webNavigation.goBack();<br>
                    235: }<br>
                    236: <br>
                    237: function goForward()<br>
                    238: {<br>
                    239: &nbsp;&nbsp;&nbsp; var webNavigation = myBrowser.webNavigation;<br>
                    240: &nbsp;&nbsp;&nbsp; if (webNavigation.canGoForward)<br>
                    241: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; webNavigation.goForward();<br>
                    242: }</font></small><br>
                    243: <br>
                    244: Once again the <i>webNavigation</i> interface is accessed through the browser
                    245: widget. After an efficiency check on the observer to see if the it is possible,
1.6     ! brian     246: the <span style="font-style: italic;">goBack()</span> or <span
        !           247:  style="font-style: italic;">goForward()</span> routine from the interface
        !           248: is called. And that is all there is to it -- 3 lines of code. The foundations
        !           249: were laid in the initialization code, and now the benefits are reaped.<br>
1.4       brian     250:    
1.5       brian     251: <h2>Up to You</h2>
                    252: The rest, as is said, is up to you. You can choose to make your browser as
                    253: simple or as complex as possible. Mozilla provides the widgets to hold your
                    254: content, and as was illustated in this article, it also gives you the source
1.6     ! brian     255: code to add rich functionality. The surface was only touched here. Other features
        !           256: you can hook in are context menus, events such as drag&amp;drop and onclick
        !           257: on the content area, and the viewing of page source. If you are truly ambitious
        !           258: you can even go one step further and use the tabbed browser. Integrated into
        !           259: the Mozilla browser and turned on by default, this has been a popular addition
        !           260: to the browsing experience, and has won many new users. Looking at the <i>&lt;tabbrowser&gt;</i>
        !           261: widget is more complex that the basic browser, but could bring more rewards.
        !           262: And don't forget, if it doesn't exactly meet your needs, you can change the
        !           263: source code!<br>
1.1       brian     264: <br>
                    265: </body>
                    266: </html>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>