Global Notifications
This section will describe the observer service which can be used to send notifications to any objects that are interested.
Sending Notifications
Sometimes, for large applications, you will want to communicate with other parts of your application. For instance, to notify an application component that a particular task is complete. You could notify the components directly, but that would mean that you would need to change your code whenever a new notification needs to be sent or received.
The observer service can handle this for you. A component can register with the observer service for a given topic, identified by a string name. Later, another component can signal that topic, and the observer service will call all of the components that have registered for that topic.
The observer service implements the nsIObserverService interface, and is used to register and unregister observers. The observers implement the nsIObserver interface, and are responsible for responding when a particular topic is triggered.
The observers are registered globally, meaning that they are kept available until they are either unregistered or the application exits. Note that closing the window the observer was created in does not necessarily remove it. Thus, you only need to register an observer once and it will be called even when the component is no longer using it. For this reason, you need to be careful to ensure that an observer is not registered multiple times, and that you remove it when you no longer need it.
The observer service has an addObserver method which can be used to add an observer:
var observerService =
Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(observer,"my-topic",false);
First, the observer service is retrieved using the getService method. The addObserver method takes three arguments. The first is the observer object, which implements the nsIObserver interface. This will be defined below. The text "my-topic" is the topic to listen to. When that topic is triggered, any observers that have been registered for that topic will be invoked. The final argument indicates whether the observer service should hold a weak reference to the observer. If false, the service will hold a strong reference, ensuring that the observer is not deleted or garbage collected until it is explicitly removed from the observer service. If true, however, it might be deleted when no other references to the observer exist except from the observer service.
Above, we use false for the third argument, which will cause the observer to be called until we remove it or Mozilla exits. If it was true, the observer would likely be removed when the script that added it was unloaded.
We can remove an observer using the removeObserver function:
observerService.removeObserver(observer,"my-topic");
The two arguments are similar to the addObserver function. Note that it is possible to have an observer listen to several topics by calling addObserver multiple times.
To signal the observers of a topic, use the service's notifyObservers method. Calling this method will signal all registered observers of a given topic. Here is an example:
observerService.notifyObservers(subject,"my-topic","add");
The first argument should be any XPCOM object. This will be passed to the observers for additional information about why you are signaling them. The second argument is the topic. The third argument is a string, which can be any value. The third argument, like the subject, supplies additional information. The subject and data are not used by the observer service directly -- they are just extra values you can pass to the observers. For example, if you wanted to send a "Download Complete' notification, the subject might be a download object, and the data string might be the URL downloaded. Either value may be null if you don't need them.
The nsIObserver interface has only a single method named observe. Observers you create will need to implement this method. It will be called when the topic is signaled. For example:
var observer = {
observe: function(subject,topic,data){
alert("Topic sent: " + topic);
}
};
The arguments to the observe function are the same as with the observer service's notifyObservers function. In this example, an alert is displayed showing the topic that was sent.
Built-in Topics Used by Mozilla
The following table lists some of the topics that Mozilla uses for various purposes. You can always create your own by using a different topic name. It is recommended that you use a topic name that is unique, for example by including the application title, for topics that are specific to your application.
There are also a number of topics that are too application-specific so they are omitted from the table below.
| Topic | Subject | Data | Details |
|---|---|---|---|
| quit-application | None | None | Called when the application is exiting. Listen for this topic to perform cleanup on exit. |
| xpcom-shutdown | the nsIServiceManager | None | Called when the application is exiting. Listen for this topic to perform cleanup on exit. Unlike the 'quit-application' topic, it may be too late to perform some tasks as services have already shutdown. |
| xpcom-autoregistration | the nsIServiceManager | A string that indicates what has been registered. | Called when a component is registered or unregistered. |
| memory-pressure | an nsIMemory object | Either 'low-memory', 'alloc-failure', 'heap-minimize' | This is called when memory is low so that observers can free resources and do garbage collection and the like. It can also be called when the heapMinimize method of an object that implements nsIMemory is called. |
| perm-changed | an nsIPermission | The string 'added', 'changed', 'deleted' or 'cleared' (cleared means all permissions are removed) | A cookie or image loading permission has been changed. For example, this topic would be sent when the user selects to block an image. |
| profile-approve-change | an nsIProfile | either "startup" or "switch" or application startup and a profile change request respectively. | Called to indicate that a request has been made to select a different user profile. You can reject the change by calling vetoChange of the nsIProfileChangeStatus interface which is implemented by the profile passed as the subject. |
| profile-before-change | an nsIProfile | either "startup" or "switch" or application startup and a profile change request respectively. On shutdown, this will be either 'shutdown-cleanse' or 'shutdown-persist'. | Called to indicate that the currently selected user profile is about to change. This is also called on application exit so the observers may save settings before exiting. |
| profile-after-change | an nsIProfile | either "startup" or "switch" or application startup and a profile change request respectively. | Called to indicate that the currently selected user profile has changed. |
| prefservice:before-read-userprefs | the nsIPrefService | None | Called before the user preferences are read. |
| prefservice:before-reset | the nsIPrefService | None | Called before the user preferences are reset. |
| domwindowopened | an nsIDOMWindow (which is the same as a JavaScript window object) | None | Sent whenever a new window is opened. The is sent after the window has already opened. |
| domwindowclosed | an nsIDOMWindow (which is the same as a JavaScript window object) | None | Sent whenever a window is closed. |
| network:offline-about-to-go-offline | the nsIIOService | The string 'offline' | Called just before offline mode is enabled |
| network:offline-status-changed | the nsIIOService | Either 'online' or 'offline' depending on the new state | Called after offline mode is either enabled or disabled |
| http-on-modify-request | an nsIHttpChannel | None | Called just before an HTTP request is made. The subject contains the channel which can be modified, for example, to set additional headers. (Newer Mozilla builds only - older builds may use nsIHttpNotify) |
| http-on-examine-response | an nsIHttpChannel | None | Called when an HTTP response is available which can be modified by using the nsIHttpChannel passed as the subject. (Newer Mozilla builds only - older builds may use nsIHttpNotify) |
