Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 22 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
22
Dung lượng
48,63 KB
Nội dung
Chapter 5.ScriptingMozilla-P4 Figure 5-4. How XPConnect fits into the application model In Mozilla, XPConnect is the bridge between JavaScript and XPCOM components. The XPConnect technology wraps natively compiled components with JavaScript objects. XPCOM, Mozilla's own cross-platform component technology, is the framework on top of which these scriptable components are built. Using JavaScript and XPConnect, you can create instances of these components and use their methods and properties as you do any regular JavaScript object, as described here. You can access any or all of the functionality in Mozilla in this way. Chapter 8 describes more about the XPConnect technology and how it connects components to the interface. It also describes the components themselves and their interfaces, the XPCOM technology, and how you can create your own XPCOM components. 5.4.1.1. Creating XPCOM objects in script Example 5-10 demonstrates the creation and use of an XPCOM component in JavaScript. In this example, the script instantiates the filepicker object and then uses it to display a file picker dialog with all of the file filters selected. To run this example, add the function to your xfly.js file and call it from an event handler on the "New" menu item you added in Example 3-5 . Example 5-10. Scriptable component example // chooseApp: Open file picker and prompt user for application. chooseApp: function( ) { var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes["@mozilla.org/filepicker;1"]. createInstance( nsIFilePicker ); fp.init( this.mDialog, this.getString( "chooseAppFilePickerTitle" ), nsIFilePicker.modeOpen ); fp.appendFilters( nsIFilePicker.filterAll ); if ( fp.show( ) == nsIFilePicker.returnOK && fp.file ) { this.choseApp = true; this.chosenApp = fp.file; // Update dialog. this.updateApplicationName(this.chosenApp.unicodePa th); } Note the first two lines in the function and the way they work together to create the fp filepicker object. The first line in the function assigns the name of the nsFilepicker interface to the nsIFilePicker variable in JavaScript. This variable is used in the second line, where the instance is created from the component to specify which interface on that component should be used. Discovering and using library interfaces is an important aspect of XPCOM, where components always implement at least two interfaces. In Example 5-11 , an HTML file (stored locally, since it wouldn't have the required XPConnect access as a remote file because of security boundaries) loaded in Mozilla instantiates a Mozilla sound component and plays a sound with it. Go ahead and try it. Example 5-11. Scripting components from HTML <head> <title>Sound Service Play Example</title> <script> function play() { netscape.security.PrivilegeManager.enablePrivilege( "UniversalXPConnect"); var sample = Components.classes["@mozilla.org/sound;1"].createIn stance(); sample = sample.QueryInterface(Components.interfaces.nsISoun d); const SND_NETWORK_STD_CID = "@mozilla.org/network/standard-url;1"; const SND_I_URL = "nsIURL"; const SND_URL = new C.Constructor(SND_NETWORK_STD_CID, SND_I_URL); var url = new SND_URL(); url.spec = 'http://jslib.mozdev.org/test.wav'; sample.play(url); } </script> </head> <form name="form"> <input type="button" value="Play Sound" onclick="play();"> </form> As in Example 5-10 , the classes[ ] array on the special Mozilla Components object refers to a particular component -- in this case, the sound component -- by contract ID. All XPCOM objects must have a contract ID that uniquely identifies them with the domain, the component name, and a version number ["@mozilla.org/sound;1"], respectively. See the Section 8.1.5 section in Chapter 8 for more information about this. 5.4.1.2. Finding components and interfaces Most components are scripted in Mozilla. In fact, the challenge is not to find cases when this scripting occurs (which you can learn by searching LXR for the Components), but to find Mozilla components that don't use scriptable components. Finding components and interfaces in Mozilla and seeing how they are used can be useful when writing your own application. The Mozilla Component Viewer is a great tool for discovering components and provides a convenient UI for seeing components and looking at their interfaces from within Mozilla. The Component Viewer can be built as an extension to Mozilla (see "cview" in the extensions directory of the Mozilla source), or it can be downloaded and installed as a separate XPI from http://www.hacksrus.com/~ginda/cview/. Appendix B describes the Component Viewer in more detail. Commonly used XPCOM objects in the browser and other Mozilla applications include file objects, RDF services, URL objects, and category managers. 5.4.1.3. Selecting the appropriate interface from the component In all cases, the way to get the object into script is to instantiate it with the special classes object and use the createInstance( ) method on the class to select the interface you want to use. These two steps are often done together, as in the following example, which gets the component with the contract ID ldap-connection;1, instantiates an object from the nsILDAPConnection interface, and then calls a method on that object: var connection = Components.classes ["@mozilla.org/network/ldap- connection;1"]. createInstance(Components.interfaces.nsILDAPConnect ion); connection.init(queryURL.host, queryURL.port, null, generateGetTargetsBoundCallback( )); These two common processes -- getting a component and selecting one of its interfaces to assign to an object -- can also be separated into two different statements: // get the ldap connection component var connection = Components.classes ["@mozilla.org/network/ldap- connection;1"]; // create an object from the nsILDAPConnection interface; connection.createInstance(Components.interfaces.nsI LDAPConnection); // call the init( ) method on that object connection.init(queryURL.host, queryURL.port, null, generateGetTargetsBoundCallback( )); Mozilla constantly uses these processes. Wherever functionality is organized into XPCOM objects (and most of it is), these two statements bring that functionality into JavaScript as high-level and user-friendly JavaScript objects. 5.5. JavaScript Application Code There are two ways to use JavaScript in the third, deepest level of application programming. The first is to organize your JavaScript into libraries so your functions can be reused, distributed, and perhaps collaborated upon. 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. 5.5.1. JavaScript Libraries The open source JSLib project makes life easier for developers. The JSLib package implements some of the key XPCOM components just discussed and wraps them in simpler, JavaScript interfaces, which means that you can use the services of common XPCOM components without having to do any of the instantiation, interface selection, or glue code yourself. Collectively, these interfaces are intended to provide a general-purpose library for Mozilla application developers. To understand what JSLib does, consider the following short snippet from the JSLib source file jslib/io/file.js, which implements a close( ) function for open file objects and provides a handy way to clean up things when you finish editing a file in the filesystem. /********************* 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; [...]... examples show some ways the JSLib File object can manipulate local files Using these interfaces can make life a lot easier by letting you focus on creating your Mozilla application without having to implement XPCOM nsIFile objects manually from your script 5.5 .1.4 Using the FileUtils class To create an instance of the FileUtils class, use the FileUtils constructor: js> var fu = new FileUtils( ); js> fu;... fu.exists('/tmp/foo.dat'); true js> fu.exists('/tmp/foo.baz'); false You need to initialize the FileUtils class only once to use its members and handle local files robustly 5.5 .1.5 Using the Dir class The Dir class is custom-made for working with directory structures on a local filesystem To create an instance of the Dir class, call its constructor and then its help method to see the class properties: js>... 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." 5.5 .1.2 The JSLib libraries 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... Directory creation; variations of directory listings Class / (filename) Description Paths to useful Mozilla directories DirUtils / (dirUtils.js) and files such as chrome, prefs, bookmarks, localstore, etc 5.5 .1.3 Using the File class The JSLib File class exposes most local file routines from the nsIFile interface The File class is part of the JSLib I/O module, and is defined in jslib/io/file.js Here is how... xpcshell Most examples in this section are in xpcshell, but using these libraries in your user interface JavaScript is just as easy You can access these libraries from a XUL file, as the section Section 5.5 .1.6, later in this chapter, demonstrates xpcshell is the command-line interpreter to JavaScript and XPConnect This shell that uses XPConnect to call and instantiate scriptable XPCOM interfaces It is... the FileUtils class is spawn, which spawns an external executable from the operating system It's used as follows: js> fu.spawn('/usr/X11R6/bin/Eterm'); This command spawns a new Eterm with no argument To open an Eterm with vi, you could also use this code: js> fu.spawn('/usr/X11R6/bin/Eterm', ['e/usr/bin/vi']); Checking to see if three different files exist would take several lines when using the File... Then you can include the specific library files you need in your JavaScript code by using the include method: include("chrome://jslib/content/io/file.js"); include("chrome://jslib/content/zip/zip.js"); 5.5 .1.1 Installing JSLib 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... to the object, see if it exists, and create it if (it does not) by entering: js> d.append('newDir'); /tmp/newDir js> d.path; /tmp/newDir js> d.exists( ); false js> d.create( ); js> d.exists( ); true 5.5 .1.6 Using the DirUtils class Note that some methods in the DirUtils class cannot be called from xpcshell and instead must be called from a XUL window into which the proper JSLib source file was imported... important parameters here are -w, which enables warnings output, and -s, which turns on strict mode The source files for JSLib are well annotated and easy to read JSLib provide easy-to-use interfaces for creating instances of components (e.g., File objects), performing necessary error checking, and ensuring proper usage To use a function like the one just shown, simply include the source file you need... from xpcshell: $ /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: . Chapter 5. Scripting Mozilla- P4 Figure 5- 4. How XPConnect fits into the application model In Mozilla,. letting you focus on creating your Mozilla application without having to implement XPCOM nsIFile objects manually from your script. 5. 5.1.4. Using the FileUtils