This section provides an example of using XPCOM along with some additional interfaces.
The interface nsIWindowMediator allows access to all the other open Mozilla windows. You can use this to switch the focus to other windows. The list of open windows can be used as an RDF datasource. This allows you to create a Window menu with a list of the currently open windows in the application. The datasource for this is rdf:window-mediator. We can use this as in the following example:
Example 8.2.1
<toolbox>
<menubar>
<menu value="Window">
<menupopup id="window-menu" datasources="rdf:window-mediator" ref="NC:WindowMediatorRoot">
<template>
<rule>
<menuitem uri="rdf:*" value="rdf:http://home.netscape.com/NC-rdf#Name"/>
</rule>
</template>
</menupopup>
</menu>
</menubar>
</toolbox>
|
A Window menu will be created with a list of all the open windows. Try this example by opening a number of browser windows and you'll see that they are all listed on the menu. This is fine for displaying a list of open windows, but we would like to enhance this so that clicking on the menu item will switch to that window. This is accomplished by using the nsIWindowMediator interface. This interface provides access to the list of open windows. We can use it to get a specific window and then switch the focus to it. The code below shows how to get a component which implements it:
var wmdata = Components.classes["component://netscape/rdf/datasource?name=window-mediator"].getService(); var wmediator = wmdata.QueryInterface(Components.interfaces.nsIWindowMediator); |
This code retreives a window mediator component. Note the name of the component. You can use a similar syntax to get any of the built-in datasources. The component we are using is the same one that handles the window-mediator RDF datasource. A number of functions are available via the nsIWindowMediator interface:
| getEnumerator(type) | Get an object that implements nsISimpleEnumerator which can be used to interate over a set of open windows. |
| getMostRecentWindow(type) | Returns the window that was recently used. You can specify a type to get a window of a certain type. |
| getWindowForResource(url) | Given an RDF resource, return a window described by it. This can be used to get a window from the window-mediator RDF datasource. |
| convertISupportsToDOMWindow(win) | Given a XPCOM window reference, normally returned through the window enumeration, return a JavaScript window object. |
The type parameter can be null which means windows of any type (which effectively means all windows). If you specify a type, you can filter out windows that you are not interested in. A window's type can be specified by adding a windowtype attribute to a window element. For example:
<window id="findfile-window" title="Find Files" windowtype="find-files" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> |
However, we want to use the function getWindowForResource, because we can get the resource from the datasource. In the earlier example, we generated the list of windows and added it to a menu via a template. The template generates an id attribute on each menuitem element. The value of this attribute can be used as the resource. That means that in order to switch the window focus, we need to do the following:
The example below shows how we might do this:
<menu value="Window" oncommand="switchFocus(event.target);">
function switchFocus(elem)
{
var wmdata = Components.classes["component://netscape/rdf/datasource?name=window-mediator"].getService();
var wmediator = wmdata.QueryInterface(Components.interfaces.nsIWindowMediator);
var resource = elem.getAttribute('id');
switchwindow = wmediator.getWindowForResource(resource);
if (switchwindow){
switchwindow.focus();
}
}
|
A command handler was added to the menu element which calls the function with a parameter of the element that was selected from the menu. The function switchFocus first gets a reference to a component which implements the window mediator interface. Next, we get the id attribute for the element. We can use the value of the id attribute as the resource. The function getWindowForResource takes the resource and returns a window that matches it. This window, stored in the switchwindow variable, is defined the same as the JavaScript window object. This means that you can call any of the functions provided by it, one of which is focus.
(Next) Next, we'll see the XPCOM interfaces used to manipulate RDF.
Examples: 8.2.1