Diff for /books/www/chapters/ch12.html between versions 1.8 and 1.9

version 1.8, 2002/12/05 13:59:03 version 1.9, 2002/12/11 18:57:10
Line 1 Line 1
<HTML>    <style type="text/css">
<HEAD><TITLE>Chapter 12</TITLE></HEAD><BODY BGCOLOR=WHITE><H2>Chapter 12</H2>      div.c26 {font-weight: bold; text-align: center}
<H1><A NAME="77066"></A> Remote Applications</H1>      div.c25 {text-align: center}
<P>Remote applications developed with Mozilla use an application without having to endure a full download process. Given the fundamental similarities of Mozilla and standard web content, a remote Mozilla application can work much like a regular web page. For example, you can point people to your project at http://<I><A HREF="http://www.foobar.com/myApp.xul">www.foobar.com/myApp.xul</A></I>, and if they use Mozilla (or a browser that is built with Mozilla, such as Netscape 7), the browser window becomes the application. Serving an application in this way allows you to use most features of a locally installed Mozilla program and gives you unique options that aren't otherwise available. These options are discussed in this chapter.    </style>
<P>This chapter explores this alternative distribution method and compares it to how an installable application is built. Generally, there is no difference between these two types of applications other than how they are delivered. However, you should be aware of the difficulties encountered when using remote applications.
<P>One of the most important aspects of remote applications for Mozilla is the XPFE environment, or more specifically, the use of XUL/XBL, JavaScript, and CSS. Using the XPFE in remote application development offers more possibilities than, for example, just embedding Gecko into your application. It is the focus of this chapter.    <h2>Chapter 12</h2>
<H2><A NAME="77067"></A> Directions in Remote Application Development</H2>    <h1><a name="77066"></a> Remote Applications</h1>
<P>Currently, remote  <!--INDEX development:remote applications, overview -->  <!--INDEX remote applications:overview -->  <!--INDEX applications:remote, development --> Mozilla applications are not prevalent because development focuses on making the client applications as stable and efficient as possible. Therefore, this area of Mozilla development is largely speculative. This chapter argues that remote applications are worth looking at more closely.    <p>Remote applications developed with Mozilla use an
<P>One advantage a remote Mozilla application has over a client application is that a developer doesn't have to worry about an installer. Also, all users have access to the latest version of your application. Because the application is stored centrally on a server instead of on the local computer of everyone who tries your program, when you update it, you make an update available to all users.    application without having to endure a full download process.
<P>Remote software applications might be  <!--INDEX hosting remote applications -->  <!--INDEX networks, hosting remote applications --> hosted in a centralized point on the network, on multiple nodes, or on any random node in a Peer to Peer (P2P) fashion. It's even possible to have a whole suite of remote Mozilla applications hosted on several computers combined into one coherent package. <A HREF="#77002">Figure 12-1</A> shows one scenario for a simple distributed Mozilla application.    Given the fundamental similarities of Mozilla and standard web
<P><CENTER><IMG SRC="foo.gif"></CENTER>    content, a remote Mozilla application can work much like a
<P><I>Figure 12-1: <A NAME="77002"></A></I>    regular web page. For example, you can point people to your
<I>Distributed remote Mozilla application</I>    project at http://<i><a href=
    "http://www.foobar.com/myApp.xul">www.foobar.com/myApp.xul</a></i>,
<P>Currently, one of the remote application's biggest disadvantages is that it has very restricted JavaScript  <!--INDEX privileges:remote applications:JavaScript -->  <!--INDEX JavaScript:privileges, remote applications --> privileges. Here, privileges refer to the ability to carry out certain functionalities on the local system. As many high-profile "worm" viruses emerge routinely these days, security <!--INDEX security:remote applications -->  restrictions on downloadable scripts and applications are understandable. Some of the most high-profile malicious scripts access the local file system. This is not a problem unique to the Mozilla environment, but it is something to be aware of when planning and implementing a remote application.    and if they use Mozilla (or a browser that is built with
<P>To improve security, Mozilla automatically limits what JavaScript has access to on your computer when the executed scripts come from a computer other than the local one. One workaround uses signed scripts, as described in the <A HREF="#77088">"Creating Signed Remote Applications</A>" section later in this chapter. You can also have users set a special preference to enable universal XPConnect privileges to both local and remote files. To learn how to open up the security sandbox in this way, see the section <A HREF="#77095">"Expanded Privileges in Mozilla</A>" later in this chapter.    Mozilla, such as Netscape 7), the browser window becomes the
<H2><A NAME="77068"></A> Basic Remote Application Example</H2>    application. Serving an application in this way allows you to
<P>The <!--INDEX remote applications:XUL example -->  <!--INDEX XUL (XML-based User-interface Language):remote application example -->  simple XUL file in <A HREF="#77026">Example 12-1</A> uses the user's local skin information to create a toolbar-type interface for a file that can be loaded from the server. This successful effect depends on whether your server is configured with the correct Multipart Internet Mail Extension (MIME) type (see the later section <A HREF="#77071">"Server Configuration</A>"). The <TT>id</TT> on the buttons are taken from the navigator skin, so the look of the remote file changes when the user switches themes and remains consistent with the look of the browser itself.    use most features of a locally installed Mozilla program and
    gives you unique options that aren't otherwise available. These
<P><I>Example 12-1: <A NAME="77026"></A></I>    options are discussed in this chapter.</p>
<I>Remote XUL example</I>    <p>This chapter explores this alternative distribution method
<PRE> &lt;?xml version="1.0"?&gt;    and compares it to how an installable application is built.
     Generally, there is no difference between these two types of
     applications other than how they are delivered. However, you
     should be aware of the difficulties encountered when using
     remote applications.</p>
     <p>One of the most important aspects of remote applications for
     Mozilla is the XPFE environment, or more specifically, the use
     of XUL/XBL, JavaScript, and CSS. Using the XPFE in remote
     application development offers more possibilities than, for
     example, just embedding Gecko into your application. It is the
     focus of this chapter.</p>
     <h2><a name="77067"></a> Directions in Remote Application
     Development</h2>
     <p>Currently, remote 
     <!--INDEX development:remote applications, overview --> 
     <!--INDEX remote applications:overview --> 
     <!--INDEX applications:remote, development --> Mozilla
     applications are not prevalent because development focuses on
     making the client applications as stable and efficient as
     possible. Therefore, this area of Mozilla development is
     largely speculative. This chapter argues that remote
     applications are worth looking at more closely.</p>
     <p>One advantage a remote Mozilla application has over a client
     application is that a developer doesn't have to worry about an
     installer. Also, all users have access to the latest version of
     your application. Because the application is stored centrally
     on a server instead of on the local computer of everyone who
     tries your program, when you update it, you make an update
     available to all users.</p>
     <p>Remote software applications might be 
     <!--INDEX hosting remote applications --> 
     <!--INDEX networks, hosting remote applications --> hosted in a
     centralized point on the network, on multiple nodes, or on any
     random node in a Peer to Peer (P2P) fashion. It's even possible
     to have a whole suite of remote Mozilla applications hosted on
     several computers combined into one coherent package. <a href=
     "#77002">Figure 12-1</a> shows one scenario for a simple
     distributed Mozilla application.</p>
     <div class="c25">
       <img src="foo.gif">
     </div>
     <p><i>Figure 12-1: <a name="77002"></a></i> <i>Distributed
     remote Mozilla application</i></p>
     <p>Currently, one of the remote application's biggest
     disadvantages is that it has very restricted JavaScript 
     <!--INDEX privileges:remote applications:JavaScript --> 
     <!--INDEX JavaScript:privileges, remote applications -->
     privileges. Here, privileges refer to the ability to carry out
     certain functionalities on the local system. As many
     high-profile "worm" viruses emerge routinely these days,
     security <!--INDEX security:remote applications -->
     restrictions on downloadable scripts and applications are
     understandable. Some of the most high-profile malicious scripts
     access the local file system. This is not a problem unique to
     the Mozilla environment, but it is something to be aware of
     when planning and implementing a remote application.</p>
     <p>To improve security, Mozilla automatically limits what
     JavaScript has access to on your computer when the executed
     scripts come from a computer other than the local one. One
     workaround uses signed scripts, as described in the <a href=
     "#77088">"Creating Signed Remote Applications</a>" section
     later in this chapter. You can also have users set a special
     preference to enable universal XPConnect privileges to both
     local and remote files. To learn how to open up the security
     sandbox in this way, see the section <a href="#77095">"Expanded
     Privileges in Mozilla</a>" later in this chapter.</p>
     <h2><a name="77068"></a> Basic Remote Application Example</h2>
     <p>The <!--INDEX remote applications:XUL example --> 
     <!--INDEX XUL (XML-based User-interface Language):remote application example -->
     simple XUL file in <a href="#77026">Example 12-1</a> uses the
     user's local skin information to create a toolbar-type
     interface for a file that can be loaded from the server. This
     successful effect depends on whether your server is configured
     with the correct Multipart Internet Mail Extension (MIME) type
     (see the later section <a href="#77071">"Server
     Configuration</a>"). The <tt>id</tt> on the buttons are taken
     from the navigator skin, so the look of the remote file changes
     when the user switches themes and remains consistent with the
     look of the browser itself.</p>
     <p><i>Example 12-1: <a name="77026"></a></i> <i>Remote XUL
     example</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;   &lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;
  &lt;?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?&gt;   &lt;?xml-stylesheet href="chrome://navigator/skin/" type="text/css"?&gt;
  &lt;window id="remote_example"   &lt;window id="remote_example"
     xmlns="<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"     xmlns="<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
      title="Simple Remote Example"&gt;       title="Simple Remote Example"&gt;
    &lt;hbox&gt;     &lt;hbox&gt;
     &lt;button label="XFlies" class="button-toolbar" id="page-proxy-button"</TD>/&gt;     &lt;button label="XFlies" class="button-toolbar" id="page-proxy-button"&lt;/td&gt;/&gt;
      &lt;button label="Reptiles" class="button-toolbar" /&gt;       &lt;button label="Reptiles" class="button-toolbar" /&gt;
      &lt;button label="Bugs" class="button-toolbar" /&gt;       &lt;button label="Bugs" class="button-toolbar" /&gt;
    &lt;/hbox&gt;     &lt;/hbox&gt;
 &lt;/window&gt;</PRE> &lt;/window&gt;
</pre>
<P>As you can see in <A HREF="#77026">Example 12-1</A>, the markup of a remote XUL file is like that of a XUL file that is part of a local system's installed application. <A HREF="#77004">Figure 12-2</A> shows the XUL file presented using both Classic and Modern themes.    <p>As you can see in <a href="#77026">Example 12-1</a>, the
<P><CENTER><IMG SRC="foo.gif"></CENTER>    markup of a remote XUL file is like that of a XUL file that is
<P><I>Figure 12-2: <A NAME="77004"></A></I>    part of a local system's installed application. <a href=
<I>Remote XUL file-accessing skin</I>    "#77004">Figure 12-2</a> shows the XUL file presented using
    both Classic and Modern themes.</p>
<P>The XUL in <A HREF="#77026">Example 12-1</A> is minimal, but it does show that the <I>chrome://</I> URLs are accessible to the remote file and that the CSS and image resources available in the chrome's skin subdirectories can be accessed remotely. The image on the first button is picked up from a local JAR file, as accessed through chrome by using the button's <TT>page-proxy-button id</TT>. A more elegant application would use toolbars, menus, and other widgets to create a full-featured application UI.    <div class="c25">
<H3><A NAME="77069"></A> Case Study: Snake (a.k.a. Hiss-zilla)</H3>      <img src="foo.gif">
<P>In this  <!--INDEX remote applications:case studies, gaming -->  <!--INDEX games:remote applications, case studies --> section, we look at an application that is stripped down and based on a basic concept but still useful. This application shows the potential of remote application development. This case study discusses a full-featured game that is played over the Internet. <A HREF="#77006">Figure 12-3</A> below shows a sample screenshot of Hiss-zilla.    </div>
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <p><i>Figure 12-2: <a name="77004"></a></i> <i>Remote XUL
<P><I>Figure 12-3: <A NAME="77006"></A></I>    file-accessing skin</i></p>
<I>Hiss-zilla, a remote game</I>    <p>The XUL in <a href="#77026">Example 12-1</a> is minimal, but
    it does show that the <i>chrome://</i> URLs are accessible to
<P>A direct link to a remote XUL file provides access to the game, as seen in the location bar of the browser in <A HREF="#77006">Figure 12-3</A>. The game's rules are straightforward. Click on the New Game button or use N on the keyboard to begin, use arrow keys to change direction, and use the character P to pause the game. To play a game of Hiss-zilla or to take a closer look at the code, see the project page <I><A HREF="http://games.mozdev.org/action/snake/">http://games.mozdev.org/action/snake/</A></I>.    the remote file and that the CSS and image resources available
<P>The complete package includes all files associated with an XPFE application, including a XUL file, a stylesheet, images, and JavaScript files. The files and their descriptions are as follows:    in the chrome's skin subdirectories can be accessed remotely.
<DL><DT>snake.xul    The image on the first button is picked up from a local JAR
<DD>Contains the window definition and the top level of the application with the game grid, visual text, and application buttons.<P>    file, as accessed through chrome by using the button's
<DT>snake.js    <tt>page-proxy-button id</tt>. A more elegant application would
<DD>Contains the functionality for the game including the snake's movement and the eating of the food.<P>    use toolbars, menus, and other widgets to create a
<DT>snake.css    full-featured application UI.</p>
<DD>Contains styling for the UI features and inclusion of some images.<P>    <h3><a name="77069"></a> Case Study: Snake (a.k.a.
<DT>screen.js    Hiss-zilla)</h3>
<DD>Enables full screen mode in the game.<P>    <p>In this 
<DT>Image files    <!--INDEX remote applications:case studies, gaming --> 
<DD>Miscellaneous images that represent parts of the snake's body as it moves in different directions and the food that it eats.<P></DL>    <!--INDEX games:remote applications, case studies --> section,
<P>The Snake application will be developed further later in the chapter in the context of signed scripts. You will see new features that allow you to run the game in full-screen mode and to store the scores. These features illustrate different concepts relevant to remote applications.    we look at an application that is stripped down and based on a
<BLOCKQUOTE><HR><B>Mozilla Gaming</B>    basic concept but still useful. This application shows the
<P>Hiss-zilla is not the only example of a game created with Mozilla. Others, such as Mozinvaders, Mozteroids, PAGMAN, and Xultris use JavaScript and Mozilla's rendering engine to recreate two-dimensional arcade games from the 80s and early 90s. Links to most games are available at <I><A HREF="http://games.mozdev.org/">http://games.mozdev.org/</A></I>.    potential of remote application development. This case study
<P>Many of these games were created to see how far the application development capabilities of Mozilla could be pushed. PAGMAN in particular was designed as a test case to see what was possible; the result was almost identical to the original PacMan game. The creation of PAGMAN was documented in an article that provides more information about how the game came about and was developed. You can find the <I>Building a Game in Mozilla</I> article at <I><A HREF="http://www.oreillynet.com/pub/a/network/2000/06/30/magazine/mozilla_game.html">http://www.oreillynet.com/pub/a/network/2000/06/30/magazine/mozilla_game.html</A></I>.    discusses a full-featured game that is played over the
<P>Although all of these games are freely available as open source projects, not all of them work with Mozilla 1.0. Many were created while Mozilla was still in development, so games that worked on pre-1.0 releases of Mozilla need additional development to work today. The good news is that if you are just dying to play Mozteroids or Xultris, you can take what you have learned in this book and update the projects so everyone can enjoy them.<HR></BLOCKQUOTE>    Internet. <a href="#77006">Figure 12-3</a> below shows a sample
    screenshot of Hiss-zilla.</p>
<H2><A NAME="77070"></A> Setting Up XPFE for Remote Applications</H2>    <div class="c25">
<P>Remote Mozilla  <!--INDEX remote applications:XPFE:overview -->  <!--INDEX XPFE:remote applications:overview --> applications are limited because they cannot access and use some of the rich functionality provided in XPCOM interfaces. Unless you make the privilege change described in this section, access to <!--INDEX XPCOM:remote applications, enabling -->  <!--INDEX privileges:XPCOM, enabling for remote applications -->  <!--INDEX remote applications:XPCOM, enabling -->  XPCOM via XPConnect in your web page or remote application is forbidden. This privilege modification set up by the remote application developer grants complete access to the Mozilla functionality, to resources in the chrome, and to the host system via the Mozilla components that handle such tasks as File I/O. Of course, making this change means that the files on your server could be read, written to, or deleted, which is why rights are restricted by default. We recommend that you grant this extended privilege only when you do not have valuable data on the server or if you have taken steps to ensure that the data cannot be accessed.      <img src="foo.gif">
<P>The privilege, called  <!--INDEX Universal XPConnect --> Universal XPConnect, can be turned on from the  <!--INDEX Privilege Manager, remote applications --> Privilege Manager, which is a property of the <TT>netscape.security</TT> object. <A HREF="#77028">Example 12-2</A> shows a script that turns this privilege on and then uses new found privilege to create XPCOM component instance.    </div>
    <p><i>Figure 12-3: <a name="77006"></a></i> <i>Hiss-zilla, a
<P><I>Example 12-2: <A NAME="77028"></A></I>    remote game</i></p>
<I>Enabling universal XPConnect</I>    <p>A direct link to a remote XUL file provides access to the
<PRE> &lt;script type="application/x-JavaScript"&gt;    game, as seen in the location bar of the browser in <a href=
     "#77006">Figure 12-3</a>. The game's rules are straightforward.
     Click on the New Game button or use N on the keyboard to begin,
     use arrow keys to change direction, and use the character P to
     pause the game. To play a game of Hiss-zilla or to take a
     closer look at the code, see the project page <i><a href=
     "http://games.mozdev.org/action/snake/">http://games.mozdev.org/action/snake/</a></i>.</p>
     <p>The complete package includes all files associated with an
     XPFE application, including a XUL file, a stylesheet, images,
     and JavaScript files. The files and their descriptions are as
     follows:</p>
     <dl>
       <dt>snake.xul</dt>
       <dd>Contains the window definition and the top level of the
       application with the game grid, visual text, and application
       buttons.</dd>
       <dt>snake.js</dt>
       <dd>Contains the functionality for the game including the
       snake's movement and the eating of the food.</dd>
       <dt>snake.css</dt>
       <dd>Contains styling for the UI features and inclusion of
       some images.</dd>
       <dt>screen.js</dt>
       <dd>Enables full screen mode in the game.</dd>
       <dt>Image files</dt>
       <dd>Miscellaneous images that represent parts of the snake's
       body as it moves in different directions and the food that it
       eats.</dd>
     </dl>
     <p>The Snake application will be developed further later in the
     chapter in the context of signed scripts. You will see new
     features that allow you to run the game in full-screen mode and
     to store the scores. These features illustrate different
     concepts relevant to remote applications.</p>
     <blockquote>
       <hr>
       <b>Mozilla Gaming</b> 
       <p>Hiss-zilla is not the only example of a game created with
       Mozilla. Others, such as Mozinvaders, Mozteroids, PAGMAN, and
       Xultris use JavaScript and Mozilla's rendering engine to
       recreate two-dimensional arcade games from the 80s and early
       90s. Links to most games are available at <i><a href=
       "http://games.mozdev.org/">http://games.mozdev.org/</a></i>.</p>
       <p>Many of these games were created to see how far the
       application development capabilities of Mozilla could be
       pushed. PAGMAN in particular was designed as a test case to
       see what was possible; the result was almost identical to the
       original PacMan game. The creation of PAGMAN was documented
       in an article that provides more information about how the
       game came about and was developed. You can find the
       <i>Building a Game in Mozilla</i> article at <i><a href=
       "http://www.oreillynet.com/pub/a/network/2000/06/30/magazine/mozilla_game.html">
       http://www.oreillynet.com/pub/a/network/2000/06/30/magazine/mozilla_game.html</a></i>.</p>
       <p>Although all of these games are freely available as open
       source projects, not all of them work with Mozilla 1.0. Many
       were created while Mozilla was still in development, so games
       that worked on pre-1.0 releases of Mozilla need additional
       development to work today. The good news is that if you are
       just dying to play Mozteroids or Xultris, you can take what
       you have learned in this book and update the projects so
       everyone can enjoy them.</p>
       <hr>
     </blockquote>
     <h2><a name="77070"></a> Setting Up XPFE for Remote
     Applications</h2>
     <p>Remote Mozilla 
     <!--INDEX remote applications:XPFE:overview --> 
     <!--INDEX XPFE:remote applications:overview --> applications
     are limited because they cannot access and use some of the rich
     functionality provided in XPCOM interfaces. Unless you make the
     privilege change described in this section, access to 
     <!--INDEX XPCOM:remote applications, enabling --> 
     <!--INDEX privileges:XPCOM, enabling for remote applications -->
     <!--INDEX remote applications:XPCOM, enabling --> XPCOM via
     XPConnect in your web page or remote application is forbidden.
     This privilege modification set up by the remote application
     developer grants complete access to the Mozilla functionality,
     to resources in the chrome, and to the host system via the
     Mozilla components that handle such tasks as File I/O. Of
     course, making this change means that the files on your server
     could be read, written to, or deleted, which is why rights are
     restricted by default. We recommend that you grant this
     extended privilege only when you do not have valuable data on
     the server or if you have taken steps to ensure that the data
     cannot be accessed.</p>
     <p>The privilege, called <!--INDEX Universal XPConnect -->
     Universal XPConnect, can be turned on from the 
     <!--INDEX Privilege Manager, remote applications --> Privilege
     Manager, which is a property of the <tt>netscape.security</tt>
     object. <a href="#77028">Example 12-2</a> shows a script that
     turns this privilege on and then uses new found privilege to
     create XPCOM component instance.</p>
     <p><i>Example 12-2: <a name="77028"></a></i> <i>Enabling
     universal XPConnect</i></p>
 <pre>
  &lt;script type="application/x-JavaScript"&gt;
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  var Simple=new Components.Constructor("@mozilla.org/js_simple_component;1", "nsISimple");   var Simple=new Components.Constructor("@mozilla.org/js_simple_component;1", "nsISimple");
  var s = new Simple( );   var s = new Simple( );
  for(var list in s)   for(var list in s)
  document.write(list+"&lt;br&gt;\n");   document.write(list+"&lt;br&gt;\n");
 &lt;/script&gt;</PRE> &lt;/script&gt;
</pre>
<P>You can also turn on this privilege in your profile user preference file with the following line:    <p>You can also turn on this privilege in your profile user
<PRE>enablePrivilege("UniversalXPConnect");</PRE>    preference file with the following line:</p>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER><pre>
<P>A script with this kind of plate-cleaning power can only be run successfully when it's executed locally, as from a local XUL file with a <TT>&lt;DEFANGED_script&gt;</TT> element. To open up XPConnect remotely with JavaScript like this, you have to use a signed script (see the section <A HREF="#77088">"Creating Signed Remote Applications</A>" in this chapter).<P></BLOCKQUOTE>enablePrivilege("UniversalXPConnect");
<P>Once this privilege is enabled, remote XUL applications can run as if they are local. Remote files can use any Mozilla component, reuse skin resources, XBL widgets, and whatever else the browser uses.</pre>
<H3><A NAME="77071"></A> Server Configuration</H3>    <blockquote>
<P>Proper configuration <!--INDEX XUL (XML-based User-interface Language):remote applications, MIME type configuration -->  <!--INDEX remote applications:XPFE:XUL MIME type configuration -->  <!--INDEX XPFE:remote applications:XUL MIME type configuration -->  of  <!--INDEX configuring servers, remote applications and -->  <!--INDEX servers for remote applications, XUL MIME type configuration --> the XUL MIME type on your web server is necessary to serve remote Mozilla applications successfully. The trick is to ensure that the server recognizes the XUL file type and knows how to serve it properly. By default, most web servers serve files with such unrecognized extensions as <I>text/plain</I>. By adding the type <I>application/vnd.mozilla.xul+xml</I> to your server's configuration, you can make sure that the server matches the file extension and sends this MIME type in the HTTP header to the browser. To serve up static XUL pages from your web server, you need to add this line to your <I>mime.types</I> file if it hasn't been added already:      <div class="c26">
<PRE>application/vnd.mozilla.xul+xml  &lt;TAB&gt; xul</PRE>        NOTE
<P>This is how you can configure Apache MIME types to serve static XUL pages. Note that the <I>mime.types</I> file requires that you separate the type from the suffix. The format is:      </div>
<PRE>mime type &lt;tab&gt; extension.</PRE>      <p>A script with this kind of plate-cleaning power can only
<P>After the type is added to the server, the browser recognizes this header as an XUL file and parses, renders, and creates the appropriate DOM. If your server isn't configured to recognize this MIME type, then users see the contents of your file as source only-a plain text complete with all the formatting.      be run successfully when it's executed locally, as from a
<P>Now that your web server is configured correctly, you can add a sample XUL file (such as the file in <A HREF="#77030">Example 12-3</A>) to your web site to make sure things are running properly. You should name the file <I>remote.xul</I> and save it in your web site's root directory for testing.      local XUL file with a <tt>&lt;DEFANGED_script&gt;</tt>
      element. To open up XPConnect remotely with JavaScript like
<P><I>Example 12-3: <A NAME="77030"></A></I>      this, you have to use a signed script (see the section <a
<I>A sample static XUL file</I>      href="#77088">"Creating Signed Remote Applications</a>" in
<PRE> &lt;?xml version="1.0"?&gt;      this chapter).</p>
     </blockquote>
     <p>Once this privilege is enabled, remote XUL applications can
     run as if they are local. Remote files can use any Mozilla
     component, reuse skin resources, XBL widgets, and whatever else
     the browser uses.</p>
     <h3><a name="77071"></a> Server Configuration</h3>
     <p>Proper configuration 
     <!--INDEX XUL (XML-based User-interface Language):remote applications, MIME type configuration -->
     <!--INDEX remote applications:XPFE:XUL MIME type configuration -->
     <!--INDEX XPFE:remote applications:XUL MIME type configuration -->
     of <!--INDEX configuring servers, remote applications and --> 
     <!--INDEX servers for remote applications, XUL MIME type configuration -->
     the XUL MIME type on your web server is necessary to serve
     remote Mozilla applications successfully. The trick is to
     ensure that the server recognizes the XUL file type and knows
     how to serve it properly. By default, most web servers serve
     files with such unrecognized extensions as <i>text/plain</i>.
     By adding the type <i>application/vnd.mozilla.xul+xml</i> to
     your server's configuration, you can make sure that the server
     matches the file extension and sends this MIME type in the HTTP
     header to the browser. To serve up static XUL pages from your
     web server, you need to add this line to your <i>mime.types</i>
     file if it hasn't been added already:</p>
 <pre>
 application/vnd.mozilla.xul+xml  &lt;TAB&gt; xul
 </pre>
     <p>This is how you can configure Apache MIME types to serve
     static XUL pages. Note that the <i>mime.types</i> file requires
     that you separate the type from the suffix. The format is:</p>
 <pre>
 mime type &lt;tab&gt; extension.
 </pre>
     <p>After the type is added to the server, the browser
     recognizes this header as an XUL file and parses, renders, and
     creates the appropriate DOM. If your server isn't configured to
     recognize this MIME type, then users see the contents of your
     file as source only-a plain text complete with all the
     formatting.</p>
     <p>Now that your web server is configured correctly, you can
     add a sample XUL file (such as the file in <a href=
     "#77030">Example 12-3</a>) to your web site to make sure things
     are running properly. You should name the file
     <i>remote.xul</i> and save it in your web site's root directory
     for testing.</p>
     <p><i>Example 12-3: <a name="77030"></a></i> <i>A sample static
     XUL file</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE window&gt;   &lt;!DOCTYPE window&gt;
  &lt;window   &lt;window
    id = "remote"     id = "remote"
   xmlns = "<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"   xmlns = "<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
    title = "A Remote Image"     title = "A Remote Image"
    style = "min-width:282px; min-height:137px;"     style = "min-width:282px; min-height:137px;"
    orient = "vertical"&gt;     orient = "vertical"&gt;
   &lt;image src="<A HREF="http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</A>" /&gt;   &lt;image src="<a href=
 &lt;/window&gt;</PRE>"http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>" /&gt;
 &lt;/window&gt;
<P>You can now view this window by launching it as a chrome file from Mozilla as follows:</pre>
<PRE>./mozilla -chrome <A HREF="http://my.domain/remote.xul">http://my.domain/remote.xul</A></PRE>    <p>You can now view this window by launching it as a chrome
<P>Or you can also load it up by simply entering the URL in your browser location bar as follows::    file from Mozilla as follows:</p>
<PRE><A HREF="http://my.domain/remote.xul">http://my.domain/remote.xul</A></PRE><pre>
<H2><A NAME="77072"></A> Generated Content</H2>./mozilla -chrome <a href=
<P>Today par <!--INDEX remote applications:dynamic content --> t of the Web is driven by dynamically generated content. This content is primarily stored in databases, which is used by an application or middle layer to format the data to HTML. The web server then sends the content to the browser. The browser receives the web page as the end result and has no knowledge that the page was generated on the server-just that it is a properly formatted HTML file. By using these same conventional principals, we can send generated or database-driven XUL, CSS, or JavaScript to Mozilla. Because XUL is a document that creates a UI, this widget drawing capability opens up a whole new world to web application development."http://my.domain/remote.xul">http://my.domain/remote.xul</a>
<P>If you are a web developer creating database-driven applications, you will quickly see the limitations of using a simple markup like HTML-for example, being constrained to the content area of a browser for which you cannot manage all of the application interface's "real estate." Using a browser window for your application is a common enough practice, but you still don't have the application-level widgets of most client-side applications when you use HTML. This section shows that using XUL files created by scripting languages allows you to create windows and applications that move out of the browser window and into the full-featured application space. Mozilla's origins, after all, are as a web browser and suite of Internet applications, and the latest technologies in the XPFE toolkit go that extra step to allow the presentation of UI information over the wire.</pre>
<H3><A NAME="77073"></A> Generating Content with Scripting Languages</H3>    <p>Or you can also load it up by simply entering the URL in
<P>This section <!--INDEX remote applications:dynamic content:scripting languages -->  <!--INDEX scripting:remote applications:dynamic content -->  discusses the basic mechanics of server-generated content. In most cases, the actual content is static-although the server application creates the page dynamically, the content itself is not input. It is also not created dynamically by other methods, such as using JavaScript to manipulate the client's document after it loads from the server.    your browser location bar as follows::</p>
<P>To generate server-generated content, you need to use a scripting language. We explore the use of three different options: PHP, Perl, and Python. PHP is probably the most natural language for this application because it has its origins in serving up dynamic HTML, but you can play around with your favorite language and determine whether it has the appropriate capabilities for this environment. To use various scripting languages with Mozilla, you need a working knowledge of their capabilities; the scope of this book doesn't provide programming information for the selected scripting languages.<pre>
<H4><A NAME="77074"></A> PHP</H4><a href=
<P>When  <!--INDEX PHP remote applications -->  <!--INDEX remote applications:dynamic content:PHP -->  <!--INDEX scripting:remote applications:PHP --> users of your application may not have configured their browser to support the correct MIME type, you can use the PHP header function to send the browser the correct type."http://my.domain/remote.xul">http://my.domain/remote.xul</a>
<P>Remember that when using XUL with PHP, you need to edit your <I>php.ini</I> file on the server and change the default configuration to:</pre>
<PRE>short_open_tag  =   Off</PRE>    <h2><a name="77072"></a> Generated Content</h2>
<P>By default, this configuration is set to "On." When "Off," this setting tells the PHP interpreter to parse only the files with escape tag identifiers, such as <TT>&lt;?php ?&gt;</TT> (and not <TT>&lt;? ?&gt;</TT>, which are used by XML). This process is separate from the XML parsing process that occurs when Mozilla receives and tries to render the generated content. If you don't change the <I>.ini</I> file, you will see an error like this:    <p>Today par <!--INDEX remote applications:dynamic content -->
<PRE>Parse error: parse error in /usr/local/share/doc/apache/remote_xul.php on line 2</PRE>    t of the Web is driven by dynamically generated content. This
<P>This error occurs when PHP sees your XUL syntax as invalid PHP code.    content is primarily stored in databases, which is used by an
<P>Once PHP is properly configured to handle XUL files, you're ready to go. To start out with something simple, use the code in <A HREF="#77032">Example 12-4</A> to produce a simple XUL window with the xFly logo by using PHP. Be sure to save the file with a <I>.php</I> extension.    application or middle layer to format the data to HTML. The web
    server then sends the content to the browser. The browser
<P><I>Example 12-4: <A NAME="77032"></A></I>    receives the web page as the end result and has no knowledge
<I>Using PHP to generate the correct XUL MIME type</I>    that the page was generated on the server-just that it is a
<PRE> &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;    properly formatted HTML file. By using these same conventional
 &lt;</TD>?xml version="1.0"?&gt;    principals, we can send generated or database-driven XUL, CSS,
     or JavaScript to Mozilla. Because XUL is a document that
     creates a UI, this widget drawing capability opens up a whole
     new world to web application development.</p>
     <p>If you are a web developer creating database-driven
     applications, you will quickly see the limitations of using a
     simple markup like HTML-for example, being constrained to the
     content area of a browser for which you cannot manage all of
     the application interface's "real estate." Using a browser
     window for your application is a common enough practice, but
     you still don't have the application-level widgets of most
     client-side applications when you use HTML. This section shows
     that using XUL files created by scripting languages allows you
     to create windows and applications that move out of the browser
     window and into the full-featured application space. Mozilla's
     origins, after all, are as a web browser and suite of Internet
     applications, and the latest technologies in the XPFE toolkit
     go that extra step to allow the presentation of UI information
     over the wire.</p>
     <h3><a name="77073"></a> Generating Content with Scripting
     Languages</h3>
     <p>This section 
     <!--INDEX remote applications:dynamic content:scripting languages -->
     <!--INDEX scripting:remote applications:dynamic content -->
     discusses the basic mechanics of server-generated content. In
     most cases, the actual content is static-although the server
     application creates the page dynamically, the content itself is
     not input. It is also not created dynamically by other methods,
     such as using JavaScript to manipulate the client's document
     after it loads from the server.</p>
     <p>To generate server-generated content, you need to use a
     scripting language. We explore the use of three different
     options: PHP, Perl, and Python. PHP is probably the most
     natural language for this application because it has its
     origins in serving up dynamic HTML, but you can play around
     with your favorite language and determine whether it has the
     appropriate capabilities for this environment. To use various
     scripting languages with Mozilla, you need a working knowledge
     of their capabilities; the scope of this book doesn't provide
     programming information for the selected scripting
     languages.</p>
     <h4><a name="77074"></a> PHP</h4>
     <p>When <!--INDEX PHP remote applications --> 
     <!--INDEX remote applications:dynamic content:PHP --> 
     <!--INDEX scripting:remote applications:PHP --> users of your
     application may not have configured their browser to support
     the correct MIME type, you can use the PHP header function to
     send the browser the correct type.</p>
     <p>Remember that when using XUL with PHP, you need to edit your
     <i>php.ini</i> file on the server and change the default
     configuration to:</p>
 <pre>
 short_open_tag  =   Off
 </pre>
     <p>By default, this configuration is set to "On." When "Off,"
     this setting tells the PHP interpreter to parse only the files
     with escape tag identifiers, such as <tt>&lt;?php ?&gt;</tt>
     (and not <tt>&lt;? ?&gt;</tt>, which are used by XML). This
     process is separate from the XML parsing process that occurs
     when Mozilla receives and tries to render the generated
     content. If you don't change the <i>.ini</i> file, you will see
     an error like this:</p>
 <pre>
 Parse error: parse error in /usr/local/share/doc/apache/remote_xul.php on line 2
 </pre>
     <p>This error occurs when PHP sees your XUL syntax as invalid
     PHP code.</p>
     <p>Once PHP is properly configured to handle XUL files, you're
     ready to go. To start out with something simple, use the code
     in <a href="#77032">Example 12-4</a> to produce a simple XUL
     window with the xFly logo by using PHP. Be sure to save the
     file with a <i>.php</i> extension.</p>
     <p><i>Example 12-4: <a name="77032"></a></i> <i>Using PHP to
     generate the correct XUL MIME type</i></p>
 <pre>
  &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;
  &lt;&lt;/td&gt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE window&gt;   &lt;!DOCTYPE window&gt;
  &lt;window   &lt;window
      id     = "remote"       id     = "remote"
     xmlns  = "<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"     xmlns  = "<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
      title  = "A Remote Image"       title  = "A Remote Image"
      style  = "min-width:282px; min-height:137px;"       style  = "min-width:282px; min-height:137px;"
      orient = "vertical"&gt;       orient = "vertical"&gt;
   &lt;image src="<A HREF="http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</A>" /&gt;   &lt;image src="<a href=
 &lt;/window&gt;</PRE>"http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>" /&gt;
 &lt;/window&gt;
<P>Also remember that a space below the PHP tag results in a parse error in Mozilla. The next example shows the PHP header and the XML declaration at the start of the PHP file. The space between the two renders it invalid:</pre>
<PRE>&lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;    <p>Also remember that a space below the PHP tag results in a
&lt;?xml version="1.0"?&gt;</PRE>    parse error in Mozilla. The next example shows the PHP header
<P>After PHP parses its content on the server, the rest of the document is sent to Mozilla on the client. Put this file (<TT>remote_xul.php</TT>) somewhere in your document root on the server with PHP installed and launch it from Mozilla like this:    and the XML declaration at the start of the PHP file. The space
<PRE>./mozilla -chrome <A HREF="http://my.domain/remote_xul.php">http://my.domain/remote_xul.php</A></PRE>    between the two renders it invalid:</p>
<P>The window defined in <A HREF="#77032">Example 12-4</A> now appears, displaying the image. You can take advantage of this relatively straightforward technique to serve up more feature-rich user interfaces, inclusive of buttons, menus, and any other pieces of XUL that are needed.<pre>
<H4><A NAME="77075"></A> Perl</H4>&lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;
<P>Although <!--INDEX Perl:remote applications -->  <!--INDEX remote applications:dynamic content:Perl -->  <!--INDEX scripting:remote applications:Perl -->  PHP is rising in popularity, Perl is still a very popular web-scripting language. Perl is often used to drive back end web applications with CGI scripts. To process Perl scripts, no extra configuration is needed once you have the Perl interpreter set up to run in a web server environment. If, for example, you're already using Perl to serve up dynamic HTML pages, you're all set. Otherwise, you should grab a distribution of Perl (<I><A HREF="http://perl.com/">http://perl.com/</A></I>) and set up the paths to the binary files in your server scripts. This procedure is done by placing the path in the header, otherwise known as the <I>shebang line</I>. This script usually takes a form similar to <TT>#!/usr/local/bin/perl</TT> or <TT>#!/usr/bin/perl</TT>. You must also make sure that the server knows where the Perl executable is, which involves including the path to it in the systems <TT>PATH</TT> environment variable. Depending on the platform and the web server you use, other environments may need to be set.&lt;?xml version="1.0"?&gt;
<P><A HREF="#77034">Example 12-5</A> shows a simple CGI script that generates a minimal amount of XUL for display in the browser. Perl is useful for this task because you can set up several possible scripts and call selected ones, depending on what choices the user makes. You can even have different forks in the same script that displays different widgets or data. For example, imagine that your remote XUL application is an online travel planner. You would display maps, information, and links to resources based on the user's geographic location or preferences for destinations they entered earlier.</pre>
    <p>After PHP parses its content on the server, the rest of the
<P><I>Example 12-5: <A NAME="77034"></A></I>    document is sent to Mozilla on the client. Put this file
<I>A simple Perl-generated XUL file</I>    (<tt>remote_xul.php</tt>) somewhere in your document root on
<PRE> #!/usr/bin/perl    the server with PHP installed and launch it from Mozilla like
     this:</p>
 <pre>
 ./mozilla -chrome <a href=
 "http://my.domain/remote_xul.php">http://my.domain/remote_xul.php</a>
 </pre>
     <p>The window defined in <a href="#77032">Example 12-4</a> now
     appears, displaying the image. You can take advantage of this
     relatively straightforward technique to serve up more
     feature-rich user interfaces, inclusive of buttons, menus, and
     any other pieces of XUL that are needed.</p>
     <h4><a name="77075"></a> Perl</h4>
     <p>Although <!--INDEX Perl:remote applications --> 
     <!--INDEX remote applications:dynamic content:Perl --> 
     <!--INDEX scripting:remote applications:Perl --> PHP is rising
     in popularity, Perl is still a very popular web-scripting
     language. Perl is often used to drive back end web applications
     with CGI scripts. To process Perl scripts, no extra
     configuration is needed once you have the Perl interpreter set
     up to run in a web server environment. If, for example, you're
     already using Perl to serve up dynamic HTML pages, you're all
     set. Otherwise, you should grab a distribution of Perl (<i><a
     href="http://perl.com/">http://perl.com/</a></i>) and set up
     the paths to the binary files in your server scripts. This
     procedure is done by placing the path in the header, otherwise
     known as the <i>shebang line</i>. This script usually takes a
     form similar to <tt>#!/usr/local/bin/perl</tt> or
     <tt>#!/usr/bin/perl</tt>. You must also make sure that the
     server knows where the Perl executable is, which involves
     including the path to it in the systems <tt>PATH</tt>
     environment variable. Depending on the platform and the web
     server you use, other environments may need to be set.</p>
     <p><a href="#77034">Example 12-5</a> shows a simple CGI script
     that generates a minimal amount of XUL for display in the
     browser. Perl is useful for this task because you can set up
     several possible scripts and call selected ones, depending on
     what choices the user makes. You can even have different forks
     in the same script that displays different widgets or data. For
     example, imagine that your remote XUL application is an online
     travel planner. You would display maps, information, and links
     to resources based on the user's geographic location or
     preferences for destinations they entered earlier.</p>
     <p><i>Example 12-5: <a name="77034"></a></i> <i>A simple
     Perl-generated XUL file</i></p>
 <pre>
  #!/usr/bin/perl
  print "Content-type: application/vnd.mozilla.xul+xml";   print "Content-type: application/vnd.mozilla.xul+xml";
  print qq{   print qq{
  &lt;?xml version="1.0"?&gt;   &lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE window&amp;gt;   &lt;!DOCTYPE window&amp;gt;
  &lt;window   &lt;window
    id = "remote"     id = "remote"
   xmlns = "<A HREF="http://www.mozilla.org/keym">http://www.mozilla.org/keym</A>   xmlns = "<a href=
 "http://www.mozilla.org/keym">http://www.mozilla.org/keym</a>
    style = "min-width:282px; min-height:137px;"     style = "min-width:282px; min-height:137px;"
    orient = "vertical"&gt;     orient = "vertical"&gt;
   &lt;image src="<a href=
   &lt;image src="<A HREF="http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</A>"/&gt;"http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>"/&gt;
  &lt;/window&gt;   &lt;/window&gt;
 };</PRE> };
</pre>
<P>In <A HREF="#77034">Example 12-5</A>, the MIME type must be specified as part of the first line in the CGI script after the <I>shebang line</I>, and rest of the script is the XUL code used by Mozilla. Although this example does not display real dynamic content (such as the kind you get from CGI forms or other user-supplied data), it shows how you can interpolate dynamic data into a simple CGI application model.    <p>In <a href="#77034">Example 12-5</a>, the MIME type must be
<H4><A NAME="77076"></A> Python</H4>    specified as part of the first line in the CGI script after the
<P>Like <!--INDEX Python:remote applications -->  <!--INDEX remote applications:dynamic content:Python -->  <!--INDEX scripting:remote     <i>shebang line</i>, and rest of the script is the XUL code
applications:Python -->  Perl, Python provides modules that make it easy to create CGI applications that generate content dynamically. Python is already an important language in the Mozilla environment because of the <I>PyXPCOM</I> bindings discussed in <A HREF="ch08.html#77048">Chapter 8</A>.    used by Mozilla. Although this example does not display real
<P>If Python is a language that you like to code in, using it in a remote XUL environment would also make sense. Python combines the features of a lower-level language like object-oriented class and function design with the flexibility and simplicity of a scripting language. The latter feature (ease of use) is relative to a language like C++. <A HREF="#77036">Example 12-6</A> shows how to use Python to create a simple form consisting of three checkboxes.    dynamic content (such as the kind you get from CGI forms or
    other user-supplied data), it shows how you can interpolate
<P><I>Example 12-6: <A NAME="77036"></A></I>    dynamic data into a simple CGI application model.</p>
<I>A Python-generated dynamically updated form</I>    <h4><a name="77076"></a> Python</h4>
<PRE> #!/usr/local/bin/python    <p>Like <!--INDEX Python:remote applications --> 
     <!--INDEX remote applications:dynamic content:Python --> 
     <!--INDEX scripting:remote 
     applications:Python --> Perl, Python provides modules that make
     it easy to create CGI applications that generate content
     dynamically. Python is already an important language in the
     Mozilla environment because of the <i>PyXPCOM</i> bindings
     discussed in <a href="ch08.html#77048">Chapter 8</a>.</p>
     <p>If Python is a language that you like to code in, using it
     in a remote XUL environment would also make sense. Python
     combines the features of a lower-level language like
     object-oriented class and function design with the flexibility
     and simplicity of a scripting language. The latter feature
     (ease of use) is relative to a language like C++. <a href=
     "#77036">Example 12-6</a> shows how to use Python to create a
     simple form consisting of three checkboxes.</p>
     <p><i>Example 12-6: <a name="77036"></a></i> <i>A
     Python-generated dynamically updated form</i></p>
 <pre>
  #!/usr/local/bin/python
  import cgi   import cgi
  form = cgi.FieldStorage( )   form = cgi.FieldStorage( )
  print """Content-type: application/vnd.mozilla.xul+xml\n   print """Content-type: application/vnd.mozilla.xul+xml\n
Line 178  applications:Python -->  Perl, Python pr Line 547  applications:Python -->  Perl, Python pr
   &lt;!DOCTYPE window&gt;    &lt;!DOCTYPE window&gt;
   &lt;window    &lt;window
     id = "remote"      id = "remote"
    xmlns = "<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"    xmlns = "<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
     title = "listbox"      title = "listbox"
     style = "min-width:282px; min-height:137px;"      style = "min-width:282px; min-height:137px;"
     orient = "vertical"&gt;      orient = "vertical"&gt;
    &lt;box&gt;"""     &lt;box&gt;"""
 print '  &lt;checkbox label="%s" /&gt;' % form</TD>['op1'].value print '  &lt;checkbox label="%s" /&gt;' % form&lt;/td&gt;['op1'].value
 print '  &lt;checkbox label="%s" /&gt;' % form</TD>['op2'].value print '  &lt;checkbox label="%s" /&gt;' % form&lt;/td&gt;['op2'].value
   print ' &lt;checkbox label="%s" /&gt;' % form</TD>['op3'].value   print ' &lt;checkbox label="%s" /&gt;' % form&lt;/td&gt;['op3'].value
    print """&lt;/box&gt;     print """&lt;/box&gt;
   &lt;/window&gt;"""</PRE>   &lt;/window&gt;"""
</pre>
<P>In this example, the CGI module is loaded with the Python <TT>import</TT> statement, and the form object is initialized so that data input to the page in the form of URL <TT>?name=value</TT> pairs create the XUL content dynamically.    <p>In this example, the CGI module is loaded with the Python
<P><A HREF="#77036">Example 12-6</A> takes a URL, such as <I><A HREF="http://www.brownhen.com/cgi-bin/xulgen?opt1=peter?opt2=paul?opt3=mary">http://www.brownhen.com/cgi-bin/xulgen?opt1=peter?opt2=paul?opt3=mary</A></I>, and displays a checkbox for each value of the named form fields. The content type is printed before the XUL content to tell the web server what to pass when the script produces its output.    <tt>import</tt> statement, and the form object is initialized
<H3><A NAME="77077"></A> Generating Content from a Database</H3>    so that data input to the page in the form of URL
<P>One of the <!--INDEX remote applications:dynamic content:database generated -->  <!--INDEX databases:remote applications, dynamic content -->  important facets of dynamically generated content is interaction with a database to store and retrieve values for the user. For example, a public forum or subscription-based service could have a client that is written in XUL and requires authentication of users. Having such a client could require some form of database lookup. This section covers a simple example that uses data stored in a database to generate a XUL tree. We will use PHP to retrieve the data from the SQL-driven database and format it into XUL. Theoretically, this database could be any relational model, such as Oracle or MySQL.    <tt>?name=value</tt> pairs create the XUL content
<P><A HREF="#77038">Example 12-7</A> generates a simple tree listing with the columns "User" and "Project." The SQL script creates a table called "sample" and then inserts value pairs into the table. To use this type content generation, your database must be set up to handle table creation and dynamic updating via SQL calls.    dynamically.</p>
    <p><a href="#77036">Example 12-6</a> takes a URL, such as <i><a
<P><I>Example 12-7: <A NAME="77038"></A></I>    href=
<I>SQL script with User and Project data</I>    "http://www.brownhen.com/cgi-bin/xulgen?opt1=peter?opt2=paul?opt3=mary">
<PRE> # table to be inserted into database    http://www.brownhen.com/cgi-bin/xulgen?opt1=peter?opt2=paul?opt3=mary</a></i>,
     and displays a checkbox for each value of the named form
     fields. The content type is printed before the XUL content to
     tell the web server what to pass when the script produces its
     output.</p>
     <h3><a name="77077"></a> Generating Content from a
     Database</h3>
     <p>One of the 
     <!--INDEX remote applications:dynamic content:database generated -->
     <!--INDEX databases:remote applications, dynamic content -->
     important facets of dynamically generated content is
     interaction with a database to store and retrieve values for
     the user. For example, a public forum or subscription-based
     service could have a client that is written in XUL and requires
     authentication of users. Having such a client could require
     some form of database lookup. This section covers a simple
     example that uses data stored in a database to generate a XUL
     tree. We will use PHP to retrieve the data from the SQL-driven
     database and format it into XUL. Theoretically, this database
     could be any relational model, such as Oracle or MySQL.</p>
     <p><a href="#77038">Example 12-7</a> generates a simple tree
     listing with the columns "User" and "Project." The SQL script
     creates a table called "sample" and then inserts value pairs
     into the table. To use this type content generation, your
     database must be set up to handle table creation and dynamic
     updating via SQL calls.</p>
     <p><i>Example 12-7: <a name="77038"></a></i> <i>SQL script with
     User and Project data</i></p>
 <pre>
  # table to be inserted into database
  CREATE TABLE sample (   CREATE TABLE sample (
    User char(16) NOT NULL default '',     User char(16) NOT NULL default '',
    Project char(32) NOT NULL default ''     Project char(32) NOT NULL default ''
Line 205  applications:Python -->  Perl, Python pr Line 604  applications:Python -->  Perl, Python pr
  INSERT INTO sample VALUES ('Bob','moz_bob');   INSERT INTO sample VALUES ('Bob','moz_bob');
  INSERT INTO sample VALUES ('Joe','skinner');   INSERT INTO sample VALUES ('Joe','skinner');
  INSERT INTO sample VALUES ('Bret','bretzilla');   INSERT INTO sample VALUES ('Bret','bretzilla');
 INSERT INTO sample VALUES ('Sally','mozstream');</PRE> INSERT INTO sample VALUES ('Sally','mozstream');
</pre>
<P>The code in <A HREF="#77038">Example 12-7</A> creates a table with two fields, "User" and "Project." It then inserts four records into the newly created table in the database by using <TT>INSERT</TT> <TT>INTO</TT> calls. Now the script has tangible data to query.    <p>The code in <a href="#77038">Example 12-7</a> creates a
<P><A HREF="#77040">Example 12-8</A> shows the creation of a simple XUL tree with PHP and a MySQL database. The "User" and "Project" columns display the data in the table.    table with two fields, "User" and "Project." It then inserts
    four records into the newly created table in the database by
<P><I>Example 12-8: <A NAME="77040"></A></I>    using <tt>INSERT</tt> <tt>INTO</tt> calls. Now the script has
<I>XUL generated from database</I>    tangible data to query.</p>
<PRE> &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;    <p><a href="#77040">Example 12-8</a> shows the creation of a
     simple XUL tree with PHP and a MySQL database. The "User" and
     "Project" columns display the data in the table.</p>
     <p><i>Example 12-8: <a name="77040"></a></i> <i>XUL generated
     from database</i></p>
 <pre>
  &lt;?php header( "Content-type: application/vnd.mozilla.xul+xml" ); ?&gt;
  &lt;?xml version="1.0"?&gt;   &lt;?xml version="1.0"?&gt;
  &lt;?php   &lt;?php
    // connect code     // connect code
Line 232  applications:Python -->  Perl, Python pr Line 637  applications:Python -->  Perl, Python pr
  &lt;!DOCTYPE window&gt;   &lt;!DOCTYPE window&gt;
  &lt;window   &lt;window
    id = "remote"     id = "remote"
   xmlns = "<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"   xmlns = "<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"
    title = "A Remote Image" style = "min-width:282px; min-height:137px;"&gt;     title = "A Remote Image" style = "min-width:282px; min-height:137px;"&gt;
   &lt;image src="<A HREF="http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</A>" /&gt;   &lt;image src="<a href=
 "http://books.mozdev.org/screenshots/logo5.gif">http://books.mozdev.org/screenshots/logo5.gif</a>" /&gt;
    &lt;hbox&gt;     &lt;hbox&gt;
      &lt;tree&gt;       &lt;tree&gt;
        &lt;treecols&gt;         &lt;treecols&gt;
          &lt;treecol id="userCol" label="User" /&gt;           &lt;treecol id="userCol" label="User" /&gt;
          &lt;treecol id="projectCol" label="Project" flex="1"/&gt;           &lt;treecol id="projectCol" label="Project" flex="1"/&gt;
        &lt;/treecols&gt;         &lt;/treecols&gt;
   
        &lt;treechildren&gt;         &lt;treechildren&gt;
          &lt;?php           &lt;?php
            // generate data from db             // generate data from db
Line 260  applications:Python -->  Perl, Python pr Line 666  applications:Python -->  Perl, Python pr
      &lt;/tree&gt;       &lt;/tree&gt;
      &lt;spacer flex="1" /&gt;       &lt;spacer flex="1" /&gt;
   &lt;/hbox&gt;    &lt;/hbox&gt;
 &lt;/window&gt;</PRE> &lt;/window&gt;
</pre>
<P>The PHP header method is placed at the top of the file to properly format the output as XUL. The PHP MySQL APIs prepare the code for connection to a MySQL database. Finally, a loop is used to print out the stored data's <TT>treerows</TT> and <TT>treecells</TT>.    <p>The PHP header method is placed at the top of the file to
<P>This kind of operation provides insight into the possibilities of using remote XUL when you have information stored in a database. Many web     properly format the output as XUL. The PHP MySQL APIs prepare
applications already do this via HTML forms and other mechanisms, but Mozilla's XPFE toolkit provides a richer widget set than HTML to display and retrieve information (see the section <A HREF="ch03.html#77114">"Form Controls" in Chapter 3</A>).    the code for connection to a MySQL database. Finally, a loop is
<P>Some XUL widgets are created specifically to display complex tabular data such as <TT>&lt;tree&gt;</TT>, and some widgets provide user selection such as <TT>&lt;checkbox&gt;</TT>, <TT>&lt;radio&gt;</TT>, and <TT>&lt;textbox&gt;</TT>, plus the CSS used for controlling presentation. All of these widgets can be generated on the fly from the database and used to accept user-inputted information.    used to print out the stored data's <tt>treerows</tt> and
<H3><A NAME="77078"></A> Localizing Remote Applications</H3>    <tt>treecells</tt>.</p>
<P>Unfortunately,  <!--INDEX remote applications:localizing -->  <!--INDEX localizing remote applications --> localizing remote applications is a not as straightforward since there is no http: protocol equivalent for chrome:-included locales. You could use <I>HTTP/1.1</I> content negotiation to serve the users-preferred language, but Mozilla 1.0 does not read DTD files over the wire. To overcome this problem, use server-side page processing. For example, this code includes the DTD by using PHP:    <p>This kind of operation provides insight into the
<PRE>&lt;!DOCTYPE window [    possibilities of using remote XUL when you have information
     stored in a database. Many web applications already do this via
     HTML forms and other mechanisms, but Mozilla's XPFE toolkit
     provides a richer widget set than HTML to display and retrieve
     information (see the section <a href="ch03.html#77114">"Form
     Controls" in Chapter 3</a>).</p>
     <p>Some XUL widgets are created specifically to display complex
     tabular data such as <tt>&lt;tree&gt;</tt>, and some widgets
     provide user selection such as <tt>&lt;checkbox&gt;</tt>,
     <tt>&lt;radio&gt;</tt>, and <tt>&lt;textbox&gt;</tt>, plus the
     CSS used for controlling presentation. All of these widgets can
     be generated on the fly from the database and used to accept
     user-inputted information.</p>
     <h3><a name="77078"></a> Localizing Remote Applications</h3>
     <p>Unfortunately, <!--INDEX remote applications:localizing --> 
     <!--INDEX localizing remote applications --> localizing remote
     applications is a not as straightforward since there is no
     http: protocol equivalent for chrome:-included locales. You
     could use <i>HTTP/1.1</i> content negotiation to serve the
     users-preferred language, but Mozilla 1.0 does not read DTD
     files over the wire. To overcome this problem, use server-side
     page processing. For example, this code includes the DTD by
     using PHP:</p>
 <pre>
 &lt;!DOCTYPE window [
 &lt;?php require(PROJECT_PATH."/online/locale/xfly.dtd"); ?&gt;  &lt;?php require(PROJECT_PATH."/online/locale/xfly.dtd"); ?&gt;
]&gt;</PRE>]&gt;
<P>Therefore, the served page looks like this:</pre>
<PRE>&lt;!DOCTYPE window [    <p>Therefore, the served page looks like this:</p>
 <pre>
 &lt;!DOCTYPE window [
 &lt;!ENTITY fileMenu.label        "File"&gt;  &lt;!ENTITY fileMenu.label        "File"&gt;
 &lt;!ENTITY fileMenu.accesskey    "f"&gt;  &lt;!ENTITY fileMenu.accesskey    "f"&gt;
 ...  ...
]&gt;</PRE>]&gt;
<P>The only caveat for this approach is that you need a method to filter the entities, depending on which language is loaded. Obtaining a method could be done by reading in the locale and outputting the entities or by calling a separate script. This overhead is not necessarily high, as multiple files exist for multiple languages in a client distribution. A remote application would require the same process, but in a different format.</pre>
<H2><A NAME="77079"></A> Certificate Authorities and Digital Signatures</H2>    <p>The only caveat for this approach is that you need a method
<P>Instead  <!--INDEX security:remote applications:Certificate Authorities and digital signatures -->  <!--INDEX remote applications:Certificate Authorities -->  <!--INDEX remote applications:digital signatures -->  <!--INDEX Certificate Authorities:remote applications -->  <!--INDEX digital signatures, remote applications --> of changing the Universal XPConnect privileges (see <A HREF="#77070">"Setting Up XPFE for Remote Applications</A>" earlier in this chapter), you could create signed remote applications that can be granted access to users' computers. A signed application means that the application has a digital signature, which verifies that a file or group of files was created by the person or organization from which you download and that they are trustworthy. In essence, if you trust the person or organization signing the files, then you trust the files themselves.    to filter the entities, depending on which language is loaded.
<P>Digital signatures originate from a certificate authority (CA), an organization that claims responsibility for any digital signature it creates. CAs act as gatekeepers by allowing only people who the organization trusts to create digital signatures. Large CAs like  <!--INDEX Certificate Authorities: Verisign;Verisign --> Verisign, whose certificates come preinstalled in many web browsers, enforce validity through large fees. For example, if you can afford $600, then you are an organization with whom the CA would be glad to associate. That $600 then also buys your application respectability with user's web browsers. You can see the CAs that come with the Mozilla browser by going to Privacy &amp; Security &gt; Certificates in your preferences panel and then by selecting the Manage Certificates option. Of the different types of CAs-there's a type for SSL connections, for example, and another one for S/MIME-the  <!--INDEX Netscape:Object Signing certificate --> Netscape Object Signing certificate is what matters for signed applications.    Obtaining a method could be done by reading in the locale and
<P>Fortunately, to get your remote applications signed by a CA, you don't have to pay for a Verisign Netscape Object Signing CA because other options are available. You can use the MozDev CA, for example, and even create your own. The next section tells you how use Mozilla tools to become your own certificate authority so you can sign your own applications and those of other Mozilla developers. The <A HREF="#77088">"Creating Signed Remote Applications</A>" section later in this chapter uses the MozDev CA to discuss both avenues.    outputting the entities or by calling a separate script. This
<H3><A NAME="77080"></A> Mozilla Network Security Services (NSS)</H3>    overhead is not necessarily high, as multiple files exist for
<P>The Mozilla  <!--INDEX NSS (Network Security Service) -->  <!--INDEX Certificate Authorities:NSS --> Network Security Services tools, which are described in detail at <!--INDEX web sites:NSS -->  <I><A HREF="http://www.mozilla.org/projects/security/pki/nss/">http://www.mozilla.org/projects/security/pki/nss/</A></I>, allow you to become your own Netscape Object Signing CA. By becoming your own Netscape Signing CA, you can distribute signing certificates to Mozilla application developers. You can obtain the tools via a simplified distribution of NSS for Windows and Linux at <I><A HREF="http://certs.mozdev.org">http://certs.mozdev.org</A></I>. These tools allow you to become a CA and to package signed remote Mozilla applications. Finally, the commands for CertUtil work the same way on Windows, Linux, and any other OS on which you run CertUtil.    multiple languages in a client distribution. A remote
<H3><A NAME="77081"></A> CA Certificates, Signing Certificates, and the Certificate Chain</H3>    application would require the same process, but in a different
<P>A certificate  <!--INDEX Certificate Authorities:distribution certificates:requirements --> represents an organization in a official digital form. It provides fields for the organization's name, contact information, date of issue, and an expiration date. There are also two keys: a private and a public key.    format.</p>
<P>To become a CA, you need to create two certificates for yourself: a "root certificate" and a "distribution certificate." Once you set up these certificates, you can issue signing certificates, which create digital signatures. <A HREF="#77008">Figure 12-4</A> shows the chain of relationships between certificates.    <h2><a name="77079"></a> Certificate Authorities and Digital
<P><CENTER><IMG SRC="foo.gif"></CENTER>    Signatures</h2>
<P><I>Figure 12-4: <A NAME="77008"></A></I>    <p>Instead 
<I>A  <!--INDEX Netscape:Object Signing certificate --> Netscape Object Signing certificate chain</I>    <!--INDEX security:remote applications:Certificate Authorities and digital signatures -->
    <!--INDEX remote applications:Certificate Authorities --> 
<P>The distribution certificate is based on the root certificate's public key. You can then create signing certificates from the distribution certificate, using its public key that it handles automatically by NSS. Finally, the digital signatures derived from the signing certificate can sign applications using NSS.    <!--INDEX remote applications:digital signatures --> 
<H3><A NAME="77082"></A> Setting Up a Certificate Authority</H3>    <!--INDEX Certificate Authorities:remote applications --> 
<P>Using the CertUtil tool <!--INDEX Certificate Authorities:setting up -->  <!--INDEX security:Certificate Authorities:setting up -->  that comes with NSS, you need to create a root certificate and a distribution certificate for yourself to become a CA. The CertUtil tool is located in the NSS installation's <I>bin</I> directory and can be run from anywhere in a console window. In the next few sections, we walk through the steps necessary to accomplish this process.    <!--INDEX digital signatures, remote applications --> of
<H4><A NAME="77083"></A> Creating a certificate database</H4>    changing the Universal XPConnect privileges (see <a href=
<P>Mozilla <!--INDEX Certificate Authorities:certificate database -->  <!--INDEX certificate database, creating -->  <!--INDEX databases:certificate, creating -->  <!--INDEX security:Certificate Authorities:certificate database -->  comes with a prefilled certificate database that contains information about certificates from Verisign and other CAs (found in the file <I>cert7.db</I> in the user profile directory), which you can modify. However, starting with a blank database is better because it avoids the possibility of corruption.    "#77070">"Setting Up XPFE for Remote Applications</a>" earlier
<P>At the prompt, create a new database by using the <TT>-N</TT> and <TT>-d</TT> options for CertUtil:    in this chapter), you could create signed remote applications
<PRE>C:\NSS\bin&gt;certutil -N -d .</PRE>    that can be granted access to users' computers. A signed
<P>Enter a password for the database. You need to reenter this password every time you issue or change certificates. CertUtil creates the files <I>cert7.db</I>, <I>key3.db</I>, and <I>secmod.db</I> in the same directory as CertUtil. You can delete the <I>key3.db</I> and <I>secmod.db</I> files because they do not pertain to certificate creation or modification.    application means that the application has a digital signature,
<H4><A NAME="77084"></A> Creating the root CA certificate</H4>    which verifies that a file or group of files was created by the
<P>The root <!--INDEX Certificate Authorities:root certificate, creating -->  <!--INDEX security:Certificate Authorities:root certificate, creating -->  <!--INDEX root certificates, creating -->  <!--INDEX certificates:root, creating -->  certificate is the foundation for the certificate chain and should not be shared with anyone outside your organization. You may want to consider storing the database or exported certificate on a floppy disk for safe keeping. If it gets lost or stolen, you need to make a new one and all your users will need to use new certificates and resign their applications.    person or organization from which you download and that they
<P>Once you create <I>cert7.db</I>, CertUtil can process the Root CA Certificate into it, using the following and substituting the name of your CA for mozdev.org:    are trustworthy. In essence, if you trust the person or
<PRE>C:\NSS\bin&gt;certutil -S -s "CN=mozdev.org, O=mozdev.org" -n "mozdev.org"    organization signing the files, then you trust the files
-t ",,C" -x -d . -1 -2 -5</PRE>    themselves.</p>
<P>Enter a password at the prompt and proceed by making the menu choices shown in <A HREF="#77042">Example 12-9</A>.    <p>Digital signatures originate from a certificate authority
    (CA), an organization that claims responsibility for any
<P><I>Example 12-9: <A NAME="77042"></A></I>    digital signature it creates. CAs act as gatekeepers by
<I>Creating a root certificate</I>    allowing only people who the organization trusts to create
<PRE> Generating key.  This may take a few moments...    digital signatures. Large CAs like 
     <!--INDEX Certificate Authorities: Verisign;Verisign -->
     Verisign, whose certificates come preinstalled in many web
     browsers, enforce validity through large fees. For example, if
     you can afford $600, then you are an organization with whom the
     CA would be glad to associate. That $600 then also buys your
     application respectability with user's web browsers. You can
     see the CAs that come with the Mozilla browser by going to
     Privacy &amp; Security &gt; Certificates in your preferences
     panel and then by selecting the Manage Certificates option. Of
     the different types of CAs-there's a type for SSL connections,
     for example, and another one for S/MIME-the 
     <!--INDEX Netscape:Object Signing certificate --> Netscape
     Object Signing certificate is what matters for signed
     applications.</p>
     <p>Fortunately, to get your remote applications signed by a CA,
     you don't have to pay for a Verisign Netscape Object Signing CA
     because other options are available. You can use the MozDev CA,
     for example, and even create your own. The next section tells
     you how use Mozilla tools to become your own certificate
     authority so you can sign your own applications and those of
     other Mozilla developers. The <a href="#77088">"Creating Signed
     Remote Applications</a>" section later in this chapter uses the
     MozDev CA to discuss both avenues.</p>
     <h3><a name="77080"></a> Mozilla Network Security Services
     (NSS)</h3>
     <p>The Mozilla <!--INDEX NSS (Network Security Service) --> 
     <!--INDEX Certificate Authorities:NSS --> Network Security
     Services tools, which are described in detail at 
     <!--INDEX web sites:NSS --> <i><a href=
     "http://www.mozilla.org/projects/security/pki/nss/">http://www.mozilla.org/projects/security/pki/nss/</a></i>,
     allow you to become your own Netscape Object Signing CA. By
     becoming your own Netscape Signing CA, you can distribute
     signing certificates to Mozilla application developers. You can
     obtain the tools via a simplified distribution of NSS for
     Windows and Linux at <i><a href=
     "http://certs.mozdev.org">http://certs.mozdev.org</a></i>.
     These tools allow you to become a CA and to package signed
     remote Mozilla applications. Finally, the commands for CertUtil
     work the same way on Windows, Linux, and any other OS on which
     you run CertUtil.</p>
     <h3><a name="77081"></a> CA Certificates, Signing Certificates,
     and the Certificate Chain</h3>
     <p>A certificate 
     <!--INDEX Certificate Authorities:distribution certificates:requirements -->
     represents an organization in a official digital form. It
     provides fields for the organization's name, contact
     information, date of issue, and an expiration date. There are
     also two keys: a private and a public key.</p>
     <p>To become a CA, you need to create two certificates for
     yourself: a "root certificate" and a "distribution
     certificate." Once you set up these certificates, you can issue
     signing certificates, which create digital signatures. <a href=
     "#77008">Figure 12-4</a> shows the chain of relationships
     between certificates.</p>
     <div class="c25">
       <img src="foo.gif">
     </div>
     <p><i>Figure 12-4: <a name="77008"></a></i> <i>A 
     <!--INDEX Netscape:Object Signing certificate --> Netscape
     Object Signing certificate chain</i></p>
     <p>The distribution certificate is based on the root
     certificate's public key. You can then create signing
     certificates from the distribution certificate, using its
     public key that it handles automatically by NSS. Finally, the
     digital signatures derived from the signing certificate can
     sign applications using NSS.</p>
     <h3><a name="77082"></a> Setting Up a Certificate
     Authority</h3>
     <p>Using the CertUtil tool 
     <!--INDEX Certificate Authorities:setting up --> 
     <!--INDEX security:Certificate Authorities:setting up --> that
     comes with NSS, you need to create a root certificate and a
     distribution certificate for yourself to become a CA. The
     CertUtil tool is located in the NSS installation's <i>bin</i>
     directory and can be run from anywhere in a console window. In
     the next few sections, we walk through the steps necessary to
     accomplish this process.</p>
     <h4><a name="77083"></a> Creating a certificate database</h4>
     <p>Mozilla 
     <!--INDEX Certificate Authorities:certificate database --> 
     <!--INDEX certificate database, creating --> 
     <!--INDEX databases:certificate, creating --> 
     <!--INDEX security:Certificate Authorities:certificate database -->
     comes with a prefilled certificate database that contains
     information about certificates from Verisign and other CAs
     (found in the file <i>cert7.db</i> in the user profile
     directory), which you can modify. However, starting with a
     blank database is better because it avoids the possibility of
     corruption.</p>
     <p>At the prompt, create a new database by using the
     <tt>-N</tt> and <tt>-d</tt> options for CertUtil:</p>
 <pre>
 C:\NSS\bin&gt;certutil -N -d .
 </pre>
     <p>Enter a password for the database. You need to reenter this
     password every time you issue or change certificates. CertUtil
     creates the files <i>cert7.db</i>, <i>key3.db</i>, and
     <i>secmod.db</i> in the same directory as CertUtil. You can
     delete the <i>key3.db</i> and <i>secmod.db</i> files because
     they do not pertain to certificate creation or
     modification.</p>
     <h4><a name="77084"></a> Creating the root CA certificate</h4>
     <p>The root 
     <!--INDEX Certificate Authorities:root certificate, creating -->
     <!--INDEX security:Certificate Authorities:root certificate, creating -->
     <!--INDEX root certificates, creating --> 
     <!--INDEX certificates:root, creating --> certificate is the
     foundation for the certificate chain and should not be shared
     with anyone outside your organization. You may want to consider
     storing the database or exported certificate on a floppy disk
     for safe keeping. If it gets lost or stolen, you need to make a
     new one and all your users will need to use new certificates
     and resign their applications.</p>
     <p>Once you create <i>cert7.db</i>, CertUtil can process the
     Root CA Certificate into it, using the following and
     substituting the name of your CA for mozdev.org:</p>
 <pre>
 C:\NSS\bin&gt;certutil -S -s "CN=mozdev.org, O=mozdev.org" -n "mozdev.org"
 -t ",,C" -x -d . -1 -2 -5
 </pre>
     <p>Enter a password at the prompt and proceed by making the
     menu choices shown in <a href="#77042">Example 12-9</a>.</p>
     <p><i>Example 12-9: <a name="77042"></a></i> <i>Creating a root
     certificate</i></p>
 <pre>
  Generating key.  This may take a few moments...
                            0 - Digital Signature                             0 - Digital Signature
                            1 - Non-repudiation                             1 - Non-repudiation
                            2 - Key encipherment                             2 - Key encipherment
Line 327  applications already do this via HTML fo Line 885  applications already do this via HTML fo
                            6 - CRL signing key                             6 - CRL signing key
                            Other to finish                             Other to finish
  9   9
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
  n   n
 Is this a CA certificate </TD>[y/n]? Is this a CA certificate &lt;/td&gt;[y/n]?
  y   y
 Enter the path length constraint, enter to skip </TD>[&lt;0 for unlimited path]: Enter the path length constraint, enter to skip &lt;/td&gt;[&lt;0 for unlimited path]:
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
  n   n
                            0 - SSL Client                             0 - SSL Client
                            1 - SSL Server                             1 - SSL Server
Line 354  applications already do this via HTML fo Line 912  applications already do this via HTML fo
                            7 - Object Signing CA                             7 - Object Signing CA
                            Other to finish                             Other to finish
  9   9
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
 n</PRE> n
</pre>
<P>The mozdev.org Root CA Certificate resides in <I>cert7.db</I>. You can export it to a file for safekeeping as follows:    <p>The mozdev.org Root CA Certificate resides in
<PRE>C:\NSS\bin&gt;certutil -L -d . -n "mozdev.org" -a -o mozdev.cacert</PRE>    <i>cert7.db</i>. You can export it to a file for safekeeping as
<P>This code will yield an ASCII representation of the certificate.    follows:</p>
<H4><A NAME="77085"></A> Creating a distribution CA certificate</H4><pre>
<P>Next you must <!--INDEX Certificate Authorities:distribution certificates:creating -->  <!--INDEX security:Certificate Authorities:distribution certificates, creating -->  <!--INDEX distribution certificates:creating -->  <!--INDEX certificates:distribution:creating -->  create a distribution certificate. This certificate will be installed into the user's Mozilla web browser so Mozilla can verify related signed remote Mozilla applications. Start the certificate by typing the following code at the prompt and substituting the name of your CA for "mozdev.org":C:\NSS\bin&gt;certutil -L -d . -n "mozdev.org" -a -o mozdev.cacert
<PRE>C:\NSS\bin&gt;certutil -S -n "certs.mozdev.org"</pre>
     <p>This code will yield an ASCII representation of the
     certificate.</p>
     <h4><a name="77085"></a> Creating a distribution CA
     certificate</h4>
     <p>Next you must 
     <!--INDEX Certificate Authorities:distribution certificates:creating -->
     <!--INDEX security:Certificate Authorities:distribution certificates, creating -->
     <!--INDEX distribution certificates:creating --> 
     <!--INDEX certificates:distribution:creating --> create a
     distribution certificate. This certificate will be installed
     into the user's Mozilla web browser so Mozilla can verify
     related signed remote Mozilla applications. Start the
     certificate by typing the following code at the prompt and
     substituting the name of your CA for "mozdev.org":</p>
 <pre>
 C:\NSS\bin&gt;certutil -S -n "certs.mozdev.org"
 -s "CN=certs.mozdev.org, O=certs.mozdev.org" -c "mozdev.org" -v 96  -s "CN=certs.mozdev.org, O=certs.mozdev.org" -c "mozdev.org" -v 96
-t ",,C" -d . -1 -2 -5</PRE>-t ",,C" -d . -1 -2 -5
<P>Enter a password at the prompt and make the menu choices shown in <A HREF="#77044">Example 12-10</A>.</pre>
    <p>Enter a password at the prompt and make the menu choices
Example 12-10<A NAME="77044"></A>    shown in <a href="#77044">Example 12-10</a>. Example 12-10<a
<I>Creating a distribution certificate</I>    name="77044"></a> <i>Creating a distribution
<PRE> Generating key.  This may take a few moments...    certificate</i></p>
 <pre>
  Generating key.  This may take a few moments...
                            0 - Digital Signature                             0 - Digital Signature
                            1 - Non-repudiation                             1 - Non-repudiation
                            2 - Key encipherment                             2 - Key encipherment
Line 388  Example 12-10<A NAME="77044"></A> Line 964  Example 12-10<A NAME="77044"></A>
                            6 - CRL signning key                             6 - CRL signning key
                            Other to finish                             Other to finish
  9   9
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
  n   n
 Is this a CA certificate </TD>[y/n]? Is this a CA certificate &lt;/td&gt;[y/n]?
  y   y
 Enter the path length constraint, enter to skip </TD>[&lt;0 for unlimited path]: Enter the path length constraint, enter to skip &lt;/td&gt;[&lt;0 for unlimited path]:
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
  n   n
                            0 - SSL Client                             0 - SSL Client
                            1 - SSL Server                             1 - SSL Server
Line 415  Example 12-10<A NAME="77044"></A> Line 991  Example 12-10<A NAME="77044"></A>
                            7 - Object Signing CA                             7 - Object Signing CA
                            Other to finish                             Other to finish
  9   9
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
 n</PRE> n
</pre>
<P>Note the differences between this process and that used to create the root certificate. The distribution certificate is not self-signed, so to create it, you must reference the mozdev.org Root CA Certificate in the initial command. Also, the <TT>-v 96</TT> option indicates that the certificate is good for 96 months.    <p>Note the differences between this process and that used to
<P>Once you've created the distribution certificate, export it using the following command (for which "certs.mozdev.org" is the name of your CA):    create the root certificate. The distribution certificate is
<PRE>C:\NSS\bin&gt;certutil -L -d . -n "certs.mozdev.org" -a -o certs_mozdev.cacert</PRE>    not self-signed, so to create it, you must reference the
<P>Keep track of the resulting file because you will need to upload it to your web site later so browsers can install it.    mozdev.org Root CA Certificate in the initial command. Also,
<H3><A NAME="77086"></A> Issuing Signing Certificates</H3>    the <tt>-v 96</tt> option indicates that the certificate is
<P>Once you  <!--INDEX signing certificates:issuing -->  <!--INDEX certificates:signing:issuing -->  <!--INDEX Certificate Authorities:signing certificates, issuing -->  <!--INDEX security:Certificate Authorities:issuing signing certificates --> create the two root and distribution certificates for your organization, you are a certificate authority, much like VeriSign. You decide who gets the privilege of a signing certificate and issue them accordingly. Signing certificates should not be reused for different people. When you want to give out a signing certificate, you should create a new one by using CertUtil and make a copy of the exported certificate for yourself to keep and catalog.    good for 96 months.</p>
<P>To create a signing certificate, use the following command and substitute the name of your CA for "mozdev.org":    <p>Once you've created the distribution certificate, export it
<PRE>C:\NSS\bin&gt;certutil -S -n "certs.mozdev.org/signing"    using the following command (for which "certs.mozdev.org" is
-s "CN=certs.mozdev.org/signing, O=certs.mozdev.org" -c "certs.mozdev.org" -v 96 -t ",,C" -d . -1 -2 -5</PRE>    the name of your CA):</p>
<P>Enter a password at the prompt and make the menu choices shown in <A HREF="#77046">Example 12-11</A>.<pre>
C:\NSS\bin&gt;certutil -L -d . -n "certs.mozdev.org" -a -o certs_mozdev.cacert
Example 12-11<A NAME="77046"></A></pre>
<I>Create a signing certificate</I>    <p>Keep track of the resulting file because you will need to
<PRE> Generating key.  This may take a few moments...    upload it to your web site later so browsers can install
     it.</p>
     <h3><a name="77086"></a> Issuing Signing Certificates</h3>
     <p>Once you <!--INDEX signing certificates:issuing --> 
     <!--INDEX certificates:signing:issuing --> 
     <!--INDEX Certificate Authorities:signing certificates, issuing -->
     <!--INDEX security:Certificate Authorities:issuing signing certificates -->
     create the two root and distribution certificates for your
     organization, you are a certificate authority, much like
     VeriSign. You decide who gets the privilege of a signing
     certificate and issue them accordingly. Signing certificates
     should not be reused for different people. When you want to
     give out a signing certificate, you should create a new one by
     using CertUtil and make a copy of the exported certificate for
     yourself to keep and catalog.</p>
     <p>To create a signing certificate, use the following command
     and substitute the name of your CA for "mozdev.org":</p>
 <pre>
 C:\NSS\bin&gt;certutil -S -n "certs.mozdev.org/signing"
 -s "CN=certs.mozdev.org/signing, O=certs.mozdev.org" -c "certs.mozdev.org" -v 96 -t ",,C" -d . -1 -2 -5
 </pre>
     <p>Enter a password at the prompt and make the menu choices
     shown in <a href="#77046">Example 12-11</a>. Example 12-11<a
     name="77046"></a> <i>Create a signing certificate</i></p>
 <pre>
  Generating key.  This may take a few moments...
                            0 - Digital Signature                             0 - Digital Signature
                            1 - Non-repudiation                             1 - Non-repudiation
                            2 - Key encipherment                             2 - Key encipherment
Line 459  Example 12-11<A NAME="77046"></A> Line 1060  Example 12-11<A NAME="77046"></A>
                            6 - CRL signning key                             6 - CRL signning key
                            Other to finish                             Other to finish
  9   9
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
  n   n
 Is this a CA certificate </TD>[y/n]? Is this a CA certificate &lt;/td&gt;[y/n]?
  n   n
 Enter the path length constraint, enter to skip </TD>[&lt;0 for unlimited path]: Enter the path length constraint, enter to skip &lt;/td&gt;[&lt;0 for unlimited path]:
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
  n   n
                            0 - SSL Client                             0 - SSL Client
                            1 - SSL Server                             1 - SSL Server
Line 486  Example 12-11<A NAME="77046"></A> Line 1087  Example 12-11<A NAME="77046"></A>
                            7 - Object Signing CA                             7 - Object Signing CA
                            Other to finish                             Other to finish
  9   9
 Is this a critical extension </TD>[y/n]? Is this a critical extension &lt;/td&gt;[y/n]?
 n</PRE> n
</pre>
<P>In <A HREF="#77046">Example 12-11</A>, the <I>certs.mozdev.org/signing</I> certificate references the <I>certs.mozdev.org</I> CA certificate. The Digital Signature option is also set so a signed remote Mozilla application can be compiled from the certificate.    <p>In <a href="#77046">Example 12-11</a>, the
<P>Export the signing certificate with the following command:    <i>certs.mozdev.org/signing</i> certificate references the
<PRE>C:\NSS\bin&gt;certutil -L -d . -n "certs.mozdev.org/signing" -a    <i>certs.mozdev.org</i> CA certificate. The Digital Signature
-o eric.cacert</PRE>    option is also set so a signed remote Mozilla application can
<P>You can send the resulting file to the person who requested the Signing Certificate. That person can then use it to create signed remote applications, as described later in this chapter in the <A HREF="#77092">"Signing the application</A>" section.    be compiled from the certificate.</p>
<H3><A NAME="77087"></A> Distributing Distribution Certificates</H3>    <p>Export the signing certificate with the following
<P>The distribution  <!--INDEX distribution certificates:distributing -->  <!--INDEX certificates:distribution:distributing -->  <!--INDEX Certificate Authorities:distribution certificates:distributing -->  <!--INDEX security:Certificate Authorities:distributing distribution certificates --> certificate (<I>certs_mozdev.cacert</I> in <A HREF="#77044">Example 12-10</A>) must be installed into a user's Mozilla web browser before she can use signed applications that come from certificates you've distributed. It's best to state clearly on the web site hosting these signed remote Mozilla applications that the distribution certificate is needed. If you distribute many different signing certificates, and they are used by all signed remote Mozilla applications, then all applications can use that same distribution certificate (as they do with Verisign's and other certificate authorities).    command:</p>
<P>To allow users to install the distribution certificate, create a link to the certificate file on your web page:<pre>
<PRE>&lt;a href="certs_mozdev.cacert"&gt;Install the MozDev CA Certificate&lt;/a&gt;</PRE>C:\NSS\bin&gt;certutil -L -d . -n "certs.mozdev.org/signing" -a
<P>Also make sure that your web server uses the MIME type <TT>application/x-x509-ca-cert</TT> for <I>.cacert</I> files.-o eric.cacert
<P>If the web server is set up correctly, the user will get a dialog box that looks like <A HREF="#77010">Figure 12-5</A>. Tell the user to select the options for "web sites" and "software developers."</pre>
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <p>You can send the resulting file to the person who requested
<P><I>Figure 12-5: <A NAME="77010"></A></I>    the Signing Certificate. That person can then use it to create
<I>Downloading a certificate window</I>    signed remote applications, as described later in this chapter
    in the <a href="#77092">"Signing the application</a>"
<P>After the certificate is installed, it will appear in the Certificate Manager, as shown in <A HREF="#77012">Figure 12-6</A>. The Certificate Manager can be accessed via the global Mozilla preferences (Edit &gt; Preferences &gt; Privacy &amp; Security &gt; Certificates). Mozilla is then ready to run signed remote Mozilla applications bearing signatures from your certificate authority.    section.</p>
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <h3><a name="77087"></a> Distributing Distribution
<P><I>Figure 12-6: <A NAME="77012"></A></I>    Certificates</h3>
<I>Certificate manager with a certs.mozdev.org CA certificate</I>    <p>The distribution 
    <!--INDEX distribution certificates:distributing --> 
<H2><A NAME="77088"></A> Creating Signed Remote Applications</H2>    <!--INDEX certificates:distribution:distributing --> 
<P>Security in Mozilla's  <!--INDEX remote applications:signed -->  <!--INDEX security:remote applications:signed --> web browser is designed to meet today's advanced scripting needs in a secure manner. Mozilla is a much more secure browser than past Netscape 4.x and Internet Explorer releases because it has a better sense of what remote scripts can and cannot do.    <!--INDEX Certificate Authorities:distribution certificates:distributing -->
<P>Because of Mozilla's approach toward potentially insecure applications, if you decide to serve up your own application remotely, remember that you will not have automatic access to the chrome in the way you do when you have a registered, locally installed Mozilla application. Unless you sign your application or have the user turn on a special preference (see <A HREF="#77070">"Setting Up XPFE for Remote Applications</A>"), services like XPConnect will not be available.    <!--INDEX security:Certificate Authorities:distributing distribution certificates -->
<P>In Mozilla, you can bundle any number of files into a JAR archive (which, you'll recall from <A HREF="ch06.html#77063">Chapter 6</A>, is just a     certificate (<i>certs_mozdev.cacert</i> in <a href=
zip file with a JAR suffix) and designate the archive as an object that can be signed. This designation makes it very easy to produce an entire signed and secure remote Mozilla application because it stores your application in a single file type that Mozilla already treats as a separate package.    "#77044">Example 12-10</a>) must be installed into a user's
<P>This section provides an overview of the signed script technology and shows you how to create signed applications that live on the server but take full advantage of the user's local chrome, including Mozilla components.    Mozilla web browser before she can use signed applications that
<H3><A NAME="77089"></A> certs.mozdev.org CA Certificate</H3>    come from certificates you've distributed. It's best to state
<P>Before users <!--INDEX installation:certificates -->  <!--INDEX certificates:installing -->  <!--INDEX remote applications:certificates:installing -->  <!--INDEX security:remote applications:installing certificates -->  can load signed applications, a CA certificate must be installed into their installed copy of Mozilla. Once this certificate is installed in a browser, all MozDev-signed applications can work with this certificate. This setup makes things easier on users who access many of these signed applications because they do not have to install a new certificate for each one. Also, if the user wants to use applications from other certificate authorities, they need to install a distribution certificate from that certificate authority.    clearly on the web site hosting these signed remote Mozilla
<P>Installing the certificate is easy. Just provide the users with a regular link on a web page-for example, <I><A HREF="http://certs.mozdev.org/certs_mozdev.cacert">http://certs.mozdev.org/certs_mozdev.cacert</A></I>. When loading this page, a dialog box pops up and asks the user to install the certificate. See the <A HREF="#77093">"Distributing the application</A>" section later in this chapter for more information about this process.    applications that the distribution certificate is needed. If
<H3><A NAME="77090"></A> Signing Certificates</H3>    you distribute many different signing certificates, and they
<P>As a Mozilla  <!--INDEX signing certificates -->  <!--INDEX certificates:signing -->  <!--INDEX remote applications:certificates:signing -->  <!--INDEX security:remote applications:signing certificates --> application developer, you can obtain a common MozDev signing certificate and release a signed application that puts your application on par with other signed MozDev applications. If you consider your application mission-critical, however, you should go to a trusted CA such as Verisign. Mozilla already supports the VeriSign  <!--INDEX Netscape:Object Signing certificate --> Netscape Object Signing CA, and discriminating users may find it more acceptable. A few other CAs listed in Mozilla's Certificate Manager may support Netscape Object Signing, so researching these options further may be worthwhile.    are used by all signed remote Mozilla applications, then all
<P>To get a <I>certs.mozdev.org/signing</I> certificate, send email to <I><A HREF="MAILTO:cert-request@mozdev.org">cert-request@mozdev.org</A></I>. In return, you will receive a <I>.cacert</I> file that will be used to sign your remote Mozilla application.    applications can use that same distribution certificate (as
<P>SignTool (part of the NSS tool sets) takes a directory of files, zips them up into a JAR archive (refer to the section <A HREF="#77092">"Signing the application</A>" later in this chapter to see how to do this), and signs the archive using the certificate you specify.    they do with Verisign's and other certificate authorities).</p>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    <p>To allow users to install the distribution certificate,
<P>SignTool comes with the latest release of NSS, Version 3.4.1. On <I><A HREF="http://certs.mozdev.org">http://certs.mozdev.org</A></I>, limited functionality versions of NSS contain SignTool for Windows and Linux that you can use instead for the processes in this book.<P></BLOCKQUOTE>    create a link to the certificate file on your web page:</p>
<P>Use CertUtil to set up a database for SignTool. Next, run some commands to set up the certificate environment:<pre>
<PRE>C:\NSS\bin&gt;certutil -N -d .&lt;a href="certs_mozdev.cacert"&gt;Install the MozDev CA Certificate&lt;/a&gt;
 </pre>
     <p>Also make sure that your web server uses the MIME type
     <tt>application/x-x509-ca-cert</tt> for <i>.cacert</i>
     files.</p>
     <p>If the web server is set up correctly, the user will get a
     dialog box that looks like <a href="#77010">Figure 12-5</a>.
     Tell the user to select the options for "web sites" and
     "software developers."</p>
     <div class="c25">
       <img src="foo.gif">
     </div>
     <p><i>Figure 12-5: <a name="77010"></a></i> <i>Downloading a
     certificate window</i></p>
     <p>After the certificate is installed, it will appear in the
     Certificate Manager, as shown in <a href="#77012">Figure
     12-6</a>. The Certificate Manager can be accessed via the
     global Mozilla preferences (Edit &gt; Preferences &gt; Privacy
     &amp; Security &gt; Certificates). Mozilla is then ready to run
     signed remote Mozilla applications bearing signatures from your
     certificate authority.</p>
     <div class="c25">
       <img src="foo.gif">
     </div>
     <p><i>Figure 12-6: <a name="77012"></a></i> <i>Certificate
     manager with a certs.mozdev.org CA certificate</i></p>
     <h2><a name="77088"></a> Creating Signed Remote
     Applications</h2>
     <p>Security in Mozilla's 
     <!--INDEX remote applications:signed --> 
     <!--INDEX security:remote applications:signed --> web browser
     is designed to meet today's advanced scripting needs in a
     secure manner. Mozilla is a much more secure browser than past
     Netscape 4.x and Internet Explorer releases because it has a
     better sense of what remote scripts can and cannot do.</p>
     <p>Because of Mozilla's approach toward potentially insecure
     applications, if you decide to serve up your own application
     remotely, remember that you will not have automatic access to
     the chrome in the way you do when you have a registered,
     locally installed Mozilla application. Unless you sign your
     application or have the user turn on a special preference (see
     <a href="#77070">"Setting Up XPFE for Remote
     Applications</a>"), services like XPConnect will not be
     available.</p>
     <p>In Mozilla, you can bundle any number of files into a JAR
     archive (which, you'll recall from <a href=
     "ch06.html#77063">Chapter 6</a>, is just a zip file with a JAR
     suffix) and designate the archive as an object that can be
     signed. This designation makes it very easy to produce an
     entire signed and secure remote Mozilla application because it
     stores your application in a single file type that Mozilla
     already treats as a separate package.</p>
     <p>This section provides an overview of the signed script
     technology and shows you how to create signed applications that
     live on the server but take full advantage of the user's local
     chrome, including Mozilla components.</p>
     <h3><a name="77089"></a> certs.mozdev.org CA Certificate</h3>
     <p>Before users <!--INDEX installation:certificates --> 
     <!--INDEX certificates:installing --> 
     <!--INDEX remote applications:certificates:installing --> 
     <!--INDEX security:remote applications:installing certificates -->
     can load signed applications, a CA certificate must be
     installed into their installed copy of Mozilla. Once this
     certificate is installed in a browser, all MozDev-signed
     applications can work with this certificate. This setup makes
     things easier on users who access many of these signed
     applications because they do not have to install a new
     certificate for each one. Also, if the user wants to use
     applications from other certificate authorities, they need to
     install a distribution certificate from that certificate
     authority.</p>
     <p>Installing the certificate is easy. Just provide the users
     with a regular link on a web page-for example, <i><a href=
     "http://certs.mozdev.org/certs_mozdev.cacert">http://certs.mozdev.org/certs_mozdev.cacert</a></i>.
     When loading this page, a dialog box pops up and asks the user
     to install the certificate. See the <a href=
     "#77093">"Distributing the application</a>" section later in
     this chapter for more information about this process.</p>
     <h3><a name="77090"></a> Signing Certificates</h3>
     <p>As a Mozilla <!--INDEX signing certificates --> 
     <!--INDEX certificates:signing --> 
     <!--INDEX remote applications:certificates:signing --> 
     <!--INDEX security:remote applications:signing certificates -->
     application developer, you can obtain a common MozDev signing
     certificate and release a signed application that puts your
     application on par with other signed MozDev applications. If
     you consider your application mission-critical, however, you
     should go to a trusted CA such as Verisign. Mozilla already
     supports the VeriSign 
     <!--INDEX Netscape:Object Signing certificate --> Netscape
     Object Signing CA, and discriminating users may find it more
     acceptable. A few other CAs listed in Mozilla's Certificate
     Manager may support Netscape Object Signing, so researching
     these options further may be worthwhile.</p>
     <p>To get a <i>certs.mozdev.org/signing</i> certificate, send
     email to <i><a href=
     "MAILTO:cert-request@mozdev.org">cert-request@mozdev.org</a></i>.
     In return, you will receive a <i>.cacert</i> file that will be
     used to sign your remote Mozilla application.</p>
     <p>SignTool (part of the NSS tool sets) takes a directory of
     files, zips them up into a JAR archive (refer to the section <a
     href="#77092">"Signing the application</a>" later in this
     chapter to see how to do this), and signs the archive using the
     certificate you specify.</p>
     <blockquote>
       <div class="c26">
         NOTE
       </div>
       <p>SignTool comes with the latest release of NSS, Version
       3.4.1. On <i><a href=
       "http://certs.mozdev.org">http://certs.mozdev.org</a></i>,
       limited functionality versions of NSS contain SignTool for
       Windows and Linux that you can use instead for the processes
       in this book.</p>
     </blockquote>
     <p>Use CertUtil to set up a database for SignTool. Next, run
     some commands to set up the certificate environment:</p>
 <pre>
 C:\NSS\bin&gt;certutil -N -d .
 C:\NSS\bin&gt;certutil -A -n "certs.mozdev.org/signing" -t ",,C"  C:\NSS\bin&gt;certutil -A -n "certs.mozdev.org/signing" -t ",,C"
-i eric.cacert -d .</PRE>-i eric.cacert -d .
<P>The first command creates an empty <I>cert7.db</I> file where certificates can be stored. The second imports your Signing Certificate into the database. SignTool can use only certificates that reside in a database, which is the reason for this process.</pre>
<H3><A NAME="77091"></A> Creating and Signing the Application</H3>    <p>The first command creates an empty <i>cert7.db</i> file
<P>When someone  <!--INDEX installation:certificates -->  <!--INDEX certificates:installing -->  <!--INDEX remote applications:certificates:installing -->  <!--INDEX security:remote applications:installing certificates --> obtains a private key (which is part of a Signing Certificate), they can encrypt their scripts and produce a public key. The relationship of the private key and the public key is called a  <!--INDEX private-public key pairs --> private-public key pair. Using this relationship, you can create a signed Mozilla application and make it available to users in three steps:    where certificates can be stored. The second imports your
<OL><P><LI>Build the application itself, including the XUL, CSS, JavaScript, and whatever else you use to create the Mozilla application.<P>    Signing Certificate into the database. SignTool can use only
<P>For this section, let's assume that you already created the XUL and JavaScript for the application and have all the files and directories together.<P>    certificates that reside in a database, which is the reason for
<P><LI>Archive and sign the application. SignTool takes care of both steps simultaneously, putting your application files in a JAR with a digital signature to validate everything.<P>    this process.</p>
<P>The signing process described next in <A HREF="#77092">"Signing the application</A>" deals entirely with SignTool.<P>    <h3><a name="77091"></a> Creating and Signing the
<P><LI>Distribute your application (see the later section <A HREF="#77093">"Distributing the application</A>").<P></OL>    Application</h3>
<H4><A NAME="77092"></A> Signing the application</H4>    <p>When someone <!--INDEX installation:certificates --> 
<P>Security is  <!--INDEX remote applications:signing -->  <!--INDEX security:remote applications:signing -->  <!--INDEX signing applications --> not simple. Security technologists and vendors work hard to make sure that evildoers cannot abuse their encryption schemes, keys, and other tricks. Tools like SignTool can hide some of this complexity from you. When you sign an application, you create a digital signature in the archive that is based on the relationship of the files being signed, as <A HREF="#77014">Figure 12-7</A> illustrates.    <!--INDEX certificates:installing --> 
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <!--INDEX remote applications:certificates:installing --> 
<P><I>Figure 12-7: <A NAME="77014"></A></I>    <!--INDEX security:remote applications:installing certificates -->
<I>SignTool's processes for creating a signed application</I>    obtains a private key (which is part of a Signing Certificate),
    they can encrypt their scripts and produce a public key. The
<P>SignTool automates these steps for you, so you don't worry about them. However, knowing these processes and seeing how these transactions take place can be useful, especially since using signed applications with Mozilla doesn't always work as expected and long-term directions for signed applications in Mozilla are uncertain. This uncertainty makes long-term deployment of signed remote Mozilla applications a risky option.    relationship of the private key and the public key is called a 
<P>To start off your remote Mozilla signed application development, you can do something as simple as place one XUL and one JavaScript file in a single directory. Then move it into a NSS <I>bin</I> directory such as <I>C:\NSS\bin</I> and issue the command:    <!--INDEX private-public key pairs --> private-public key pair.
<PRE>C:\NSS\bin&gt;signtool -d . -k"certs.mozdev.org/signing"    Using this relationship, you can create a signed Mozilla
-p"password_of_database" -Z"myapp.jar" myappfiles/</PRE>    application and make it available to users in three steps:</p>
<P>The <TT>-d</TT> option is where the certificate database resides and <TT>-k</TT> is the certificate name.    <ol>
<H4><A NAME="77093"></A> Distributing the application</H4>      <li>
<P>Once the file is <!--INDEX remote applications:distributing -->  <!--INDEX distribution:remote applications -->  created from the <TT>-Z</TT> option (e.g., <I>myapp.jar</I> from the example above), you can put it online. On the application's web page, note that the application is signed and put a link to <I><A HREF="http://certs.mozdev.org/certs_mozdev.cacert">http://certs.mozdev.org/certs_mozdev.cacert</A></I> so users can install the necessary MozDev certificate if they do not have it.        Build the application itself, including the XUL, CSS,
<P>To access the application online, you must use a special URL format. This format looks like <I>jar:<A HREF="http://certs.mozdev.org/myapp.jar">http://certs.mozdev.org/myapp.jar</A>!/myapp.xul</I> and points into the JAR at the main application file. This URL is difficult to type, so it may be wise to link it for user access or set up a redirected URL to that address, as shown in <A HREF="#77048">Example 12-12</A>.        JavaScript, and whatever else you use to create the Mozilla
        application.
Example 12-12<A NAME="77048"></A>        <p>For this section, let's assume that you already created
<I>Sample redirect into a signed application</I>        the XUL and JavaScript for the application and have all the
<PRE> &lt;HTML&gt;        files and directories together.</p>
       </li>
       <li>
         Archive and sign the application. SignTool takes care of
         both steps simultaneously, putting your application files
         in a JAR with a digital signature to validate everything.
         <p>The signing process described next in <a href=
         "#77092">"Signing the application</a>" deals entirely with
         SignTool.</p>
       </li>
       <li>Distribute your application (see the later section <a
       href="#77093">"Distributing the application</a>").</li>
     </ol>
     <h4><a name="77092"></a> Signing the application</h4>
     <p>Security is <!--INDEX remote applications:signing --> 
     <!--INDEX security:remote applications:signing --> 
     <!--INDEX signing applications --> not simple. Security
     technologists and vendors work hard to make sure that evildoers
     cannot abuse their encryption schemes, keys, and other tricks.
     Tools like SignTool can hide some of this complexity from you.
     When you sign an application, you create a digital signature in
     the archive that is based on the relationship of the files
     being signed, as <a href="#77014">Figure 12-7</a>
     illustrates.</p>
     <div class="c25">
       <img src="foo.gif">
     </div>
     <p><i>Figure 12-7: <a name="77014"></a></i> <i>SignTool's
     processes for creating a signed application</i></p>
     <p>SignTool automates these steps for you, so you don't worry
     about them. However, knowing these processes and seeing how
     these transactions take place can be useful, especially since
     using signed applications with Mozilla doesn't always work as
     expected and long-term directions for signed applications in
     Mozilla are uncertain. This uncertainty makes long-term
     deployment of signed remote Mozilla applications a risky
     option.</p>
     <p>To start off your remote Mozilla signed application
     development, you can do something as simple as place one XUL
     and one JavaScript file in a single directory. Then move it
     into a NSS <i>bin</i> directory such as <i>C:\NSS\bin</i> and
     issue the command:</p>
 <pre>
 C:\NSS\bin&gt;signtool -d . -k"certs.mozdev.org/signing"
 -p"password_of_database" -Z"myapp.jar" myappfiles/
 </pre>
     <p>The <tt>-d</tt> option is where the certificate database
     resides and <tt>-k</tt> is the certificate name.</p>
     <h4><a name="77093"></a> Distributing the application</h4>
     <p>Once the file is 
     <!--INDEX remote applications:distributing --> 
     <!--INDEX distribution:remote applications --> created from the
     <tt>-Z</tt> option (e.g., <i>myapp.jar</i> from the example
     above), you can put it online. On the application's web page,
     note that the application is signed and put a link to <i><a
     href=
     "http://certs.mozdev.org/certs_mozdev.cacert">http://certs.mozdev.org/certs_mozdev.cacert</a></i>
     so users can install the necessary MozDev certificate if they
     do not have it.</p>
     <p>To access the application online, you must use a special URL
     format. This format looks like <i>jar:<a href=
     "http://certs.mozdev.org/myapp.jar">http://certs.mozdev.org/myapp.jar</a>!/myapp.xul</i>
     and points into the JAR at the main application file. This URL
     is difficult to type, so it may be wise to link it for user
     access or set up a redirected URL to that address, as shown in
     <a href="#77048">Example 12-12</a>. Example 12-12<a name=
     "77048"></a> <i>Sample redirect into a signed
     application</i></p>
 <pre>
  &lt;HTML&gt;
  &lt;HEAD&gt;   &lt;HEAD&gt;
    &lt;META HTTP-EQUIV="REFRESH" CONTENT="0;     &lt;META HTTP-EQUIV="REFRESH" CONTENT="0;
         URL= jar:<A HREF="http://certs.mozdev.org/sample.jar">http://certs.mozdev.org/sample.jar</A>!/sample.xul"&gt;         URL= jar:<a href=
 "http://certs.mozdev.org/sample.jar">http://certs.mozdev.org/sample.jar</a>!/sample.xul"&gt;
  &lt;/HEAD&gt;   &lt;/HEAD&gt;
 &lt;/HTML&gt;</PRE> &lt;/HTML&gt;
</pre>
<H3><A NAME="77094"></A> Receiving a Signed Application</H3>    <h3><a name="77094"></a> Receiving a Signed Application</h3>
<P>As shown in  <!--INDEX remote applications:receiving -->  <!--INDEX security:remote applications:receiving --> <A HREF="#77016">Figure 12-8</A>, when Mozilla receives a JAR, it must check it for validity before displaying the contents. A public key in <I>certs_mozdev.cacert</I> must be used along with the digital signature to make sure that the contents are not tampered with and that the signature is valid.    <p>As shown in <!--INDEX remote applications:receiving --> 
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <!--INDEX security:remote applications:receiving --> <a href=
<P><I>Figure 12-8: <A NAME="77016"></A></I>    "#77016">Figure 12-8</a>, when Mozilla receives a JAR, it must
<I>Receiving a signed application</I>    check it for validity before displaying the contents. A public
    key in <i>certs_mozdev.cacert</i> must be used along with the
<BLOCKQUOTE><CENTER><B>WARNING</B></CENTER>    digital signature to make sure that the contents are not
<P>When you are  <!--INDEX JAR (Java Archive) files:remote applications -->  <!--INDEX remote applications:updating, JAR files and --> developing a signed remote Mozilla application, clear a JAR's cache before trying to reload an updated version of it. Clearing the cache can be done most easily by restarting Mozilla. If you or your users do not do clear it, the consumer of the application will probably wind up with a blank screen.<P></BLOCKQUOTE>    tampered with and that the signature is valid.</p>
<H2><A NAME="77095"></A> Expanded Privileges in Mozilla</H2>    <div class="c25">
<P>While the security aspect  <!--INDEX privileges:remote applications -->  <!--INDEX remote applications:privileges -->  <!--INDEX security:remote applications:privileges --> of signed objects is nice, the ability to make remote Java-Script do just about anything is even better for web developers because it avoids the perceived complexity of languages like C++. Also, JavaScript, along with Perl and PHP, has always been a preferred language in the web environment.      <img src="foo.gif">
<P>Knowing that Internet Explorer no longer has a huge advantage when it comes to remote browser-based applications is also nice, since JavaScript and XPCOM in Mozilla provide a framework very similar to ActiveX. They also provide web page scripting in which you can create and use components from a web page or web application.    </div>
<P><A HREF="#77022">Table 12-1</A> shows the expanded privileges available to signed scripts. Signed applications are granted these privileges as a matter of course.    <p><i>Figure 12-8: <a name="77016"></a></i> <i>Receiving a
    signed application</i></p>
<P><I>Table 12-1: <A NAME="77022"></A></I>    <blockquote>
<I>Expanded privileges available to signed scripts</I>      <div class="c26">
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Privilege</B></TD> <TD><B>  Purpose</B></TD></TR>        WARNING
<TR><TD>  UniversalBrowserRead</TD>     <TD>  Reads sensitive browser data. This reading allows the script to pass the same origin check when reading from any document.</TD></TR>      </div>
<TR><TD>  UniversalBrowserWrite</TD>     <TD>  Modifies sensitive browser data. This modification allows the script to pass the same origin check when writing to any document.</TD></TR>      <p>When you are 
<TR><TD>  UniversalXPConnect</TD>     <TD>  Gives unrestricted access to browser APIs using XPConnect.</TD></TR>      <!--INDEX JAR (Java Archive) files:remote applications --> 
<TR><TD>  UniversalPreferencesRead</TD>     <TD>  Reads preferences using the </TD><TT>navigator.preference</TT> method.</TR>      <!--INDEX remote applications:updating, JAR files and -->
<TR><TD>  UniversalPreferencesWrite</TD>     <TD>  Allows you to set preferences using the </TD><TT>navigator.preference</TT> method.</TR>      developing a signed remote Mozilla application, clear a JAR's
<TR><TD>  CapabilityPreferencesAccess</TD>     <TD>  Allows you to read/set the preferences that define security policies, including which privileges are granted and denied to scripts. (You also need </TD><I>UniversalPreferencesRead/Write</I>.)</TR>      cache before trying to reload an updated version of it.
<TR><TD>  UniversalFileRead</TD>     <TD>  Handles </TD><TT>window.open</TT> of <I>file://</I> URLs. Makes the browser upload files from the user's hard drive by using <TT>&lt;input type="file"&gt;</TT>.</TR></TABLE><P>      Clearing the cache can be done most easily by restarting
      Mozilla. If you or your users do not do clear it, the
<P>The JavaScript features require expanded privileges and the target used to access each feature. Unsigned scripts cannot do the following:      consumer of the application will probably wind up with a
<UL><P><LI>Use an about: format URL other than <I>about:blank</I>; requires <I>Universal-BrowserRead</I>.<P>      blank screen.</p>
<P><LI>Use the history object to find out what other sites the user visited or how many other sites the user visited in this session. Doing so requires <I>Universal-BrowserRead</I>.<P>    </blockquote>
<P><LI>When using navigator object, get the preference value by using the preference method. Getting such a value requires <I>UniversalPreferencesRead</I>.<P>    <h2><a name="77095"></a> Expanded Privileges in Mozilla</h2>
<P><LI>Set the preference value using the preference method; getting this value requires <I>UniversalPreferencesWrite</I>.<P>    <p>While the security aspect 
<P><LI>Add or remove the directory bar, location bar, menu bar, personal bar, scroll bar, status bar, or toolbar. These are done using the window object and require <I>UniversalBrowserWrite</I>.<P>    <!--INDEX privileges:remote applications --> 
<P><LI>Use the methods and properties in the <A HREF="#77024">Table 12-2</A> under the indicated circumstances.<P></UL>    <!--INDEX remote applications:privileges --> 
    <!--INDEX security:remote applications:privileges --> of signed
<P><I>Table 12-2: <A NAME="77024"></A></I>    objects is nice, the ability to make remote Java-Script do just
<I>Expanded privileges available to signed scripts</I>    about anything is even better for web developers because it
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Method / property</B></TD>   <TD><B>  Description</B></TD></TR>    avoids the perceived complexity of languages like C++. Also,
<TR><TD>  EnableExternalCapture</TD>    <TD>  Captures events in pages loaded from different servers. Follow this method with </TD><I>captureEvents</I>.</TR>    JavaScript, along with Perl and PHP, has always been a
<TR><TD>  Close</TD>    <TD>  Unconditionally closes a browser window.</TD></TR>    preferred language in the web environment.</p>
<TR><TD>  moveBy, moveTo</TD>   <TD>  Moves a window off of the screen.</TD></TR>    <p>Knowing that Internet Explorer no longer has a huge
<TR><TD>  Open</TD>             *        Creates a window smaller than 100 x 100 pixels or larger than the screen can accommodate by using <I>innerWidth</I>, <I>innerHeight,</I> <I>outerWidth</I>, and <I>outerHeight</I>.</TR></TABLE><P>    advantage when it comes to remote browser-based applications is
        *        Places a window offscreen by using <I>screenX</I> and <I>screenY</I>.    also nice, since JavaScript and XPCOM in Mozilla provide a
        *        Creates a window without a titlebar by using <TT>titlebar=no</TT>.    framework very similar to ActiveX. They also provide web page
        *        Uses <I>alwaysRaised</I>, <I>alwaysLowered</I>, or z-lock for any setting.    scripting in which you can create and use components from a web
<P><TABLE WIDTH=100% BORDER=1><TR><TD>  resizeTo, resizeBy</TD>     <TD>  Resizes a window smaller than 100 x 100 pixels or larger than the screen can accommodate.</TD></TR>    page or web application.</p>
<TR><TD>  innerWidth, innerHeight</TD>     <TD>  Sets the inner width of a window to a size smaller than 100 x 100 or larger than the screen can accommodate.</TD></TR></TABLE><P>    <p><a href="#77022">Table 12-1</a> shows the expanded
    privileges available to signed scripts. Signed applications are
<P>This snippet of code shows how to use the privilege manager in JavaScript:    granted these privileges as a matter of course.</p>
<PRE>netscape.security.PrivilegeManager.    <p><i>Table 12-1: <a name="77022"></a></i> <i>Expanded
     privileges available to signed scripts</i></p>
     <tt>navigator.preference</tt>method.<tt>navigator.preference</tt>method.<i>
     UniversalPreferencesRead/Write</i>.)<tt>window.open</tt>of
     <i>file://</i>URLs. Makes the browser upload files from the
     user's hard drive by using <tt>&lt;input type="file"&gt;</tt>.
     <table width="100%" border="1">
       <tr>
         <td><b>Privilege</b></td>
         <td><b>Purpose</b></td>
       </tr>
       <tr>
         <td>UniversalBrowserRead</td>
         <td>Reads sensitive browser data. This reading allows the
         script to pass the same origin check when reading from any
         document.</td>
       </tr>
       <tr>
         <td>UniversalBrowserWrite</td>
         <td>Modifies sensitive browser data. This modification
         allows the script to pass the same origin check when
         writing to any document.</td>
       </tr>
       <tr>
         <td>UniversalXPConnect</td>
         <td>Gives unrestricted access to browser APIs using
         XPConnect.</td>
       </tr>
       <tr>
         <td>UniversalPreferencesRead</td>
         <td>Reads preferences using the</td>
       </tr>
       <tr>
         <td>UniversalPreferencesWrite</td>
         <td>Allows you to set preferences using the</td>
       </tr>
       <tr>
         <td>CapabilityPreferencesAccess</td>
         <td>Allows you to read/set the preferences that define
         security policies, including which privileges are granted
         and denied to scripts. (You also need</td>
       </tr>
       <tr>
         <td>UniversalFileRead</td>
         <td>Handles</td>
       </tr>
     </table>
     <p>The JavaScript features require expanded privileges and the
     target used to access each feature. Unsigned scripts cannot do
     the following:</p>
     <ul>
       <li>Use an about: format URL other than <i>about:blank</i>;
       requires <i>Universal-BrowserRead</i>.</li>
       <li>Use the history object to find out what other sites the
       user visited or how many other sites the user visited in this
       session. Doing so requires <i>Universal-BrowserRead</i>.</li>
       <li>When using navigator object, get the preference value by
       using the preference method. Getting such a value requires
       <i>UniversalPreferencesRead</i>.</li>
       <li>Set the preference value using the preference method;
       getting this value requires
       <i>UniversalPreferencesWrite</i>.</li>
       <li>Add or remove the directory bar, location bar, menu bar,
       personal bar, scroll bar, status bar, or toolbar. These are
       done using the window object and require
       <i>UniversalBrowserWrite</i>.</li>
       <li>Use the methods and properties in the <a href=
       "#77024">Table 12-2</a> under the indicated
       circumstances.</li>
     </ul>
     <p><i>Table 12-2: <a name="77024"></a></i> <i>Expanded
     privileges available to signed scripts</i></p>
     <i>captureEvents</i>.* Creates a window smaller than 100 x 100
     pixels or larger than the screen can accommodate by using
     <i>innerWidth</i>, <i>innerHeight,</i><i>outerWidth</i>, and
     <i>outerHeight</i>.
     <table width="100%" border="1">
       <tr>
         <td><b>Method / property</b></td>
         <td><b>Description</b></td>
       </tr>
       <tr>
         <td>EnableExternalCapture</td>
         <td>Captures events in pages loaded from different servers.
         Follow this method with</td>
       </tr>
       <tr>
         <td>Close</td>
         <td>Unconditionally closes a browser window.</td>
       </tr>
       <tr>
         <td>moveBy, moveTo</td>
         <td>Moves a window off of the screen.</td>
       </tr>
       <tr>
         <td>Open</td>
       </tr>
     </table>
     <p>* Places a window offscreen by using <i>screenX</i> and
     <i>screenY</i>. * Creates a window without a titlebar by using
     <tt>titlebar=no</tt>. * Uses <i>alwaysRaised</i>,
     <i>alwaysLowered</i>, or z-lock for any setting.</p>
     <table width="100%" border="1">
       <tr>
         <td>resizeTo, resizeBy</td>
         <td>Resizes a window smaller than 100 x 100 pixels or
         larger than the screen can accommodate.</td>
       </tr>
       <tr>
         <td>innerWidth, innerHeight</td>
         <td>Sets the inner width of a window to a size smaller than
         100 x 100 or larger than the screen can accommodate.</td>
       </tr>
     </table>
     <p>This snippet of code shows how to use the privilege manager
     in JavaScript:</p>
 <pre>
 netscape.security.PrivilegeManager.
       enablePrivilege("UniversalBrowserWrite");        enablePrivilege("UniversalBrowserWrite");
window.titlebar=no;</PRE>window.titlebar=no;
<P>You can pass any privilege listed in <A HREF="#77022">Table 12-1</A> to the <TT>enablePrivilege</TT> method, which is accessed through the <TT>netscape.security.PrivilegeManager</TT> object. This object is recognized globally. In this example, the code hides the titlebar via the window object.</pre>
<P>Security is extremely important, so it is important that some means of granting special privileges to trusted scripts for accessing Mozilla components be available. In essence, signed scripts are Mozilla's version of ActiveX.    <p>You can pass any privilege listed in <a href="#77022">Table
<P>The parallels become even more apparent when you consider access to XPConnect as one of the security model's main boundaries. Just as ActiveX makes COM available in IE, signing makes XPCOM available in remote Mozilla applications. Given all that is possible in XPCOM, this chapter leaves what can be archived with remote Mozilla applications and XPConnect up to your imagination.    12-1</a> to the <tt>enablePrivilege</tt> method, which is
<H2><A NAME="77096"></A> Signed Remote Snake Game</H2>    accessed through the
<P>In this section, we look at an enhanced version of the Snake game presented earlier in the chapter. The enhanced version uses XPConnect to provide a total full-screen display of the game on the Windows platform as a remote application.    <tt>netscape.security.PrivilegeManager</tt> object. This object
<H3><A NAME="77097"></A> How to Expand Mozilla to Full Screen</H3>    is recognized globally. In this example, the code hides the
<P>The best way to <!--INDEX full-screen mode, enabling -->  <!--INDEX remote applications:Snake game:expanding to full screen -->  <!--INDEX Snake game:expanding to full screen -->  <!--INDEX games:expanding to full screen -->  expand Mozilla to a full screen mode is through full-screen functions provided in an instance of <I>navigator.xul</I>. These functions run in the Windows build of Mozilla via the Full Screen item in the View menu. These functions also work in Linux and Mac, but do not provide 100% full-screen mode, as some menus and titlebars still show.    titlebar via the window object.</p>
<P>The problem here is the current window's <I>navigator.xul</I> document, which needs to be accessed to get these full-screen functions. A document loaded in that window just can't use something like <I>window.parent </I>to get to it, so another route must be found.    <p>Security is extremely important, so it is important that
<P>This route runs through the <I>nsIWindowMediator</I> interface by the way of XPConnect. It gives access to the current browser window's <I>navigator.xul</I> document's window object. <A HREF="#77050">Example 12-13</A> includes the code for this window access process, along with the functions used to create the full-screen effect.    some means of granting special privileges to trusted scripts
    for accessing Mozilla components be available. In essence,
Example 12-13<A NAME="77050"></A>    signed scripts are Mozilla's version of ActiveX.</p>
<I>Function for switching screen modes</I>    <p>The parallels become even more apparent when you consider
<PRE> netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");    access to XPConnect as one of the security model's main
     boundaries. Just as ActiveX makes COM available in IE, signing
     makes XPCOM available in remote Mozilla applications. Given all
     that is possible in XPCOM, this chapter leaves what can be
     archived with remote Mozilla applications and XPConnect up to
     your imagination.</p>
     <h2><a name="77096"></a> Signed Remote Snake Game</h2>
     <p>In this section, we look at an enhanced version of the Snake
     game presented earlier in the chapter. The enhanced version
     uses XPConnect to provide a total full-screen display of the
     game on the Windows platform as a remote application.</p>
     <h3><a name="77097"></a> How to Expand Mozilla to Full
     Screen</h3>
     <p>The best way to <!--INDEX full-screen mode, enabling --> 
     <!--INDEX remote applications:Snake game:expanding to full screen -->
     <!--INDEX Snake game:expanding to full screen --> 
     <!--INDEX games:expanding to full screen --> expand Mozilla to
     a full screen mode is through full-screen functions provided in
     an instance of <i>navigator.xul</i>. These functions run in the
     Windows build of Mozilla via the Full Screen item in the View
     menu. These functions also work in Linux and Mac, but do not
     provide 100% full-screen mode, as some menus and titlebars
     still show.</p>
     <p>The problem here is the current window's
     <i>navigator.xul</i> document, which needs to be accessed to
     get these full-screen functions. A document loaded in that
     window just can't use something like <i>window.parent</i> to
     get to it, so another route must be found.</p>
     <p>This route runs through the <i>nsIWindowMediator</i>
     interface by the way of XPConnect. It gives access to the
     current browser window's <i>navigator.xul</i> document's window
     object. <a href="#77050">Example 12-13</a> includes the code
     for this window access process, along with the functions used
     to create the full-screen effect. Example 12-13<a name=
     "77050"></a> <i>Function for switching screen modes</i></p>
 <pre>
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  const MEDIATOR_CONTRACTID="@mozilla.org/appshell/window-mediator;1";   const MEDIATOR_CONTRACTID="@mozilla.org/appshell/window-mediator;1";
  const nsIWindowMediator=Components.interfaces.nsIWindowMediator;   const nsIWindowMediator=Components.interfaces.nsIWindowMediator;
  var windowManager=   var windowManager=
     Components.classes</TD>[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);     Components.classes&lt;/td&gt;[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
  var hideSidebar=true;   var hideSidebar=true;
  var isRegular=true;   var isRegular=true;
  function switchScreen( )   function switchScreen( )
Line 665  Example 12-13<A NAME="77050"></A> Line 1607  Example 12-13<A NAME="77050"></A>
      mainWindow.BrowserFullScreen( );       mainWindow.BrowserFullScreen( );
      isRegular=true;       isRegular=true;
    }     }
 }</PRE> }
</pre>
<P><TT>windowManager</TT>, which is spawned by XPConnect, creates the <I>mainWindow</I> variable. By using the <TT>getMostRecentWindow</TT> function for <TT>navigator:browser</TT>, the Mozilla application window you currently use becomes available. Next, tests are made in code for the window status determine if it is regular or full screen. Appropriate action can then be made by calling the <TT>SidebarShowHide</TT> function.    <p><tt>windowManager</tt>, which is spawned by XPConnect,
<P>As you can see in <A HREF="#77050">Example 12-13</A>, code for hiding the toolbar and location bar is also present. This code is accomplished not by the <I>mainWindow</I> created through XPConnect, but by the existing window object:    creates the <i>mainWindow</i> variable. By using the
<PRE>window.locationbar.visible=false;    <tt>getMostRecentWindow</tt> function for
window.toolbar.visible=false;</PRE>    <tt>navigator:browser</tt>, the Mozilla application window you
<P>Using both the <TT>mainWindow</TT> and <TT>window</TT> objects allows the creation of a full-screen remote Mozilla application by allowing XPConnect privileges. <A HREF="#77018">Figure 12-9</A> shows the result on Windows-a total full screen for a signed remote Mozilla game!    currently use becomes available. Next, tests are made in code
<P><CENTER><IMG SRC="foo.gif"></CENTER>    for the window status determine if it is regular or full
<P><I>Figure 12-9: <A NAME="77018"></A></I>    screen. Appropriate action can then be made by calling the
<I>Snake game in full-screen mode on Windows</I>    <tt>SidebarShowHide</tt> function.</p>
    <p>As you can see in <a href="#77050">Example 12-13</a>, code
<H2><A NAME="77098"></A> Mozilla's XML Extras and SOAP</H2>    for hiding the toolbar and location bar is also present. This
<P>Mozilla has built functions called <!--INDEX XML Extras -->  <!--INDEX web sites:XML Extras -->  XML Extras that allow the use of XML as data in both JavaScript and C++. Such functions are an XML Serializer, XMLHttpRequest, XML Parser, SOAP-based RPC, and XML Persistence. You can find more information about these functions, along with examples, at <I><A HREF="http://www.mozilla.org/xmlextras/">http://www.mozilla.org/xmlextras/</A></I>.    code is accomplished not by the <i>mainWindow</i> created
<P>The following sections assume that you are familiar with SOAP and .NET. If not, some good O'Reilly books available on these subjects can help get you started.    through XPConnect, but by the existing window object:</p>
<H3><A NAME="77099"></A> Mozilla, SOAP, and .NET</H3><pre>
<P>In this section, SOAP is used to access data in a .NET web service, therefore allowing the Snake game to have features such as a saved game score, a retrieved game score, and a list of high scores.window.locationbar.visible=false;
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>window.toolbar.visible=false;
<P>As of Mozilla 1.0, the SOAP functions of Mozilla do not work in signed scripts. This bug will be corrected in the future. All JavaScript using SOAP functions in this section is loaded externally of the signed JAR. These SOAP functions do not require enhanced privileges.<P></BLOCKQUOTE></pre>
<H3><A NAME="77100"></A> Setting Up a .NET Web Service</H3>    <p>Using both the <tt>mainWindow</tt> and <tt>window</tt>
<P>The easiest  <!--INDEX Snake game:.NET web service -->  <!--INDEX .NET web service, setting up[NET web service, setting up] -->  <!--INDEX remote applications:Snake game:setting up .Net web service -->  <!--INDEX games:Snake:setting up .NET web service --> way  <!--INDEX SOAP:.NET web service, setting up[SOAP:NET web service, setting up] --> to create a .NET web service is through Visual Studio.NET, which provides a template for creating these services. <A HREF="#77052">Example 12-14</A> shows a bare minimum of C# code used to compile the functions that return a value to the Snake game.    objects allows the creation of a full-screen remote Mozilla
<P>Obviously, a full implementation would need a database to store these scores. For this section, seeing how the interfaces work for these SOAP functions is more important.    application by allowing XPConnect privileges. <a href=
    "#77018">Figure 12-9</a> shows the result on Windows-a total
Example 12-14<A NAME="77052"></A>    full screen for a signed remote Mozilla game!</p>
<I>Minimal .NET web service</I>    <div class="c25">
<PRE> using System;      <img src="foo.gif">
     </div>
     <p><i>Figure 12-9: <a name="77018"></a></i> <i>Snake game in
     full-screen mode on Windows</i></p>
     <h2><a name="77098"></a> Mozilla's XML Extras and SOAP</h2>
     <p>Mozilla has built functions called <!--INDEX XML Extras --> 
     <!--INDEX web sites:XML Extras --> XML Extras that allow the
     use of XML as data in both JavaScript and C++. Such functions
     are an XML Serializer, XMLHttpRequest, XML Parser, SOAP-based
     RPC, and XML Persistence. You can find more information about
     these functions, along with examples, at <i><a href=
     "http://www.mozilla.org/xmlextras/">http://www.mozilla.org/xmlextras/</a></i>.</p>
     <p>The following sections assume that you are familiar with
     SOAP and .NET. If not, some good O'Reilly books available on
     these subjects can help get you started.</p>
     <h3><a name="77099"></a> Mozilla, SOAP, and .NET</h3>
     <p>In this section, SOAP is used to access data in a .NET web
     service, therefore allowing the Snake game to have features
     such as a saved game score, a retrieved game score, and a list
     of high scores.</p>
     <blockquote>
       <div class="c26">
         NOTE
       </div>
       <p>As of Mozilla 1.0, the SOAP functions of Mozilla do not
       work in signed scripts. This bug will be corrected in the
       future. All JavaScript using SOAP functions in this section
       is loaded externally of the signed JAR. These SOAP functions
       do not require enhanced privileges.</p>
     </blockquote>
     <h3><a name="77100"></a> Setting Up a .NET Web Service</h3>
     <p>The easiest <!--INDEX Snake game:.NET web service --> 
     <!--INDEX .NET web service, setting up[NET web service, setting up] -->
     <!--INDEX remote applications:Snake game:setting up .Net web service -->
     <!--INDEX games:Snake:setting up .NET web service --> way 
     <!--INDEX SOAP:.NET web service, setting up[SOAP:NET web service, setting up] -->
     to create a .NET web service is through Visual Studio.NET,
     which provides a template for creating these services. <a href=
     "#77052">Example 12-14</a> shows a bare minimum of C# code used
     to compile the functions that return a value to the Snake
     game.</p>
     <p>Obviously, a full implementation would need a database to
     store these scores. For this section, seeing how the interfaces
     work for these SOAP functions is more important. Example
     12-14<a name="77052"></a> <i>Minimal .NET web service</i></p>
 <pre>
  using System;
  using System.Collections;   using System.Collections;
  using System.ComponentModel;   using System.ComponentModel;
  using System.Data;   using System.Data;
Line 698  Example 12-14<A NAME="77052"></A> Line 1686  Example 12-14<A NAME="77052"></A>
  using System.Web.Services;   using System.Web.Services;
  namespace SnakeService   namespace SnakeService
  {   {
     </TD>[WebServiceAttribute (Namespace="uri:SnakeScore")]     &lt;/td&gt;[WebServiceAttribute (Namespace="uri:SnakeScore")]
      public class SnakeService : System.Web.Services.WebService       public class SnakeService : System.Web.Services.WebService
      {       {
          public SnakeService( )           public SnakeService( )
Line 717  Example 12-14<A NAME="77052"></A> Line 1705  Example 12-14<A NAME="77052"></A>
              base.Dispose(disposing);               base.Dispose(disposing);
          }           }
          #endregion           #endregion
         </TD>[WebMethod]         &lt;/td&gt;[WebMethod]
          public string SaveScore(string PlayerName, string Score)           public string SaveScore(string PlayerName, string Score)
          {           {
              return "Save of score successful.";               return "Save of score successful.";
          }           }
          </TD>[WebMethod]          &lt;/td&gt;[WebMethod]
          public string GetScore(string PlayerName)           public string GetScore(string PlayerName)
          {           {
              int Score = 990;               int Score = 990;
              return Score.ToString( );               return Score.ToString( );
          }           }
         </TD>[WebMethod]         &lt;/td&gt;[WebMethod]
          public string GetHighScores( )           public string GetHighScores( )
          {           {
              return "EDM 1000,SLK 200,BRP 10";               return "EDM 1000,SLK 200,BRP 10";
          }           }
      }       }
 }</PRE> }
</pre>
<P>The most important part of <A HREF="#77052">Example 12-14</A> is the <TT>WebServiceAttribute</TT> because it sets up a URI reference to the <TT>SnakeService</TT> object. When a request is sent from the Snake game to the .NET <TT>SnakeService</TT>, <TT>uri:SnakeScore</TT> becomes the name for the object providing functions for getting and setting the game's score.    <p>The most important part of <a href="#77052">Example
<P>In <A HREF="#77052">Example 12-14</A>, all the parameter and return values are of the <TT>string</TT> type. Considering the brevity of this example, expanding it would not be hard. Functions using other objects and database connections would really make it a true web application.    12-14</a> is the <tt>WebServiceAttribute</tt> because it sets
<H3><A NAME="77101"></A> .NET WSDL</H3>    up a URI reference to the <tt>SnakeService</tt> object. When a
<P>.NET automatically  <!--INDEX WSDL, generating -->  <!--INDEX Snake game:WSDL, generating -->  <!--INDEX games:Snake:generating WSDL --> generates WSDL interfaces inside a web service. Mozilla SOAP doesn't need to reference a WDSL file to make SOAP transactions.    request is sent from the Snake game to the .NET
<P><A HREF="#77054">Example 12-15</A> is a portion of the WDSL that .NET generates and is the specific portion that relates directly to sending raw SOAP calls to the <TT>SnakeService</TT>. Also, only the definitions for the <TT>GetScore</TT> function are in this abbreviated definition.    <tt>SnakeService</tt>, <tt>uri:SnakeScore</tt> becomes the name
    for the object providing functions for getting and setting the
Example 12-15<A NAME="77054"></A>    game's score.</p>
<I>Abbreviated WSDL as produced by .NET web service.</I>    <p>In <a href="#77052">Example 12-14</a>, all the parameter and
<PRE> &lt;?xml version="1.0" encoding="utf-8"?&gt;    return values are of the <tt>string</tt> type. Considering the
     brevity of this example, expanding it would not be hard.
     Functions using other objects and database connections would
     really make it a true web application.</p>
     <h3><a name="77101"></a> .NET WSDL</h3>
     <p>.NET automatically <!--INDEX WSDL, generating --> 
     <!--INDEX Snake game:WSDL, generating --> 
     <!--INDEX games:Snake:generating WSDL --> generates WSDL
     interfaces inside a web service. Mozilla SOAP doesn't need to
     reference a WDSL file to make SOAP transactions.</p>
     <p><a href="#77054">Example 12-15</a> is a portion of the WDSL
     that .NET generates and is the specific portion that relates
     directly to sending raw SOAP calls to the
     <tt>SnakeService</tt>. Also, only the definitions for the
     <tt>GetScore</tt> function are in this abbreviated definition.
     Example 12-15<a name="77054"></a> <i>Abbreviated WSDL as
     produced by .NET web service.</i></p>
 <pre>
  &lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;definitions   &lt;definitions
    xmlns:http="<A HREF="http://schemas.xmlsoap.org/wsdl/http/">http://schemas.xmlsoap.org/wsdl/http/</A>"    xmlns:http="<a href=
    xmlns:soap="<A HREF="http://schemas.xmlsoap.org/wsdl/soap/">http://schemas.xmlsoap.org/wsdl/soap/</A>""http://schemas.xmlsoap.org/wsdl/http/">http://schemas.xmlsoap.org/wsdl/http/</a>"
    xmlns:s="<A HREF="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</A>" xmlns:s0="uri:SnakeScore"    xmlns:soap="<a href=
    xmlns:soapenc="<A HREF="http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</A>""http://schemas.xmlsoap.org/wsdl/soap/">http://schemas.xmlsoap.org/wsdl/soap/</a>"
    xmlns:tm="<A HREF="http://microsoft.com/wsdl/mime/textMatching/">http://microsoft.com/wsdl/mime/textMatching/</A>"    xmlns:s="<a href=
    xmlns:mime="<A HREF="http://schemas.xmlsoap.org/wsdl/mime/">http://schemas.xmlsoap.org/wsdl/mime/</A>""http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>" xmlns:s0="uri:SnakeScore"
     xmlns:soapenc="<a href=
 "http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"
     xmlns:tm="<a href=
 "http://microsoft.com/wsdl/mime/textMatching/">http://microsoft.com/wsdl/mime/textMatching/</a>"
     xmlns:mime="<a href=
 "http://schemas.xmlsoap.org/wsdl/mime/">http://schemas.xmlsoap.org/wsdl/mime/</a>"
     targetNamespace="uri:SnakeScore"      targetNamespace="uri:SnakeScore"
    xmlns="<A HREF="http://schemas.xmlsoap.org/wsdl/">http://schemas.xmlsoap.org/wsdl/</A>"&gt;    xmlns="<a href=
 "http://schemas.xmlsoap.org/wsdl/">http://schemas.xmlsoap.org/wsdl/</a>"&gt;
    &lt;types&gt;     &lt;types&gt;
      &lt;s:schema elementFormDefault="qualified"       &lt;s:schema elementFormDefault="qualified"
                targetNamespace="uri:SnakeScore"&gt;                 targetNamespace="uri:SnakeScore"&gt;
Line 788  Example 12-15<A NAME="77054"></A> Line 1801  Example 12-15<A NAME="77054"></A>
      &lt;/operation&gt;       &lt;/operation&gt;
    &lt;/portType&gt;     &lt;/portType&gt;
    &lt;binding name="SnakeServiceSoap" type="s0:SnakeServiceSoap"&gt;     &lt;binding name="SnakeServiceSoap" type="s0:SnakeServiceSoap"&gt;
     &lt;soap:binding transport="<A HREF="http://schemas.xmlsoap.org/soap/http">http://schemas.xmlsoap.org/soap/http</A>"     &lt;soap:binding transport="<a href=
 "http://schemas.xmlsoap.org/soap/http">http://schemas.xmlsoap.org/soap/http</a>"
                    style="document" /&gt;                     style="document" /&gt;
      &lt;operation name="GetScore"&gt;       &lt;operation name="GetScore"&gt;
        &lt;soap:operation soapAction="uri:SnakeScore/GetScore"         &lt;soap:operation soapAction="uri:SnakeScore/GetScore"
Line 804  Example 12-15<A NAME="77054"></A> Line 1818  Example 12-15<A NAME="77054"></A>
    &lt;service name="SnakeService"&gt;     &lt;service name="SnakeService"&gt;
      &lt;port name="SnakeServiceSoap" binding="s0:SnakeServiceSoap"&gt;       &lt;port name="SnakeServiceSoap" binding="s0:SnakeServiceSoap"&gt;
        &lt;soap:address         &lt;soap:address
          location="<A HREF="http://localhost/SnakeService/SnakeService.asmx">http://localhost/SnakeService/SnakeService.asmx</A>" /&gt;          location="<a href=
 "http://localhost/SnakeService/SnakeService.asmx">http://localhost/SnakeService/SnakeService.asmx</a>" /&gt;
      &lt;/port&gt;       &lt;/port&gt;
    &lt;/service&gt;     &lt;/service&gt;
 &lt;/definitions&gt;</PRE> &lt;/definitions&gt;
</pre>
<P>The most important thing to notice in this WSDL is the <TT>soapAction</TT>. In <A HREF="#77054">Example 12-15</A>, <TT>uri:SnakeScore/GetScore</TT> is defined as the identifier for the <TT>SnakeScore</TT> object's <TT>GetScore</TT> function. This identifier makes the call to this function in <A HREF="#77062">Example 12-19</A>.    <p>The most important thing to notice in this WSDL is the
<H3><A NAME="77102"></A> SOAP Call XML Formats</H3>    <tt>soapAction</tt>. In <a href="#77054">Example 12-15</a>,
<P>When .NET and  <!--INDEX SOAP:XML formats -->  <!--INDEX XML (Extensible Markup Language):SOAP call formats --> Mozilla serialize SOAP calls, they produce different XML formats. The namespace prefixes differ, and Mozilla produces more of these namespaces in its version of the SOAP message. However, the code comparison in Examples 12-16 and 12-17 mean fundamentally the same thing. Thus, .NET and Mozilla are able to communicate.    <tt>uri:SnakeScore/GetScore</tt> is defined as the identifier
    for the <tt>SnakeScore</tt> object's <tt>GetScore</tt>
Example 12-16<A NAME="77056"></A>    function. This identifier makes the call to this function in <a
<I>XML format for SOAP calls of Mozilla</I>    href="#77062">Example 12-19</a>.</p>
<PRE> &lt;env:Envelope    <h3><a name="77102"></a> SOAP Call XML Formats</h3>
    xmlns:env="<A HREF="http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</A>"    <p>When .NET and <!--INDEX SOAP:XML formats --> 
    xmlns:enc="<A HREF="http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</A>"    <!--INDEX XML (Extensible Markup Language):SOAP call formats -->
    env:encodingStyle="<A HREF="http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</A>"    Mozilla serialize SOAP calls, they produce different XML
    xmlns:xs="<A HREF="http://www.w3.org/1999/XMLSchema">http://www.w3.org/1999/XMLSchema</A>"    formats. The namespace prefixes differ, and Mozilla produces
    xmlns:xsi="<A HREF="http://www.w3.org/1999/XMLSchema-instance">http://www.w3.org/1999/XMLSchema-instance</A>"&gt;    more of these namespaces in its version of the SOAP message.
     However, the code comparison in Examples 12-16 and 12-17 mean
     fundamentally the same thing. Thus, .NET and Mozilla are able
     to communicate. Example 12-16<a name="77056"></a> <i>XML format
     for SOAP calls of Mozilla</i></p>
 <pre>
  &lt;env:Envelope
     xmlns:env="<a href=
 "http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>"
     xmlns:enc="<a href=
 "http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"
     env:encodingStyle="<a href=
 "http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"
     xmlns:xs="<a href=
 "http://www.w3.org/1999/XMLSchema">http://www.w3.org/1999/XMLSchema</a>"
     xmlns:xsi="<a href=
 "http://www.w3.org/1999/XMLSchema-instance">http://www.w3.org/1999/XMLSchema-instance</a>"&gt;
    &lt;env:Header/&gt;     &lt;env:Header/&gt;
    &lt;env:Body&gt;     &lt;env:Body&gt;
      &lt;a0:SaveScore xmlns:a0="uri:SnakeScore"&gt;       &lt;a0:SaveScore xmlns:a0="uri:SnakeScore"&gt;
Line 828  Example 12-16<A NAME="77056"></A> Line 1859  Example 12-16<A NAME="77056"></A>
        &lt;Score xsi:type="xs:string"&gt;10&lt;/Score&gt;         &lt;Score xsi:type="xs:string"&gt;10&lt;/Score&gt;
      &lt;/a0:SaveScore&gt;       &lt;/a0:SaveScore&gt;
    &lt;/env:Body&gt;     &lt;/env:Body&gt;
 &lt;/env:Envelope&gt;</PRE> &lt;/env:Envelope&gt;
</pre>
    Example 12-17<a name="77058"></a> <i>.NET format for SOAP calls
Example 12-17<A NAME="77058"></A>    of Mozilla</i> 
<I>.NET format for SOAP calls of Mozilla</I><pre>
<PRE> &lt;soap:Envelope &lt;soap:Envelope
    xmlns:xsi="<A HREF="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</A>"    xmlns:xsi="<a href=
    xmlns:xsd="<A HREF="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</A>""http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"
    xmlns:soap="<A HREF="http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</A>"&gt;    xmlns:xsd="<a href=
 "http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"
     xmlns:soap="<a href=
 "http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>"&gt;
    &lt;soap:Body&gt;     &lt;soap:Body&gt;
      &lt;SaveScore xmlns="uri:SnakeScore"&gt;       &lt;SaveScore xmlns="uri:SnakeScore"&gt;
        &lt;PlayerName&gt;EDM&lt;/PlayerName&gt;         &lt;PlayerName&gt;EDM&lt;/PlayerName&gt;
        &lt;Score&gt;10&lt;/Score&gt;         &lt;Score&gt;10&lt;/Score&gt;
      &lt;/SaveScore&gt;       &lt;/SaveScore&gt;
    &lt;/soap:Body&gt;     &lt;/soap:Body&gt;
 &lt;/soap:Envelope&gt;</PRE> &lt;/soap:Envelope&gt;
</pre>
<P>Realizing these formatting differences in Examples 12-16 and 12-17 is important because if you develop with SOAP by using .NET and Mozilla, you are bound to run across variations in your future software projects. Luckily the W3C has set a standard that Mozilla and Microsoft adheres to.    <p>Realizing these formatting differences in Examples 12-16 and
<H3><A NAME="77103"></A> Adding SnakeService SOAP to Snake</H3>    12-17 is important because if you develop with SOAP by using
<P>Developers <!--INDEX JavaScript:SOAP and -->  <!--INDEX SOAP:JavaScript and -->  use built-in methods to just write JavaScript and use SOAP easily. There is no need for enhanced privileges because nothing could affect the client adversely. However, there are some limitations on how SOAP JavaScript is used.    .NET and Mozilla, you are bound to run across variations in
<P>Mozilla sets one level of security  <!--INDEX security:SOAP and JavaScript --> with the SOAP function by requiring that the web service and the JavaScript file that makes the SOAP functions access that service be on the same domain. For example, you will not encounter problems when running everything as localhost (as shown in the examples). If you try to move the JavaScript files to mozdev.org, though, they will no longer work.    your future software projects. Luckily the W3C has set a
<P>Another limitation of the SOAP functions is that they can't be used directly in XUL documents. However, a hack, discussed in the next section, can get around this limitation.    standard that Mozilla and Microsoft adheres to.</p>
<H3><A NAME="77104"></A> Make SOAP Functions Work in XUL Documents</H3>    <h3><a name="77103"></a> Adding SnakeService SOAP to Snake</h3>
<P>The best way to  <!--INDEX SOAP:functions:XUL documents -->  <!--INDEX functions:SOAP:XUL documents -->  <!--INDEX XUL (XML-based User-interface Language):SOAP functions --> circumvent the SOAP-in-XUL-documents problem in Mozilla 1.0 (and probably 1.1) is to initially load the JavaScript file containing the SOAP functions from an HTML file, as shown in <A HREF="#77060">Example 12-18</A>.    <p>Developers <!--INDEX JavaScript:SOAP and --> 
    <!--INDEX SOAP:JavaScript and --> use built-in methods to just
Example 12-18<A NAME="77060"></A>    write JavaScript and use SOAP easily. There is no need for
<I>Preloading scores.js into cache with an HTML association</I>    enhanced privileges because nothing could affect the client
<PRE> &lt;html&gt;    adversely. However, there are some limitations on how SOAP
     JavaScript is used.</p>
     <p>Mozilla sets one level of security 
     <!--INDEX security:SOAP and JavaScript --> with the SOAP
     function by requiring that the web service and the JavaScript
     file that makes the SOAP functions access that service be on
     the same domain. For example, you will not encounter problems
     when running everything as localhost (as shown in the
     examples). If you try to move the JavaScript files to
     mozdev.org, though, they will no longer work.</p>
     <p>Another limitation of the SOAP functions is that they can't
     be used directly in XUL documents. However, a hack, discussed
     in the next section, can get around this limitation.</p>
     <h3><a name="77104"></a> Make SOAP Functions Work in XUL
     Documents</h3>
     <p>The best way to <!--INDEX SOAP:functions:XUL documents --> 
     <!--INDEX functions:SOAP:XUL documents --> 
     <!--INDEX XUL (XML-based User-interface Language):SOAP functions -->
     circumvent the SOAP-in-XUL-documents problem in Mozilla 1.0
     (and probably 1.1) is to initially load the JavaScript file
     containing the SOAP functions from an HTML file, as shown in <a
     href="#77060">Example 12-18</a>. Example 12-18<a name=
     "77060"></a> <i>Preloading scores.js into cache with an HTML
     association</i></p>
 <pre>
  &lt;html&gt;
  &lt;head&gt;   &lt;head&gt;
   &lt;script src="<A HREF="http://localhost/nss/bin/scores.js">http://localhost/nss/bin/scores.js</A>"&gt;&lt;/script&gt;   &lt;script src="<a href=
 "http://localhost/nss/bin/scores.js">http://localhost/nss/bin/scores.js</a>"&gt;&lt;/script&gt;
  &lt;/head&gt;   &lt;/head&gt;
  &lt;body&gt;   &lt;body&gt;
    &lt;script&gt;     &lt;script&gt;
 window.location.href="jar:<A HREF="http://localhost/nss/bin/snake.jar">http://localhost/nss/bin/snake.jar</A>!/scores.xul"; window.location.href="jar:<a href=
 "http://localhost/nss/bin/snake.jar">http://localhost/nss/bin/snake.jar</a>!/scores.xul";
    &lt;/script&gt;     &lt;/script&gt;
  &lt;/body&gt;   &lt;/body&gt;
 &lt;/html&gt;</PRE> &lt;/html&gt;
</pre>
<P>As stated earlier, <I>scores.js</I> (containing the SOAP functions) must exist outside the JAR file. It is loaded up into cache with this HTML document, and then the page redirects to the XUL file that has the SOAP function user interface. That JavaScript file is already loaded up in cache and will work fine.    <p>As stated earlier, <i>scores.js</i> (containing the SOAP
<P>Remember that doing this is a hack, but later versions of Mozilla that fix the SOAP-in-XUL-document problem would still not break this code.    functions) must exist outside the JAR file. It is loaded up
<H3><A NAME="77105"></A> Examining SOAP Functions for Snake</H3>    into cache with this HTML document, and then the page redirects
<P><A HREF="#77062">Example 12-19</A> shows  <!--INDEX SOAP:functions:Snake game -->  <!--INDEX functions:SOAP:Snake game -->  <!--INDEX Snake game:SOAP functions -->  <!--INDEX games:Snake:SOAP functions --> how to create two functions (<TT>SaveScore</TT> and <TT>SaveScoreResponse</TT>) to handle SOAP transactions with the previously examined .NET web service.    to the XUL file that has the SOAP function user interface. That
    JavaScript file is already loaded up in cache and will work
Example 12-19<A NAME="77062"></A>    fine.</p>
<I>SaveScore SOAP function</I>    <p>Remember that doing this is a hack, but later versions of
<PRE> const soapVersion  = 0; // Version 1.1    Mozilla that fix the SOAP-in-XUL-document problem would still
     not break this code.</p>
     <h3><a name="77105"></a> Examining SOAP Functions for
     Snake</h3>
     <p><a href="#77062">Example 12-19</a> shows 
     <!--INDEX SOAP:functions:Snake game --> 
     <!--INDEX functions:SOAP:Snake game --> 
     <!--INDEX Snake game:SOAP functions --> 
     <!--INDEX games:Snake:SOAP functions --> how to create two
     functions (<tt>SaveScore</tt> and <tt>SaveScoreResponse</tt>)
     to handle SOAP transactions with the previously examined .NET
     web service. Example 12-19<a name="77062"></a> <i>SaveScore
     SOAP function</i></p>
 <pre>
  const soapVersion  = 0; // Version 1.1
  const object       = "uri:SnakeScore";   const object       = "uri:SnakeScore";
 const transportURI = "<A HREF="http://localhost/SnakeService/SnakeService.asmx">http://localhost/SnakeService/SnakeService.asmx</A>"; const transportURI = "<a href=
 "http://localhost/SnakeService/SnakeService.asmx">http://localhost/SnakeService/SnakeService.asmx</a>";
  // SAVE PLAYER SCORE   // SAVE PLAYER SCORE
   
  function SaveScore( )   function SaveScore( )
  {   {
    var Score = window.opener.document.getElementById("currentscore").getAttribute("value");     var Score = window.opener.document.getElementById("currentscore").getAttribute("value");
Line 897  Example 12-19<A NAME="77062"></A> Line 1972  Example 12-19<A NAME="77062"></A>
    // Display confirmation     // Display confirmation
    // Part of content of SOAP message returned     // Part of content of SOAP message returned
    alert(resp.body.firstChild.firstChild.firstChild.data);     alert(resp.body.firstChild.firstChild.firstChild.data);
 }</PRE> }
</pre>
<P>The <TT>object</TT> defined here is the same as the namespace defined in <A HREF="#77052">Example 12-14</A>. Again, this snake score object (<TT>uri:SnakeScore</TT>) is simply an identifier to that exact web service. The <TT>transportURI</TT> is the location of the web service. As you can see here, it runs localhost along with the files for the Snake remote Mozilla application. Moving into the actual <TT>SaveScore</TT> function, a <TT>PlayerName</TT> is pulled from a <TT>&lt;textbox&gt;</TT> in the XUL.    <p>The <tt>object</tt> defined here is the same as the
<P>The <TT>method</TT> is the name of the function in the .NET web service with which this code will communicate. <TT>headers</TT> is an empty array because no SOAP headers are needed for this simple example. Two <TT>SOAPParameter</TT>s are also defined here in an array, and they are just simple strings. Moving on down the code in <A HREF="#77062">Example 12-19</A>, a new <TT>SOAPCall( )</TT> is defined into the call variable. Two URIs are set up for this <TT>SOAPCall</TT> object: <TT>call.transportURI</TT> and <TT>call.actionURI</TT>, which combines an object and a method into one string. The next two lines, <TT>encode</TT> and <TT>asyncInvoke</TT> the <TT>SOAPCall</TT> and the encoded XML message, as shown in Examples <A HREF="#77056">12-16</A> and <A HREF="#77058">12-17</A>, are sent to the .NET web service. When a response is received, the <TT>SaveScoreResponse</TT> function is called.    namespace defined in <a href="#77052">Example 12-14</a>. Again,
<P>Currently, a hack is used in <TT>SaveScoreResponse</TT> so a DOM property accesses the XML of the returned SOAP message. This implementation is not the best way, but the optimal way doesn't currently work. Here is an easy version of the code:    this snake score object (<tt>uri:SnakeScore</tt>) is simply an
<PRE>ret = resp.getParameters(false, new Array( ));    identifier to that exact web service. The <tt>transportURI</tt>
alert(ret[0]);</PRE>    is the location of the web service. As you can see here, it
<P>If you put this code in <TT>SaveScoreResponse</TT> and it works, it could replace the code in Examples 12-16 and 12-17. You need to play around with these different SOAP functions and see what works for you. Again, the code just shown does not work in Mozilla 1.0, but will hopefully work in all future versions of Mozilla.    runs localhost along with the files for the Snake remote
<P><A HREF="#77064">Example 12-20</A> shows the code for GetResponse and GetHighScores. Compare the JavaScript code to the code and WSDL in Examples 12-14 and 12-15 to see how they all work together.    Mozilla application. Moving into the actual <tt>SaveScore</tt>
    function, a <tt>PlayerName</tt> is pulled from a
Example 12-20<A NAME="77064"></A>    <tt>&lt;textbox&gt;</tt> in the XUL.</p>
<I>Code for GetScore and GetHighScores</I>    <p>The <tt>method</tt> is the name of the function in the .NET
<PRE> // GET PLAYER SCORE    web service with which this code will communicate.
     <tt>headers</tt> is an empty array because no SOAP headers are
     needed for this simple example. Two <tt>SOAPParameter</tt>s are
     also defined here in an array, and they are just simple
     strings. Moving on down the code in <a href="#77062">Example
     12-19</a>, a new <tt>SOAPCall( )</tt> is defined into the call
     variable. Two URIs are set up for this <tt>SOAPCall</tt>
     object: <tt>call.transportURI</tt> and <tt>call.actionURI</tt>,
     which combines an object and a method into one string. The next
     two lines, <tt>encode</tt> and <tt>asyncInvoke</tt> the
     <tt>SOAPCall</tt> and the encoded XML message, as shown in
     Examples <a href="#77056">12-16</a> and <a href=
     "#77058">12-17</a>, are sent to the .NET web service. When a
     response is received, the <tt>SaveScoreResponse</tt> function
     is called.</p>
     <p>Currently, a hack is used in <tt>SaveScoreResponse</tt> so a
     DOM property accesses the XML of the returned SOAP message.
     This implementation is not the best way, but the optimal way
     doesn't currently work. Here is an easy version of the
     code:</p>
 <pre>
 ret = resp.getParameters(false, new Array( ));
 alert(ret[0]);
 </pre>
     <p>If you put this code in <tt>SaveScoreResponse</tt> and it
     works, it could replace the code in Examples 12-16 and 12-17.
     You need to play around with these different SOAP functions and
     see what works for you. Again, the code just shown does not
     work in Mozilla 1.0, but will hopefully work in all future
     versions of Mozilla.</p>
     <p><a href="#77064">Example 12-20</a> shows the code for
     GetResponse and GetHighScores. Compare the JavaScript code to
     the code and WSDL in Examples 12-14 and 12-15 to see how they
     all work together. Example 12-20<a name="77064"></a> <i>Code
     for GetScore and GetHighScores</i></p>
 <pre>
  // GET PLAYER SCORE
  var ScoreElement; // Make this accessible to GetScoreResponse   var ScoreElement; // Make this accessible to GetScoreResponse
  function GetScore( )   function GetScore( )
  {   {
Line 944  Example 12-20<A NAME="77064"></A> Line 2055  Example 12-20<A NAME="77064"></A>
  function GetHighScoresResponse(resp,call,status)   function GetHighScoresResponse(resp,call,status)
  {   {
    alert(resp.body.firstChild.firstChild.firstChild.data);     alert(resp.body.firstChild.firstChild.firstChild.data);
 }</PRE> }
</pre>
<P><A HREF="#77020">Figure 12-10</A> shows how the XUL interface to these functions in <A HREF="#77064">Example 12-20</A> is designed. Here the score is replaced with "990," as this number is pulled from the code shown in <A HREF="#77052">Example 12-14</A>.    <p><a href="#77020">Figure 12-10</a> shows how the XUL
<P><CENTER><IMG SRC="foo.gif"></CENTER>    interface to these functions in <a href="#77064">Example
Figure 12-10<A NAME="77020"></A>    12-20</a> is designed. Here the score is replaced with "990,"
<I>Result of using the GetScore function</I>    as this number is pulled from the code shown in <a href=
    "#77052">Example 12-14</a>.</p>
<H2><A NAME="77106"></A> Looking Forward</H2>    <div class="c25">
<P>This chapter focuses on just one of many new trends outside of the original project mandate that emerged in the Mozilla developer community. Now that Mozilla 1.0 is released, its future direction will be shaped by the community itself, and Mozilla will become whatever the community would like it to be.      <img src="foo.gif">
<P>Remote applications are definitely one area of Mozilla development that will get more attention as Mozilla matures. Other areas that will     </div>
probably also be noticed include development tools (some existing development tools are discussed in <A HREF="appb.html#78077">Appendix B</A>), embedding, SVG support, and XSLT support.    Figure 12-10<a name="77020"></a> <i>Result of using the
<P>Remember that Mozilla is open to new ideas and is always looking for contributions. If you can think of a way to improve Mozilla, or if you think of something that should be added, become a part of the community and help expand the possibilities of Mozilla and all Mozilla applications.    GetScore function</i> 
<HR><BR><BR>    <h2><a name="77106"></a> Looking Forward</h2>
File a <a href="http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a> for chapter 12.    <p>This chapter focuses on just one of many new trends outside
<!-- ?php require(NOTES); ? -->    of the original project mandate that emerged in the Mozilla
<?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch12'; require(NOTES); ?>    developer community. Now that Mozilla 1.0 is released, its
</BODY>    future direction will be shaped by the community itself, and
</HTML>    Mozilla will become whatever the community would like it to
     be.</p>
     <p>Remote applications are definitely one area of Mozilla
     development that will get more attention as Mozilla matures.
     Other areas that will probably also be noticed include
     development tools (some existing development tools are
     discussed in <a href="appb.html#78077">Appendix B</a>),
     embedding, SVG support, and XSLT support.</p>
     <p>Remember that Mozilla is open to new ideas and is always
     looking for contributions. If you can think of a way to improve
     Mozilla, or if you think of something that should be added,
     become a part of the community and help expand the
     possibilities of Mozilla and all Mozilla applications.</p>
     <hr>
     <br>
     <br>
     File a <a href=
     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
     for chapter 12. <!-- ?php require(NOTES); ? -->
     <?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch12'; require(NOTES); ?>

Removed from v.1.8  
changed lines
  Added in v.1.9


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