|
1 <?xml version="1.0"?> |
|
2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> |
|
3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" |
|
4 type="text/css"?> |
|
5 <!-- |
|
6 https://bugzilla.mozilla.org/show_bug.cgi?id=549682 |
|
7 --> |
|
8 <window title="Mozilla Bug 549682" |
|
9 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
|
10 onload="run()"> |
|
11 <label value="Mozilla Bug 549682"/> |
|
12 <!-- test code goes here --> |
|
13 <script type="application/javascript"><![CDATA[ |
|
14 var Cc = Components.classes; |
|
15 var Ci = Components.interfaces; |
|
16 var Cr = Components.results; |
|
17 var Cu = Components.utils; |
|
18 |
|
19 var didRunAsync = false; |
|
20 var didRunLocal = false; |
|
21 |
|
22 var global = Cc["@mozilla.org/globalmessagemanager;1"] |
|
23 .getService(Components.interfaces.nsIMessageBroadcaster); |
|
24 var ppm = Cc["@mozilla.org/parentprocessmessagemanager;1"] |
|
25 .getService(Components.interfaces.nsIMessageBroadcaster); |
|
26 var cpm = Cc["@mozilla.org/childprocessmessagemanager;1"] |
|
27 .getService(Components.interfaces.nsISyncMessageSender); |
|
28 |
|
29 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
30 |
|
31 function ok(cond, msg) { |
|
32 opener.wrappedJSObject.ok(cond, msg); |
|
33 } |
|
34 |
|
35 function is(actual, expected, msg) { |
|
36 opener.wrappedJSObject.is(actual, expected, msg); |
|
37 } |
|
38 |
|
39 var asyncPPML = false; |
|
40 function ppmASL(m) { |
|
41 asyncPPML = true; |
|
42 } |
|
43 var syncPPML = false; |
|
44 function ppmSL(m) { |
|
45 syncPPML = true; |
|
46 } |
|
47 ppm.addMessageListener("processmessageAsync", ppmASL); |
|
48 ppm.addMessageListener("processmessageSync", ppmSL); |
|
49 |
|
50 cpm.sendAsyncMessage("processmessageAsync", ""); |
|
51 cpm.sendSyncMessage("processmessageSync", ""); |
|
52 |
|
53 var asyncCPML = false; |
|
54 function cpmASL(m) { |
|
55 asyncCPML = true; |
|
56 } |
|
57 cpm.addMessageListener("childprocessmessage", cpmASL); |
|
58 ppm.broadcastAsyncMessage("childprocessmessage", ""); |
|
59 |
|
60 function checkPMMMessages() { |
|
61 ok(asyncPPML, "should have handled async message"); |
|
62 ok(syncPPML, "should have handled sync message"); |
|
63 ok(asyncCPML, "should have handled async message"); |
|
64 ppm.removeMessageListener("processmessageAsync", ppmASL); |
|
65 ppm.removeMessageListener("processmessageSync", ppmSL); |
|
66 cpm.removeMessageListener("childprocessmessage", cpmASL); |
|
67 } |
|
68 |
|
69 var globalListenerCallCount = 0; |
|
70 function globalListener(m) { |
|
71 ++globalListenerCallCount; |
|
72 if (m.name == "sync") { |
|
73 global.removeMessageListener("async", globalListener); |
|
74 global.removeMessageListener("sync", globalListener); |
|
75 global.removeMessageListener("global-sync", globalListener); |
|
76 // Note, the result depends on what other windows are open. |
|
77 ok(globalListenerCallCount >= 4, |
|
78 "Global listener should have been called at least 4 times!"); |
|
79 ok(didRunLocal, "Local message received."); |
|
80 } |
|
81 } |
|
82 |
|
83 function asyncL(m) { |
|
84 didRunAsync = true; |
|
85 is(m.name, "async", "Wrong message!"); |
|
86 is(m.json.data, 1234, "Wrong data!"); |
|
87 } |
|
88 |
|
89 function syncL(m) { |
|
90 is(m.name, "sync", "Wrong message!"); |
|
91 is(m.json.data, 1234, "Wrong data!"); |
|
92 ok(didRunAsync, "Should have run async!"); |
|
93 } |
|
94 |
|
95 function localL(m) { |
|
96 is(m.name, "lasync", "Wrong message!"); |
|
97 is(m.json.data, 2345, "Wrong data!"); |
|
98 didRunLocal = true; |
|
99 } |
|
100 |
|
101 var weakMessageReceived = false; |
|
102 var weakListener = { |
|
103 QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, |
|
104 Ci.nsISupportsWeakReference]), |
|
105 |
|
106 receiveMessage: function(msg) { |
|
107 if (weakMessageReceived) { |
|
108 ok(false, 'Weak listener fired twice.'); |
|
109 return; |
|
110 } |
|
111 |
|
112 ok(true, 'Weak listener fired once.'); |
|
113 weakMessageReceived = true; |
|
114 document.getElementById('ifr').messageManager |
|
115 .removeWeakMessageListener('weak', weakListener); |
|
116 } |
|
117 }; |
|
118 |
|
119 var weakListener2 = { |
|
120 QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, |
|
121 Ci.nsISupportsWeakReference]), |
|
122 |
|
123 receiveMessage: function(msg) { |
|
124 ok(false, 'Should not have received a message.'); |
|
125 } |
|
126 }; |
|
127 |
|
128 function weakDoneListener() { |
|
129 ok(weakMessageReceived, 'Got "weak" message.'); |
|
130 finish(); |
|
131 } |
|
132 |
|
133 function finish() { |
|
134 opener.setTimeout("done()", 0); |
|
135 var i = document.getElementById("ifr"); |
|
136 i.parentNode.removeChild(i); // This is a crash test! |
|
137 window.close(); |
|
138 } |
|
139 |
|
140 function loadScript() { |
|
141 // Async should be processed first! |
|
142 messageManager.loadFrameScript("data:,\ |
|
143 sendAsyncMessage('async', { data: 1234 });\ |
|
144 sendSyncMessage('sync', { data: 1234 });\ |
|
145 sendAsyncMessage('weak', {});\ |
|
146 sendAsyncMessage('weak', {});\ |
|
147 sendAsyncMessage('weakdone', {});", false); |
|
148 } |
|
149 |
|
150 function run() { |
|
151 var localmm = document.getElementById('ifr').messageManager; |
|
152 |
|
153 var wn = document.getElementById('ifr').contentWindow |
|
154 .getInterface(Components.interfaces.nsIWebNavigation); |
|
155 ok(wn, "Should have webnavigation"); |
|
156 var cfmm = wn.getInterface(Components.interfaces.nsIContentFrameMessageManager); |
|
157 ok(cfmm, "Should have content messageManager"); |
|
158 |
|
159 var didGetSyncMessage = false; |
|
160 function syncContinueTestFn() { |
|
161 didGetSyncMessage = true; |
|
162 } |
|
163 localmm.addMessageListener("syncContinueTest", syncContinueTestFn); |
|
164 cfmm.sendSyncMessage("syncContinueTest", {}); |
|
165 localmm.removeMessageListener("syncContinueTest", syncContinueTestFn); |
|
166 ok(didGetSyncMessage, "Should have got sync message!"); |
|
167 |
|
168 localmm.addMessageListener("lasync", localL); |
|
169 localmm.loadFrameScript("data:,sendAsyncMessage('lasync', { data: 2345 })", false); |
|
170 |
|
171 messageManager.addMessageListener("async", asyncL); |
|
172 messageManager.addMessageListener("sync", syncL); |
|
173 global.addMessageListener("async", globalListener); |
|
174 global.addMessageListener("sync", globalListener); |
|
175 global.addMessageListener("global-sync", globalListener); |
|
176 global.loadFrameScript("data:,sendSyncMessage('global-sync', { data: 1234 });", true); |
|
177 var toBeRemovedScript = "data:,sendAsyncMessage('toberemoved', { data: 2345 })"; |
|
178 var c = 0; |
|
179 messageManager.addMessageListener("toberemoved", function() { |
|
180 ++c; |
|
181 is(c, 1, "Should be called only once!"); |
|
182 }); |
|
183 // This loads the script in the existing <browser> |
|
184 messageManager.loadFrameScript(toBeRemovedScript, true); |
|
185 // But it won't be loaded in the dynamically created <browser> |
|
186 messageManager.removeDelayedFrameScript(toBeRemovedScript); |
|
187 |
|
188 var oldValue = globalListenerCallCount; |
|
189 var b = document.createElement("browser"); |
|
190 b.setAttribute("type", "content"); |
|
191 document.documentElement.appendChild(b); |
|
192 is(globalListenerCallCount, oldValue + 1, |
|
193 "Wrong message count"); |
|
194 |
|
195 localmm.addWeakMessageListener('weak', weakListener); |
|
196 localmm.addMessageListener('weakdone', weakDoneListener); |
|
197 |
|
198 // Add weakListener2 as a weak message listener, then force weakListener2 |
|
199 // to be gc'ed. weakListener2 shouldn't be run. |
|
200 var weakRef = Cu.getWeakReference(weakListener2); |
|
201 localmm.addWeakMessageListener('weak', weakListener2); |
|
202 weakListener2 = null; |
|
203 |
|
204 // Force a gc/cc in a loop until weakRef's referent has gone away. |
|
205 function waitForWeakRefToDie() { |
|
206 if (weakRef.get()) { |
|
207 var mgr = Cc["@mozilla.org/memory-reporter-manager;1"] |
|
208 .getService(Ci.nsIMemoryReporterManager); |
|
209 mgr.minimizeMemoryUsage(waitForWeakRefToDie); |
|
210 |
|
211 // Print a message so that if the test hangs in a minimizeMemoryUsage |
|
212 // loop, we'll be able to see it in the log. |
|
213 ok(true, "waitForWeakRefToDie spinning..."); |
|
214 return; |
|
215 } |
|
216 |
|
217 setTimeout(checkPMMMessages, 0); |
|
218 setTimeout(loadScript, 0); |
|
219 } |
|
220 |
|
221 waitForWeakRefToDie(); |
|
222 } |
|
223 |
|
224 ]]></script> |
|
225 <browser type="content" src="about:blank" id="ifr"/> |
|
226 </window> |