|
1 <?xml version="1.0"?> |
|
2 <!-- This Source Code Form is subject to the terms of the Mozilla Public |
|
3 - License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
|
5 |
|
6 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> |
|
7 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
|
8 width="800" height="800" orient="vertical" onload="initRemoteFrameScript();"> |
|
9 <script> |
|
10 |
|
11 function dumpClientRect(r) { |
|
12 dump(r.left + "," + r.top + "," + r.right + "," + |
|
13 r.bottom + "," + r.width + "," + r.height + "\n"); |
|
14 } |
|
15 |
|
16 function handleMozAfterPaint(e) { |
|
17 return; |
|
18 dump(e.type + "\n") |
|
19 var rects = e.clientRects; |
|
20 var i; |
|
21 dump("\tclientRects:\n"); |
|
22 for (i = 0; i < rects.length; ++i) { |
|
23 var r = rects.item(i); |
|
24 dump("\t\t"); |
|
25 dumpClientRect(rects.item(i)); |
|
26 } |
|
27 |
|
28 dump("\tboundingClientRect\n\t\t"); |
|
29 dumpClientRect(e.boundingClientRect); |
|
30 |
|
31 var paintRequests = e.paintRequests; |
|
32 dump("\tpaintRequests\n"); |
|
33 for (i = 0; i < paintRequests.length; ++i) { |
|
34 var pr = paintRequests.item(i); |
|
35 dump("\t\t"); |
|
36 dumpClientRect(pr.clientRect); |
|
37 if (pr.reason) |
|
38 dump("\t\t" + pr.reason + "\n"); |
|
39 } |
|
40 } |
|
41 |
|
42 function handleMozScrolledAreaChanged(e) { |
|
43 return; |
|
44 dump(e.type + "\n"); |
|
45 dump("\t" + e.x + "," + e.y + "," + e.width + "," + e.height + "\n"); |
|
46 } |
|
47 |
|
48 function restart() { |
|
49 var y = document.getElementById('page'); |
|
50 var p = y.parentNode; |
|
51 p.removeChild(y); |
|
52 p.appendChild(y); |
|
53 |
|
54 var fl = y.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader; |
|
55 fl.activateFrameEvent("MozAfterPaint", true); |
|
56 fl.activateFrameEvent("MozScrolledAreaChanged", true); |
|
57 y.addEventListener("MozAfterPaint", handleMozAfterPaint, true); |
|
58 y.addEventListener("MozScrolledAreaChanged", handleMozScrolledAreaChanged, true); |
|
59 } |
|
60 |
|
61 function loadURL(url) { |
|
62 document.getElementById('page').setAttribute('src', url); |
|
63 } |
|
64 |
|
65 function randomClick() { |
|
66 // First focus the remote frame, then dispatch click. This way remote frame gets focus before |
|
67 // mouse event. |
|
68 document.getElementById('page').focus(); |
|
69 var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader; |
|
70 var x = parseInt(Math.random() * 100); |
|
71 var y = parseInt(Math.random() * 100); |
|
72 frameLoader.sendCrossProcessMouseEvent("mousedown", x, y, 0, 1, 0, false); |
|
73 frameLoader.sendCrossProcessMouseEvent("mouseup", x, y, 0, 1, 0, false); |
|
74 } |
|
75 |
|
76 function keyPress() { |
|
77 // First focus the remote frame, then dispatch click. This way remote frame gets focus before |
|
78 // mouse event. |
|
79 document.getElementById('page').focus(); |
|
80 var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader; |
|
81 |
|
82 var keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_A; |
|
83 frameLoader.sendCrossProcessKeyEvent("keydown", keyCode, 0, 0); |
|
84 frameLoader.sendCrossProcessKeyEvent("keypress", keyCode, 0, 0); |
|
85 frameLoader.sendCrossProcessKeyEvent("keyup", keyCode, 0, 0); |
|
86 } |
|
87 |
|
88 function openWindow() { |
|
89 window.open('chrome://global/content/test-ipc.xul', '_blank', 'chrome,resizable,width=800,height=800'); |
|
90 } |
|
91 |
|
92 function closeWindow() { |
|
93 window.close(); |
|
94 } |
|
95 |
|
96 function initRemoteFrameScript() { |
|
97 // 1. Test that loading a script works, and that accessing process level mm and |
|
98 // global mm works. |
|
99 var ppm = Components.classes["@mozilla.org/parentprocessmessagemanager;1"] |
|
100 .getService(Components.interfaces.nsIMessageBroadcaster); |
|
101 var gm = Components.classes["@mozilla.org/globalmessagemanager;1"] |
|
102 .getService(Components.interfaces.nsIMessageBroadcaster); |
|
103 var cpm = Components.classes["@mozilla.org/childprocessmessagemanager;1"] |
|
104 .getService(Components.interfaces.nsISyncMessageSender); |
|
105 |
|
106 if (ppm.childCount != 2) { |
|
107 alert("Should have two child processes!"); |
|
108 } |
|
109 var childprocessmm = ppm.getChildAt(1); // 0 is the in-process child process mm |
|
110 |
|
111 childprocessmm.addMessageListener("ppm-sync", |
|
112 function(m) { |
|
113 if (m.target != childprocessmm) alert("Wrong target!"); |
|
114 document.getElementById("messageLog").value += "[SYNC1 PPM]"; |
|
115 } |
|
116 ); |
|
117 |
|
118 ppm.addMessageListener("ppm-sync", |
|
119 function(m) { |
|
120 // Check that global process message manager gets the per-process mm as target. |
|
121 if (m.target != childprocessmm) alert("Wrong target!"); |
|
122 document.getElementById("messageLog").value += "[SYNC2 PPM]"; |
|
123 } |
|
124 ); |
|
125 childprocessmm.addMessageListener("ppm-async", |
|
126 function(m) { |
|
127 if (m.target != childprocessmm) alert("Wrong target!"); |
|
128 document.getElementById("messageLog").value += "[ASYNC1 PPM]"; |
|
129 } |
|
130 ); |
|
131 ppm.addMessageListener("ppm-async", |
|
132 function(m) { |
|
133 // Check that global process message manager gets the per-process mm as target. |
|
134 if (m.target != childprocessmm) alert("Wrong target!"); |
|
135 document.getElementById("messageLog").value += "[ASYNC2 PPM]"; |
|
136 } |
|
137 ); |
|
138 messageManager.loadFrameScript("chrome://global/content/remote-test-ipc.js", true); |
|
139 ppm.sendAsyncMessage("cpm-async"); |
|
140 |
|
141 // 2. Test that adding message listener works, and that receiving a sync message works. |
|
142 messageManager.addMessageListener("linkclick", |
|
143 function(m) { |
|
144 // This checks that json sending works in sync messages. |
|
145 document.getElementById("messageLog").value = m.name + ": " + m.json.href; |
|
146 return { message: "linkclick-received" }; |
|
147 }); |
|
148 |
|
149 // 3. Test that returning multiple json results works. |
|
150 messageManager.addMessageListener("linkclick", |
|
151 function(m) { |
|
152 return { message: "linkclick-received" }; |
|
153 }); |
|
154 |
|
155 // 4. Test that receiving an async message works. |
|
156 // Test also that sending async message to content works. |
|
157 // Test also that { receiveMessage: function(m) {} } works. |
|
158 messageManager.addMessageListener("linkclick-reply-object", |
|
159 { foobarObjectVar: true, |
|
160 receiveMessage: function(m) { |
|
161 var s = (m.json.message == "linkclick-received") && |
|
162 (this.foobarObjectVar) ? "PASS" : "FAIL"; |
|
163 messageManager.broadcastAsyncMessage("chrome-message", { ok : s } ); |
|
164 } |
|
165 } |
|
166 ); |
|
167 |
|
168 // 5. Final test to check that everything went ok. |
|
169 messageManager.addMessageListener("chrome-message-reply", |
|
170 function(m) { |
|
171 // Check that 'this' and .target values are handled correctly |
|
172 if (m.target == document.getElementById("page") && |
|
173 this == messageManager) { |
|
174 // Check that the message properties are enumerable. |
|
175 var hasName = false; |
|
176 var hasSync = false; |
|
177 var hasJSON = false; |
|
178 for (i in m) { |
|
179 if (i == "name") { |
|
180 hasName = true; |
|
181 } else if (i == "sync") { |
|
182 hasSync = true; |
|
183 } else if (i == "json") { |
|
184 hasJSON = true; |
|
185 } |
|
186 } |
|
187 if (hasName && hasSync && hasJSON) { |
|
188 document.getElementById("messageLog").value += ", " + m.json.ok; |
|
189 } |
|
190 } |
|
191 }); |
|
192 } |
|
193 |
|
194 var speedTestStartTime = 0; |
|
195 var speedTestCount = 0; |
|
196 function messageSpeed() { |
|
197 speedTestCount = 0; |
|
198 messageManager.addMessageListener("speed-test", speedHandler); |
|
199 messageManager.broadcastAsyncMessage("speed-test-start"); |
|
200 } |
|
201 |
|
202 function speedHandler() { |
|
203 if (!speedTestCount) { |
|
204 speedTestStartTime = new Date().getTime(); |
|
205 } |
|
206 if (++speedTestCount == 1000) { |
|
207 setTimeout("alert('" + speedTestCount + " in " + (new Date().getTime() - speedTestStartTime) + "ms')", 0); |
|
208 return { message: "done" }; |
|
209 } |
|
210 return { message: "continue" }; |
|
211 } |
|
212 |
|
213 var addRemoveTestCount = 0; |
|
214 |
|
215 function echoListener() { |
|
216 if (++addRemoveTestCount == 1) { |
|
217 alert("Expected echo message"); |
|
218 messageManager.removeMessageListener("async-echo", echoListener); |
|
219 messageManager.broadcastAsyncMessage("async-echo"); |
|
220 return; |
|
221 } |
|
222 alert("Unexpected echo message"); |
|
223 } |
|
224 |
|
225 function listenerAddRemove() { |
|
226 addRemoveTestCount = 0; |
|
227 messageManager.addMessageListener("async-echo", echoListener); |
|
228 messageManager.broadcastAsyncMessage("async-echo"); |
|
229 } |
|
230 |
|
231 var MozAfterPaintCount = 0; |
|
232 function enableMozAfterPaint() { |
|
233 messageManager.addMessageListener("MozAfterPaint", |
|
234 function(m) { |
|
235 document.getElementById("messageLog").value = m.name + "[" + (++MozAfterPaintCount) + "]"; |
|
236 }); |
|
237 messageManager.loadFrameScript("data:,addEventListener('MozAfterPaint', function(e) { sendAsyncMessage('MozAfterPaint'); },true);", false); |
|
238 } |
|
239 |
|
240 var Ci = Components.interfaces; |
|
241 var Cu = Components.utils; |
|
242 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
243 </script> |
|
244 |
|
245 <toolbar id="controls"> |
|
246 <toolbarbutton label="Back"/> |
|
247 <toolbarbutton label="Forward"/> |
|
248 <textbox onchange="loadURL(this.value)" flex="1" id="URL"/> |
|
249 </toolbar> |
|
250 <toolbar> |
|
251 <toolbarbutton onclick="restart()" label="Recover"/> |
|
252 <toolbarbutton onclick="randomClick()" label="random click"/> |
|
253 <toolbarbutton onclick="keyPress()" label="key press"/> |
|
254 <toolbarbutton onclick="messageSpeed()" label="test message handling speed"/> |
|
255 <toolbarbutton onclick="listenerAddRemove()" label="test listener add/remove"/> |
|
256 <toolbarbutton onclick="enableMozAfterPaint()" label="MozAfterPaint"/> |
|
257 <toolbarbutton onclick="openWindow()" label="open new window"/> |
|
258 <toolbarbutton onclick="closeWindow()" label="close this window"/> |
|
259 </toolbar> |
|
260 <toolbar><label value="Load a script (URL) to content process:"/> |
|
261 <textbox flex="1" id="script"/><button |
|
262 label="send" oncommand="document.getElementById('page') |
|
263 .QueryInterface(Components.interfaces.nsIFrameLoaderOwner) |
|
264 .frameLoader.messageManager |
|
265 .loadFrameScript(this.previousSibling.value, false);"/> |
|
266 </toolbar> |
|
267 <toolbar> |
|
268 <label value="Eval script in chrome context"/> |
|
269 <textbox flex="1"/><button label="run" oncommand="eval(this.previousSibling.value);"/> |
|
270 </toolbar> |
|
271 |
|
272 <browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"/> |
|
273 <label id="messageLog" value="" crop="center"/> |
|
274 </window> |