Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=430351
5 -->
6 <head>
7 <title>Test for Bug 430351</title>
8 <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
9 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10 <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
12 </head>
13 <body>
14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430351">Mozilla Bug 430351</a>
15 <p id="display"></p>
16 <div id="content">
17 <div id="parent"></div>
18 <div id="editableParent" contenteditable="true"></div>
19 <iframe id="frame"></iframe>
20 <map name="map"><area></map>
21 </div>
22 <pre id="test">
23 <script class="testbody" type="text/javascript">
25 /** Test for Bug 430351 **/
27 var focusableElements = [
28 "<a tabindex=\"-1\"></a>",
29 "<a tabindex=\"0\"></a>",
30 "<a tabindex=\"0\" disabled></a>",
31 "<a tabindex=\"1\"></a>",
32 "<a contenteditable=\"true\"></a>",
34 "<a href=\"#\"></a>",
35 "<a href=\"#\" tabindex=\"-1\"></a>",
36 "<a href=\"#\" tabindex=\"0\"></a>",
37 "<a href=\"#\" tabindex=\"0\" disabled></a>",
38 "<a href=\"#\" tabindex=\"1\"></a>",
39 "<a href=\"#\" contenteditable=\"true\"></a>",
40 "<a href=\"#\" disabled></a>",
42 "<button></button>",
43 "<button tabindex=\"-1\"></button>",
44 "<button tabindex=\"0\"></button>",
45 "<button tabindex=\"1\"></button>",
46 "<button contenteditable=\"true\"></button>",
48 "<button type=\"reset\"></button>",
49 "<button type=\"reset\" tabindex=\"-1\"></button>",
50 "<button type=\"reset\" tabindex=\"0\"></button>",
51 "<button type=\"reset\" tabindex=\"1\"></button>",
52 "<button type=\"reset\" contenteditable=\"true\"></button>",
54 "<button type=\"submit\"></button>",
55 "<button type=\"submit\" tabindex=\"-1\"></button>",
56 "<button type=\"submit\" tabindex=\"0\"></button>",
57 "<button type=\"submit\" tabindex=\"1\"></button>",
58 "<button type=\"submit\" contenteditable=\"true\"></button>",
60 "<div tabindex=\"-1\"></div>",
61 "<div tabindex=\"0\"></div>",
62 "<div tabindex=\"1\"></div>",
63 "<div contenteditable=\"true\"></div>",
64 "<div tabindex=\"0\" disabled></div>",
66 "<embed>",
67 "<embed tabindex=\"-1\">",
68 "<embed tabindex=\"0\">",
69 "<embed tabindex=\"0\" disabled>",
70 "<embed tabindex=\"1\">",
71 "<embed disabled>",
72 "<embed contenteditable=\"true\">",
74 "<iframe contenteditable=\"true\"></iframe>",
76 "<iframe src=\"about:blank\"></iframe>",
77 "<iframe src=\"about:blank\" disabled></iframe>",
78 "<iframe src=\"about:blank\" tabindex=\"-1\"></iframe>",
79 "<iframe src=\"about:blank\" tabindex=\"0\"></iframe>",
80 "<iframe src=\"about:blank\" tabindex=\"0\" disabled></iframe>",
81 "<iframe src=\"about:blank\" tabindex=\"1\"></iframe>",
82 "<iframe src=\"about:blank\" contenteditable=\"true\"></iframe>",
84 "<iframe></iframe>",
85 "<iframe tabindex=\"-1\"></iframe>",
86 "<iframe tabindex=\"0\"></iframe>",
87 "<iframe tabindex=\"0\" disabled></iframe>",
88 "<iframe tabindex=\"1\"></iframe>",
89 "<iframe disabled></iframe>",
91 "<img tabindex=\"-1\">",
92 "<img tabindex=\"0\">",
93 "<img tabindex=\"0\" disabled>",
94 "<img tabindex=\"1\">",
96 "<input>",
97 "<input tabindex=\"-1\">",
98 "<input tabindex=\"0\">",
99 "<input tabindex=\"1\">",
100 "<input contenteditable=\"true\">",
102 "<input type=\"button\">",
103 "<input type=\"button\" tabindex=\"-1\">",
104 "<input type=\"button\" tabindex=\"0\">",
105 "<input type=\"button\" tabindex=\"1\">",
106 "<input type=\"button\" contenteditable=\"true\">",
108 "<input type=\"checkbox\">",
109 "<input type=\"checkbox\" tabindex=\"-1\">",
110 "<input type=\"checkbox\" tabindex=\"0\">",
111 "<input type=\"checkbox\" tabindex=\"1\">",
112 "<input type=\"checkbox\" contenteditable=\"true\">",
114 "<input type=\"image\">",
115 "<input type=\"image\" tabindex=\"-1\">",
116 "<input type=\"image\" tabindex=\"0\">",
117 "<input type=\"image\" tabindex=\"1\">",
118 "<input type=\"image\" contenteditable=\"true\">",
120 "<input type=\"password\">",
121 "<input type=\"password\" tabindex=\"-1\">",
122 "<input type=\"password\" tabindex=\"0\">",
123 "<input type=\"password\" tabindex=\"1\">",
124 "<input type=\"password\" contenteditable=\"true\">",
126 "<input type=\"radio\">",
127 "<input type=\"radio\" tabindex=\"-1\">",
128 "<input type=\"radio\" tabindex=\"0\">",
129 "<input type=\"radio\" tabindex=\"1\">",
130 "<input type=\"radio\" contenteditable=\"true\">",
131 "<input type=\"radio\" checked>",
132 "<form><input type=\"radio\" name=\"foo\"></form>",
134 "<input type=\"reset\">",
135 "<input type=\"reset\" tabindex=\"-1\">",
136 "<input type=\"reset\" tabindex=\"0\">",
137 "<input type=\"reset\" tabindex=\"1\">",
138 "<input type=\"reset\" contenteditable=\"true\">",
140 "<input type=\"submit\">",
141 "<input type=\"submit\" tabindex=\"-1\">",
142 "<input type=\"submit\" tabindex=\"0\">",
143 "<input type=\"submit\" tabindex=\"1\">",
144 "<input type=\"submit\" contenteditable=\"true\">",
146 "<input type=\"text\">",
147 "<input type=\"text\" tabindex=\"-1\">",
148 "<input type=\"text\" tabindex=\"0\">",
149 "<input type=\"text\" tabindex=\"1\">",
150 "<input type=\"text\" contenteditable=\"true\">",
152 "<input type=\"number\">",
153 "<input type=\"number\" tabindex=\"-1\">",
154 "<input type=\"number\" tabindex=\"0\">",
155 "<input type=\"number\" tabindex=\"1\">",
156 "<input type=\"number\" contenteditable=\"true\">",
158 "<object tabindex=\"-1\"></object>",
159 "<object tabindex=\"0\"></object>",
160 "<object tabindex=\"1\"></object>",
161 "<object contenteditable=\"true\"></object>",
163 "<object classid=\"java:a\"></object>",
164 "<object classid=\"java:a\" tabindex=\"-1\"></object>",
165 "<object classid=\"java:a\" tabindex=\"0\"></object>",
166 "<object classid=\"java:a\" tabindex=\"0\" disabled></object>",
167 "<object classid=\"java:a\" tabindex=\"1\"></object>",
168 "<object classid=\"java:a\" disabled></object>",
169 "<object classid=\"java:a\" contenteditable=\"true\"></object>",
171 "<select></select>",
172 "<select tabindex=\"-1\"></select>",
173 "<select tabindex=\"0\"></select>",
174 "<select tabindex=\"1\"></select>",
175 "<select contenteditable=\"true\"></select>",
177 "<option tabindex='-1'></option>",
178 "<option tabindex='0'></option>",
179 "<option tabindex='1'></option>",
180 "<option contenteditable></option>",
182 "<optgroup tabindex='-1'></optgroup>",
183 "<optgroup tabindex='0'></optgroup>",
184 "<optgroup tabindex='1'></optgroup>",
185 "<optgroup contenteditable></optgroup>"
186 ];
188 var nonFocusableElements = [
189 "<a></a>",
190 "<a disabled></a>",
192 "<button tabindex=\"0\" disabled></button>",
193 "<button disabled></button>",
195 "<button type=\"reset\" tabindex=\"0\" disabled></button>",
196 "<button type=\"reset\" disabled></button>",
198 "<button type=\"submit\" tabindex=\"0\" disabled></button>",
199 "<button type=\"submit\" disabled></button>",
201 "<div></div>",
202 "<div disabled></div>",
204 "<img>",
205 "<img disabled>",
206 "<img contenteditable=\"true\">",
208 "<img usemap=\"#map\">",
209 "<img usemap=\"#map\" tabindex=\"-1\">",
210 "<img usemap=\"#map\" tabindex=\"0\">",
211 "<img usemap=\"#map\" tabindex=\"0\" disabled>",
212 "<img usemap=\"#map\" tabindex=\"1\">",
213 "<img usemap=\"#map\" disabled>",
214 "<img usemap=\"#map\" contenteditable=\"true\">",
216 "<input tabindex=\"0\" disabled>",
217 "<input disabled>",
219 "<input type=\"button\" tabindex=\"0\" disabled>",
220 "<input type=\"button\" disabled>",
222 "<input type=\"checkbox\" tabindex=\"0\" disabled>",
223 "<input type=\"checkbox\" disabled>",
225 "<input type=\"file\" tabindex=\"0\" disabled>",
226 "<input type=\"file\" disabled>",
228 "<input type=\"hidden\">",
229 "<input type=\"hidden\" tabindex=\"-1\">",
230 "<input type=\"hidden\" tabindex=\"0\">",
231 "<input type=\"hidden\" tabindex=\"0\" disabled>",
232 "<input type=\"hidden\" tabindex=\"1\">",
233 "<input type=\"hidden\" disabled>",
234 "<input type=\"hidden\" contenteditable=\"true\">",
236 "<input type=\"image\" tabindex=\"0\" disabled>",
237 "<input type=\"image\" disabled>",
239 "<input type=\"password\" tabindex=\"0\" disabled>",
240 "<input type=\"password\" disabled>",
242 "<input type=\"radio\" tabindex=\"0\" disabled>",
243 "<input type=\"radio\" disabled>",
245 "<input type=\"reset\" tabindex=\"0\" disabled>",
246 "<input type=\"reset\" disabled>",
248 "<input type=\"submit\" tabindex=\"0\" disabled>",
249 "<input type=\"submit\" disabled>",
251 "<input type=\"text\" tabindex=\"0\" disabled>",
252 "<input type=\"text\" disabled>",
254 "<object></object>",
256 "<select tabindex=\"0\" disabled></select>",
257 "<select disabled></select>",
259 "<option></option>",
260 "<option tabindex='1' disabled></option>",
262 "<optgroup></optgroup>",
263 "<optgroup tabindex='1' disabled></optgroup>"
264 ];
266 var focusableInContentEditable = [
267 "<button></button>",
268 "<button tabindex=\"-1\"></button>",
269 "<button tabindex=\"0\"></button>",
270 "<button tabindex=\"1\"></button>",
271 "<button contenteditable=\"true\"></button>",
273 "<button type=\"reset\"></button>",
274 "<button type=\"reset\" tabindex=\"-1\"></button>",
275 "<button type=\"reset\" tabindex=\"0\"></button>",
276 "<button type=\"reset\" tabindex=\"1\"></button>",
277 "<button type=\"reset\" contenteditable=\"true\"></button>",
279 "<button type=\"submit\"></button>",
280 "<button type=\"submit\" tabindex=\"-1\"></button>",
281 "<button type=\"submit\" tabindex=\"0\"></button>",
282 "<button type=\"submit\" tabindex=\"1\"></button>",
283 "<button type=\"submit\" contenteditable=\"true\"></button>",
285 "<div tabindex=\"-1\"></div>",
286 "<div tabindex=\"0\"></div>",
287 "<div tabindex=\"1\"></div>",
288 "<div tabindex=\"0\" disabled></div>",
290 "<embed>",
291 "<embed tabindex=\"-1\">",
292 "<embed tabindex=\"0\">",
293 "<embed tabindex=\"0\" disabled>",
294 "<embed tabindex=\"1\">",
295 "<embed disabled>",
296 "<embed contenteditable=\"true\">",
298 "<iframe src=\"about:blank\"></iframe>",
299 "<iframe></iframe>",
300 "<iframe src=\"about:blank\" disabled></iframe>",
301 "<iframe disabled></iframe>",
302 "<iframe src=\"about:blank\" tabindex=\"-1\"></iframe>",
303 "<iframe tabindex=\"-1\"></iframe>",
304 "<iframe src=\"about:blank\" tabindex=\"0\"></iframe>",
305 "<iframe tabindex=\"0\"></iframe>",
306 "<iframe src=\"about:blank\" tabindex=\"0\" disabled></iframe>",
307 "<iframe tabindex=\"0\" disabled></iframe>",
308 "<iframe src=\"about:blank\" tabindex=\"1\"></iframe>",
309 "<iframe tabindex=\"1\"></iframe>",
310 "<iframe src=\"about:blank\" contenteditable=\"true\"></iframe>",
311 "<iframe contenteditable=\"true\"></iframe>",
313 "<img tabindex=\"-1\">",
314 "<img tabindex=\"0\">",
315 "<img tabindex=\"0\" disabled>",
316 "<img tabindex=\"1\">",
318 "<input>",
319 "<input tabindex=\"-1\">",
320 "<input tabindex=\"0\">",
321 "<input tabindex=\"1\">",
322 "<input contenteditable=\"true\">",
324 "<input type=\"button\">",
325 "<input type=\"button\" tabindex=\"-1\">",
326 "<input type=\"button\" tabindex=\"0\">",
327 "<input type=\"button\" tabindex=\"1\">",
328 "<input type=\"button\" contenteditable=\"true\">",
330 "<input type=\"file\">",
331 "<input type=\"file\" tabindex=\"-1\">",
332 "<input type=\"file\" tabindex=\"0\">",
333 "<input type=\"file\" tabindex=\"1\">",
334 "<input type=\"file\" contenteditable=\"true\">",
336 "<input type=\"checkbox\">",
337 "<input type=\"checkbox\" tabindex=\"-1\">",
338 "<input type=\"checkbox\" tabindex=\"0\">",
339 "<input type=\"checkbox\" tabindex=\"1\">",
340 "<input type=\"checkbox\" contenteditable=\"true\">",
342 "<input type=\"image\">",
343 "<input type=\"image\" tabindex=\"-1\">",
344 "<input type=\"image\" tabindex=\"0\">",
345 "<input type=\"image\" tabindex=\"1\">",
346 "<input type=\"image\" contenteditable=\"true\">",
348 "<input type=\"password\">",
349 "<input type=\"password\" tabindex=\"-1\">",
350 "<input type=\"password\" tabindex=\"0\">",
351 "<input type=\"password\" tabindex=\"1\">",
352 "<input type=\"password\" contenteditable=\"true\">",
354 "<input type=\"radio\">",
355 "<input type=\"radio\" tabindex=\"-1\">",
356 "<input type=\"radio\" tabindex=\"0\">",
357 "<input type=\"radio\" tabindex=\"1\">",
358 "<input type=\"radio\" contenteditable=\"true\">",
359 "<input type=\"radio\" checked>",
360 "<form><input type=\"radio\" name=\"foo\"></form>",
362 "<input type=\"reset\">",
363 "<input type=\"reset\" tabindex=\"-1\">",
364 "<input type=\"reset\" tabindex=\"0\">",
365 "<input type=\"reset\" tabindex=\"1\">",
366 "<input type=\"reset\" contenteditable=\"true\">",
368 "<input type=\"submit\">",
369 "<input type=\"submit\" tabindex=\"-1\">",
370 "<input type=\"submit\" tabindex=\"0\">",
371 "<input type=\"submit\" tabindex=\"1\">",
372 "<input type=\"submit\" contenteditable=\"true\">",
374 "<input type=\"text\">",
375 "<input type=\"text\" tabindex=\"-1\">",
376 "<input type=\"text\" tabindex=\"0\">",
377 "<input type=\"text\" tabindex=\"1\">",
378 "<input type=\"text\" contenteditable=\"true\">",
380 "<input type=\"number\">",
381 "<input type=\"number\" tabindex=\"-1\">",
382 "<input type=\"number\" tabindex=\"0\">",
383 "<input type=\"number\" tabindex=\"1\">",
384 "<input type=\"number\" contenteditable=\"true\">",
386 "<object tabindex=\"-1\"></object>",
387 "<object tabindex=\"0\"></object>",
388 "<object tabindex=\"1\"></object>",
390 // Disabled doesn't work for <object>.
391 "<object tabindex=\"0\" disabled></object>",
392 "<object disabled></object>",
394 "<select></select>",
395 "<select tabindex=\"-1\"></select>",
396 "<select tabindex=\"0\"></select>",
397 "<select tabindex=\"1\"></select>",
398 "<select contenteditable=\"true\"></select>",
400 "<option tabindex='-1'></option>",
401 "<option tabindex='0'></option>",
402 "<option tabindex='1'></option>",
404 "<optgroup tabindex='-1'></optgroup>",
405 "<optgroup tabindex='0'></optgroup>",
406 "<optgroup tabindex='1'></optgroup>"
407 ];
409 var focusableInDesignMode = [
410 "<embed>",
411 "<embed tabindex=\"-1\">",
412 "<embed tabindex=\"0\">",
413 "<embed tabindex=\"0\" disabled>",
414 "<embed tabindex=\"1\">",
415 "<embed disabled>",
416 "<embed contenteditable=\"true\">",
418 "<img tabindex=\"-1\">",
419 "<img tabindex=\"0\">",
420 "<img tabindex=\"0\" disabled>",
421 "<img tabindex=\"1\">",
422 ];
424 // Can't currently test these, need a plugin.
425 var focusableElementsTODO = [
426 "<object classid=\"java:a\"></object>",
427 "<object classid=\"java:a\" tabindex=\"-1\"></object>",
428 "<object classid=\"java:a\" tabindex=\"0\"></object>",
429 "<object classid=\"java:a\" tabindex=\"0\" disabled></object>",
430 "<object classid=\"java:a\" tabindex=\"1\"></object>",
431 "<object classid=\"java:a\" disabled></object>",
432 "<object classid=\"java:a\" contenteditable=\"true\"></object>",
433 ];
435 var serializer = new XMLSerializer();
437 function testElements(parent, tags, shouldBeFocusable)
438 {
439 var focusable, errorSuffix = "";
440 if (parent.ownerDocument.designMode == "on") {
441 focusable = focusableInDesignMode;
442 errorSuffix = " in a document with designMode=on";
443 }
444 else if (parent.contentEditable == "true") {
445 focusable = focusableInContentEditable;
446 }
448 for (var tag of tags) {
449 parent.ownerDocument.body.focus();
451 if (focusableElementsTODO.indexOf(tag) > -1) {
452 todo_is(parent.ownerDocument.activeElement, parent.firstChild,
453 tag + " should be focusable" + errorSuffix);
454 continue;
455 }
457 parent.innerHTML = tag;
459 // Focus the deepest descendant.
460 var descendant = parent;
461 while ((descendant = descendant.firstChild))
462 element = descendant;
464 if (element.nodeName == "IFRAME" && element.hasAttribute("src"))
465 var foo = element.contentDocument;
467 element.focus();
469 var errorPrefix = serializer.serializeToString(element) + " in " +
470 serializer.serializeToString(parent);
472 try {
473 // Make sure activeElement doesn't point to a
474 // native anonymous element.
475 parent.ownerDocument.activeElement.localName;
476 } catch (ex) {
477 ok(false, ex + errorPrefix + errorSuffix);
478 }
479 if (focusable ? focusable.indexOf(tag) > -1 : shouldBeFocusable) {
480 is(parent.ownerDocument.activeElement, element,
481 errorPrefix + " should be focusable" + errorSuffix);
482 }
483 else {
484 isnot(parent.ownerDocument.activeElement, element,
485 errorPrefix + " should not be focusable" + errorSuffix);
486 }
488 parent.innerHTML = "";
489 }
490 }
492 function test()
493 {
494 var parent = document.getElementById("parent");
495 var editableParent = document.getElementById("editableParent");
497 testElements(parent, focusableElements, true);
498 testElements(parent, nonFocusableElements, false);
500 testElements(editableParent, focusableElements, true);
501 testElements(editableParent, nonFocusableElements, false);
503 var frame = document.getElementById("frame");
504 frame.contentDocument.body.innerHTML = document.getElementById("content").innerHTML;
505 frame.contentDocument.designMode = "on";
506 parent = frame.contentDocument.getElementById("parent");
507 editableParent = frame.contentDocument.getElementById("editableParent");
509 testElements(parent, focusableElements, false);
510 testElements(parent, nonFocusableElements, false);
512 testElements(editableParent, focusableElements, false);
513 testElements(editableParent, nonFocusableElements, false);
514 }
516 SimpleTest.waitForExplicitFinish();
517 addLoadEvent(test);
518 addLoadEvent(SimpleTest.finish);
520 </script>
521 </pre>
522 </body>
523 </html>