The second way is to write a JavaScript component, create a separate interface for that component, and compile it as an XPCOM component whose methods and data can be accessed from XPConnect (using JavaScript). This kind of application programming is described in Chapter 8, which includes examples of creating new interfaces, implementing them in JavaScript or C++, and compiling, testing, and using the resulting component in the Mozilla interface.
This section introduces the library organization method of JavaScript application programming. The JSLib code discussed here is a group of JavaScript libraries currently being developed by Mozilla contributors and is especially useful for working with the XPFE and other aspects of the Mozilla application/package programming model. When you include the right source files at the top of your JavaScript and/or XUL file, you can use the functions defined in JSLib libraries as you would use any third-party library or built-in functions. You may even want to contribute to the JSLib project yourself if you think functionality is missing and as your Mozilla programming skills grow.
/********************* CLOSE ******************************** * void close( ) * * * * void file close * * return type void(null) * * takes no arguments closes an open file stream and * * deletes member var instances of objects * * Ex: * * var p='/tmp/foo.dat'; * * var f=new File(p); * * fopen( ); * * f.close( ); * * * * outputs: void(null) * ************************************************************/ File.prototype.close = function( ) { /***************** Destroy Instances *********************/ if(this.mFileChannel) delete this.mFileChannel; if(this.mInputStream) delete this.mInputStream; if(this.mTransport) delete this.mTransport; if(this.mMode) this.mMode=null; if(this.mOutStream) { this.mOutStream.close( ); delete this.mOutStream; } if(this.mLineBuffer) this.mLineBuffer=null; this.mPosition = 0; /***************** Destroy Instances *********************/ return; }
<script type="application/x-JavaScript" src="chrome://jslib/content/jslib.js" />
include("chrome://jslib/content/io/file.js"); include("chrome://jslib/content/zip/zip.js");
To use the JavaScript libraries, install the JSLib package in Mozilla. The package is available as a tarball, a zip file, or as CVS sources. The easiest way to obtain it is to install it from the Web using Mozilla's XPInstall technology, described in Chapter 6.
Using your Mozilla browser, go to http://jslib.mozdev.org/installation.html and click the installation hyperlink. The link uses XPInstall to install JSLIB and make it available to you in Mozilla. To test whether it is installed properly, type the following code in your shell:
./mozilla -chrome chrome://jslib/content/
You should see a simple window that says "welcome to jslib."
Currently available JavaScript functions in the JSLib package are divided into different modules that, in turn, are divided into different classes defined in source files such as file.js, dir.js, and fileUtils.js. Table 5-1 describes the basic classes in the JSLib package's I/O module and describes how they are used.
Table 5-1. JSLib classes
Class / (filename) |
Description |
---|---|
File / (file.js) |
Contains most routines associated with the File object (implementing nsIFile). The library is part of the jslib I/O module. |
FileUtils / (fileUtils.js) |
The chrome registry to local file path conversion, file metadata, etc. |
Dir / (dir.js) |
Directory creation; variations of directory listings. |
DirUtils / (dirUtils.js) |
Paths to useful Mozilla directories and files such as chrome, prefs, bookmarks, localstore, etc. |
$ ./run-mozilla.sh ./xpcshell -w -s js> load('chrome/jslib/jslib.js'); ********************* JS_LIB DEBUG IS ON ********************* js>
Once JSLib is loaded, you can load the File module with an include statement:
js> include(`chrome://jslib/content/io/file.js'); *** Chrome Registration of package: Checking for contents.rdf at resource:/chrome/jslib/ *** load: filesystem.js OK *** load: file.js OK true js>
js> include(JS_LIB_PATH+'io/file.js');
js> var f = new File('/tmp/foo'); js> f; [object Object] js> f.help; // listing of everything available to the object . . . js> f.path; /tmp/foo js> f.exists( ); // see if /tmp/foo exists false js> f.create( ); // it doesn't, so create it. js> f.exists( ); true js> f.isFile( ); // is it a file? true js> f.open('w'); // open the file for writing true js> f.write('this is line #1\n'); true js> f.close( ); js> f.open( ); // open the file again and js> f.read( ); // read back the data // you can also use default flag 'r' for reading this is line #1 js> f.close( );
js> f.open( ); true js> var contents = f.read( ); js> f.close( ); js> print(contents); this is line #1 js> // rename the file js> f.move(`/tmp/foo.dat'); foo.dat filesystem.js:move successful! js> f.path; /tmp/foo.dat
To create an instance of the FileUtils class, use the FileUtils constructor:
js> var fu = new FileUtils( ); js> fu; [object Object]
Then look at the object by calling its help method:
js> fu.help;
js> fu.exists('/tmp'); true // convert a chrome path to a url js> fu.chromeToPath('chrome://jslib/content/'); /usr/src/mozilla/dist/bin/chrome/jslib/jslib.xul // convert a file URL path to a local file path js> fu.urlToPath('file:///tmp/foo.dat'); /tmp/foo.dat
js> fu.spawn('/usr/X11R6/bin/Eterm');
js> fu.spawn('/usr/X11R6/bin/Eterm', ['-e/usr/bin/vi']);
js> var fu=new FileUtils( ); js> fu.exists('/tmp'); true js> fu.exists('/tmp/foo.dat'); true js> fu.exists('/tmp/foo.baz'); false
js> var d = new Dir('/tmp'); js> d.help;
js> d.path; /tmp js> d.exists( ); true js> d.isDir( ); true
js> d.append('newDir'); /tmp/newDir js> d.path; /tmp/newDir js> d.exists( ); false js> d.create( ); js> d.exists( ); true
<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin" type="text/css"?> <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" id="dir-utils-window" orient="vertical" autostretch="never"> <script type="application/x-javascript" src="chrome://jslib/content/io/dirUtils.js"/> <script> var du = new DirUtils( ); function getChromeDir( ) { cd = du.getChromeDir( ); textfield1 = document.getElementById("tf1"); textfield1.setAttribute("value", cd); } function getMozDir( ) { md = du.getMozHomeDir( ); textfield2 = document.getElementById("tf2"); textfield2.setAttribute("value", md); } </script> <box> <button id="chrome" onclick="getChromeDir( );" label="chrome" /> <textbox id="tf1" value="chrome dir" /> </box> <box> <button id="moz" onclick="getMozDir( );" label="mozdir" /> <textbox id="tf2" value="moz dir" /> </box> </window>