|
1 # This Source Code Form is subject to the terms of the Mozilla Public |
|
2 # License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
4 |
|
5 |
|
6 // A couple of classes to simplify creating observers. |
|
7 // |
|
8 // // Example1: |
|
9 // |
|
10 // function doSomething() { ... } |
|
11 // var observer = new G_ObserverWrapper(topic, doSomething); |
|
12 // someObj.addObserver(topic, observer); |
|
13 // |
|
14 // // Example2: |
|
15 // |
|
16 // function doSomething() { ... } |
|
17 // new G_ObserverServiceObserver("profile-after-change", |
|
18 // doSomething, |
|
19 // true /* run only once */); |
|
20 |
|
21 |
|
22 /** |
|
23 * This class abstracts the admittedly simple boilerplate required of |
|
24 * an nsIObserver. It saves you the trouble of implementing the |
|
25 * indirection of your own observe() function. |
|
26 * |
|
27 * @param topic String containing the topic the observer will filter for |
|
28 * |
|
29 * @param observeFunction Reference to the function to call when the |
|
30 * observer fires |
|
31 * |
|
32 * @constructor |
|
33 */ |
|
34 function G_ObserverWrapper(topic, observeFunction) { |
|
35 this.debugZone = "observer"; |
|
36 this.topic_ = topic; |
|
37 this.observeFunction_ = observeFunction; |
|
38 } |
|
39 |
|
40 /** |
|
41 * XPCOM |
|
42 */ |
|
43 G_ObserverWrapper.prototype.QueryInterface = function(iid) { |
|
44 if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIObserver)) |
|
45 return this; |
|
46 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
47 } |
|
48 |
|
49 /** |
|
50 * Invoked by the thingy being observed |
|
51 */ |
|
52 G_ObserverWrapper.prototype.observe = function(subject, topic, data) { |
|
53 if (topic == this.topic_) |
|
54 this.observeFunction_(subject, topic, data); |
|
55 } |
|
56 |
|
57 |
|
58 /** |
|
59 * This class abstracts the admittedly simple boilerplate required of |
|
60 * observing an observerservice topic. It implements the indirection |
|
61 * required, and automatically registers to hear the topic. |
|
62 * |
|
63 * @param topic String containing the topic the observer will filter for |
|
64 * |
|
65 * @param observeFunction Reference to the function to call when the |
|
66 * observer fires |
|
67 * |
|
68 * @param opt_onlyOnce Boolean indicating if the observer should unregister |
|
69 * after it has fired |
|
70 * |
|
71 * @constructor |
|
72 */ |
|
73 function G_ObserverServiceObserver(topic, observeFunction, opt_onlyOnce) { |
|
74 this.debugZone = "observerserviceobserver"; |
|
75 this.topic_ = topic; |
|
76 this.observeFunction_ = observeFunction; |
|
77 this.onlyOnce_ = !!opt_onlyOnce; |
|
78 |
|
79 this.observer_ = new G_ObserverWrapper(this.topic_, |
|
80 BindToObject(this.observe_, this)); |
|
81 this.observerService_ = Cc["@mozilla.org/observer-service;1"] |
|
82 .getService(Ci.nsIObserverService); |
|
83 this.observerService_.addObserver(this.observer_, this.topic_, false); |
|
84 } |
|
85 |
|
86 /** |
|
87 * Unregister the observer from the observerservice |
|
88 */ |
|
89 G_ObserverServiceObserver.prototype.unregister = function() { |
|
90 this.observerService_.removeObserver(this.observer_, this.topic_); |
|
91 this.observerService_ = null; |
|
92 } |
|
93 |
|
94 /** |
|
95 * Invoked by the observerservice |
|
96 */ |
|
97 G_ObserverServiceObserver.prototype.observe_ = function(subject, topic, data) { |
|
98 this.observeFunction_(subject, topic, data); |
|
99 if (this.onlyOnce_) |
|
100 this.unregister(); |
|
101 } |
|
102 |
|
103 #ifdef DEBUG |
|
104 function TEST_G_Observer() { |
|
105 if (G_GDEBUG) { |
|
106 |
|
107 var z = "observer UNITTEST"; |
|
108 G_debugService.enableZone(z); |
|
109 |
|
110 G_Debug(z, "Starting"); |
|
111 |
|
112 var regularObserverRan = 0; |
|
113 var observerServiceObserverRan = 0; |
|
114 |
|
115 function regularObserver() { |
|
116 regularObserverRan++; |
|
117 }; |
|
118 |
|
119 function observerServiceObserver() { |
|
120 observerServiceObserverRan++; |
|
121 }; |
|
122 |
|
123 var service = Cc["@mozilla.org/observer-service;1"] |
|
124 .getService(Ci.nsIObserverService); |
|
125 var topic = "google-observer-test"; |
|
126 |
|
127 var o1 = new G_ObserverWrapper(topic, regularObserver); |
|
128 service.addObserver(o1, topic, false); |
|
129 |
|
130 new G_ObserverServiceObserver(topic, |
|
131 observerServiceObserver, true /* once */); |
|
132 |
|
133 // Notifications happen synchronously, so this is easy |
|
134 service.notifyObservers(null, topic, null); |
|
135 service.notifyObservers(null, topic, null); |
|
136 |
|
137 G_Assert(z, regularObserverRan == 2, "Regular observer broken"); |
|
138 G_Assert(z, observerServiceObserverRan == 1, "ObsServObs broken"); |
|
139 |
|
140 service.removeObserver(o1, topic); |
|
141 G_Debug(z, "PASSED"); |
|
142 } |
|
143 } |
|
144 #endif |