|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=61098 |
|
5 --> |
|
6 <head> |
|
7 <title>Test for Bug 61098</title> |
|
8 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
9 <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> |
|
10 <script type="application/javascript" src="/tests/SimpleTest/MockObjects.js"></script> |
|
11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
12 </head> |
|
13 <body onload="runtests();"> |
|
14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=61098">Mozilla Bug 61098</a> |
|
15 <p id="display"> |
|
16 </p> |
|
17 <div id="content" style="display: none"> |
|
18 </div> |
|
19 <pre id="test"> |
|
20 </pre> |
|
21 <script class="testbody" type="text/javascript"> |
|
22 /** Test for Bug 61098 **/ |
|
23 |
|
24 SimpleTest.expectAssertions(8); |
|
25 SimpleTest.waitForExplicitFinish(); |
|
26 |
|
27 var mockPromptServiceRegisterer, mockPromptFactoryRegisterer; |
|
28 |
|
29 var promptState; |
|
30 |
|
31 function registerMockPromptService() |
|
32 { |
|
33 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); |
|
34 var XPCOMUtils = SpecialPowers.Cu.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils; |
|
35 var Ci = SpecialPowers.Ci; |
|
36 |
|
37 function MockPrompt(aDOMWindow) { |
|
38 this.domWindow = aDOMWindow; |
|
39 } |
|
40 |
|
41 MockPrompt.prototype = { |
|
42 QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]), |
|
43 |
|
44 domWindow : null, |
|
45 |
|
46 _toggleModalState: function() |
|
47 { |
|
48 // The real prompt service puts the window into a modal state |
|
49 // immediately before showing a modal prompt, and leaves the modal state |
|
50 // when the prompt is dismissed by the user. This mock prompt doesn't |
|
51 // show anything to the user, so we only need to enter and immediately |
|
52 // leave the modal state -- this is done to trigger the necessary |
|
53 // accounting for triggering the "stop showing more prompts" code for |
|
54 // abusive pages. |
|
55 var winUtils = SpecialPowers.getDOMWindowUtils(this.domWindow); |
|
56 winUtils.enterModalState(); |
|
57 winUtils.leaveModalState(); |
|
58 }, |
|
59 |
|
60 alert: function(aDialogTitle, aText) |
|
61 { |
|
62 this._toggleModalState(); |
|
63 promptState = {method: "alert", |
|
64 parent: this.domWindow, |
|
65 title: aDialogTitle, |
|
66 msg: aText |
|
67 }; |
|
68 }, |
|
69 |
|
70 alertCheck: function(aDialogTitle, aText, aCheckMsg, aCheckState) |
|
71 { |
|
72 this._toggleModalState(); |
|
73 promptState = {method: "alertCheck", |
|
74 parent: this.domWindow, |
|
75 title: aDialogTitle, |
|
76 msg: aText, |
|
77 checkMsg: aCheckMsg, |
|
78 checkState: aCheckState |
|
79 }; |
|
80 |
|
81 SpecialPowers.wrap(aCheckState).value = true; |
|
82 }, |
|
83 |
|
84 confirm: function(aDialogTitle, aText) |
|
85 { |
|
86 this._toggleModalState(); |
|
87 promptState = {method: "confirm", |
|
88 parent: this.domWindow, |
|
89 title: aDialogTitle, |
|
90 msg: aText |
|
91 }; |
|
92 |
|
93 return true; |
|
94 }, |
|
95 |
|
96 confirmCheck: function(aDialogTitle, aText, aCheckMsg, aCheckState) |
|
97 { |
|
98 this._toggleModalState(); |
|
99 promptState = {method: "confirmCheck", |
|
100 parent: this.domWindow, |
|
101 title: aDialogTitle, |
|
102 msg: aText, |
|
103 checkMsg: aCheckMsg, |
|
104 checkState: aCheckState |
|
105 }; |
|
106 |
|
107 SpecialPowers.wrap(aCheckState).value = true; |
|
108 |
|
109 return true; |
|
110 }, |
|
111 |
|
112 confirmEx: function(aDialogTitle, aText, aButtonFlags, |
|
113 aButton0Title, aButton1Title, aButton2Title, |
|
114 aCheckMsg, aCheckState) |
|
115 { |
|
116 this._toggleModalState(); |
|
117 promptState = {method: "confirmCheck", |
|
118 parent: this.domWindow, |
|
119 title: aDialogTitle, |
|
120 msg: aText, |
|
121 checkMsg: aCheckMsg, |
|
122 checkState: aCheckState |
|
123 }; |
|
124 |
|
125 if (aCheckMsg != null) |
|
126 SpecialPowers.wrap(aCheckState).value = true; |
|
127 |
|
128 return 0; |
|
129 }, |
|
130 |
|
131 prompt: function(aDialogTitle, aText, aValue, aCheckMsg, |
|
132 aCheckState) |
|
133 { |
|
134 this._toggleModalState(); |
|
135 promptState = {method: "prompt", |
|
136 parent: this.domWindow, |
|
137 title: aDialogTitle, |
|
138 msg: aText, |
|
139 checkMsg: aCheckMsg, |
|
140 checkState: aCheckState |
|
141 }; |
|
142 |
|
143 if (aCheckMsg != null) |
|
144 SpecialPowers.wrap(aCheckState).value = true; |
|
145 |
|
146 return true; |
|
147 }, |
|
148 }; |
|
149 |
|
150 |
|
151 // Override the prompt service with our own so that we can test |
|
152 // modal dialogs |
|
153 |
|
154 function MockPromptService() |
|
155 { |
|
156 } |
|
157 |
|
158 MockPromptService.prototype = { |
|
159 QueryInterface: XPCOMUtils.generateQI([Ci.nsIPromptFactory, Ci.nsIPromptService]), |
|
160 |
|
161 getPrompt: function(aDOMWindow, aIID) |
|
162 { |
|
163 return new MockPrompt(aDOMWindow); |
|
164 }, |
|
165 |
|
166 alert: function(aParent, aDialogTitle, aText) |
|
167 { |
|
168 var prompt = new MockPrompt(aParent); |
|
169 return prompt.alert(aDialogTitle, aText); |
|
170 }, |
|
171 |
|
172 alertCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) |
|
173 { |
|
174 var prompt = new MockPrompt(aParent); |
|
175 return prompt.alertCheck(aDialogTitle, aText, aCheckMsg, aCheckState); |
|
176 }, |
|
177 |
|
178 confirm: function(aParent, aDialogTitle, aText) |
|
179 { |
|
180 var prompt = new MockPrompt(aParent); |
|
181 return prompt.confirm(aDialogTitle, aText); |
|
182 }, |
|
183 |
|
184 confirmCheck: function(aParent, aDialogTitle, aText, aCheckMsg, |
|
185 aCheckState) |
|
186 { |
|
187 var prompt = new MockPrompt(aParent); |
|
188 return prompt.confirmCheck(aDialogTitle, aText, aCheckMsg, aCheckState); |
|
189 }, |
|
190 |
|
191 confirmEx: function(aParent, aDialogTitle, aText, aButtonFlags, |
|
192 aButton0Title, aButton1Title, aButton2Title, |
|
193 aCheckMsg, aCheckState) |
|
194 { |
|
195 var prompt = new MockPrompt(aParent); |
|
196 return prompt.confirmEx(aDialogTitle, aText, aButtonFlags, |
|
197 aButton0Title, aButton1Title, aButton2Title, |
|
198 aCheckMsg, aCheckState); |
|
199 }, |
|
200 |
|
201 prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, |
|
202 aCheckState) |
|
203 { |
|
204 var prompt = new MockPrompt(aParent); |
|
205 return prompt.prompt(aDialogTitle, aText, aValue, aCheckMsg, aCheckState); |
|
206 }, |
|
207 |
|
208 }; |
|
209 |
|
210 mockPromptServiceRegisterer = |
|
211 new MockObjectRegisterer("@mozilla.org/embedcomp/prompt-service;1", |
|
212 MockPromptService); |
|
213 mockPromptFactoryRegisterer = |
|
214 new MockObjectRegisterer("@mozilla.org/prompter;1", |
|
215 MockPromptService); |
|
216 |
|
217 mockPromptServiceRegisterer.register(); |
|
218 mockPromptFactoryRegisterer.register(); |
|
219 }; |
|
220 |
|
221 function enableDialogLoopBlocking() |
|
222 { |
|
223 var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]. |
|
224 getService(SpecialPowers.Ci.nsIPrefBranch); |
|
225 |
|
226 prefs.setIntPref("dom.successive_dialog_time_limit", 3); |
|
227 } |
|
228 |
|
229 function resetDialogLoopBlocking() |
|
230 { |
|
231 var prefs = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]. |
|
232 getService(SpecialPowers.Ci.nsIPrefBranch); |
|
233 |
|
234 prefs.setIntPref("dom.successive_dialog_time_limit", 0); |
|
235 } |
|
236 |
|
237 var expectedState; |
|
238 |
|
239 function runtests() |
|
240 { |
|
241 registerMockPromptService(); |
|
242 enableDialogLoopBlocking(); |
|
243 |
|
244 // Test that alert() works normally and then gets blocked on the |
|
245 // second call. |
|
246 w = window.open(); |
|
247 w.alert("alert message 1"); |
|
248 is (promptState.method, "alert", "Wrong prompt method called"); |
|
249 is (promptState.parent, w, "Wrong alert parent"); |
|
250 is (promptState.msg, "alert message 1", "Wrong alert message"); |
|
251 promptState = void(0); |
|
252 |
|
253 w.alert("alert message 2"); |
|
254 is (promptState.method, "alertCheck", "Wrong prompt method called"); |
|
255 is (promptState.parent, w, "Wrong alert parent"); |
|
256 is (promptState.msg, "alert message 2", "Wrong alert message"); |
|
257 promptState = void(0); |
|
258 |
|
259 try { |
|
260 w.alert("alert message 3"); |
|
261 } catch(e) { |
|
262 is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception"); |
|
263 } |
|
264 |
|
265 is (promptState, void(0), "Wrong prompt state after blocked alert()"); |
|
266 |
|
267 w.close(); |
|
268 |
|
269 // Test that confirm() works normally and then gets blocked on the |
|
270 // second call. |
|
271 w = window.open(); |
|
272 w.confirm("confirm message 1"); |
|
273 is (promptState.method, "confirm", "Wrong prompt method called"); |
|
274 is (promptState.parent, w, "Wrong confirm parent"); |
|
275 is (promptState.msg, "confirm message 1", "Wrong confirm message"); |
|
276 promptState = void(0); |
|
277 |
|
278 w.confirm("confirm message 2"); |
|
279 is (promptState.method, "confirmCheck", "Wrong prompt method called"); |
|
280 is (promptState.parent, w, "Wrong confirm parent"); |
|
281 is (promptState.msg, "confirm message 2", "Wrong confirm message"); |
|
282 promptState = void(0); |
|
283 |
|
284 try { |
|
285 w.confirm("confirm message 3"); |
|
286 } catch(e) { |
|
287 is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception"); |
|
288 } |
|
289 |
|
290 is (promptState, void(0), "Wrong prompt state after blocked confirm()"); |
|
291 |
|
292 w.close(); |
|
293 |
|
294 // Test that prompt() works normally and then gets blocked on the |
|
295 // second call. |
|
296 w = window.open(); |
|
297 w.prompt("prompt message 1"); |
|
298 is (promptState.method, "prompt", "Wrong prompt method called"); |
|
299 is (promptState.parent, w, "Wrong prompt parent"); |
|
300 is (promptState.msg, "prompt message 1", "Wrong prompt message"); |
|
301 is (promptState.checkMsg, null, "Wrong dialog value"); |
|
302 promptState = void(0); |
|
303 |
|
304 w.prompt("prompt message 2"); |
|
305 is (promptState.method, "prompt", "Wrong prompt method called"); |
|
306 is (promptState.parent, w, "Wrong prompt parent"); |
|
307 is (promptState.msg, "prompt message 2", "Wrong prompt message"); |
|
308 is (promptState.checkMsg, "Prevent this page from creating additional dialogs", "Wrong dialog value"); |
|
309 promptState = void(0); |
|
310 |
|
311 try { |
|
312 w.prompt("prompt message 3"); |
|
313 } catch(e) { |
|
314 is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception"); |
|
315 } |
|
316 |
|
317 is (promptState, void(0), "Wrong prompt state after blocked prompt()"); |
|
318 |
|
319 w.close(); |
|
320 |
|
321 // Test that showModalDialog() works normally and then gets blocked |
|
322 // on the second call. |
|
323 w = window.open(); |
|
324 w.showModalDialog("data:text/html,%3Cscript>window.close();%3C/script>") |
|
325 is (promptState, void(0), "Wrong prompt state"); |
|
326 |
|
327 // Test that showModalDialog() works normally and then gets blocked |
|
328 // on the second call. |
|
329 try { |
|
330 w.showModalDialog("data:text/html,%3Cscript>window.close();%3C/script>") |
|
331 } catch(e) { |
|
332 is(e.name, "NS_ERROR_NOT_AVAILABLE", "Wrong exception"); |
|
333 } |
|
334 is (promptState.method, "confirm", "Wrong prompt method called"); |
|
335 is (promptState.parent, w, "Wrong confirm parent"); |
|
336 is (promptState.msg, "Prevent this page from creating additional dialogs", |
|
337 "Wrong confirm message"); |
|
338 promptState = void(0); |
|
339 |
|
340 w.close(); |
|
341 |
|
342 resetDialogLoopBlocking(); |
|
343 |
|
344 mockPromptFactoryRegisterer.unregister(); |
|
345 mockPromptServiceRegisterer.unregister(); |
|
346 |
|
347 SimpleTest.finish(); |
|
348 } |
|
349 |
|
350 </script> |
|
351 </body> |
|
352 </html> |