|
1 /** |
|
2 * Dispatches |handler| to |element|, as if fired in response to |event|. |
|
3 */ |
|
4 function send(element, event, handler) { |
|
5 function unique_handler() { return handler.apply(this, arguments) } |
|
6 element.addEventListener(event, unique_handler, false); |
|
7 try { sendMouseEvent({ type: event }, element.id) } |
|
8 finally { element.removeEventListener(event, unique_handler, false) } |
|
9 } |
|
10 |
|
11 /** |
|
12 * Because it's not nice to leave popup windows open after the tests are |
|
13 * finished, we need a foolproof way to close some/all window.opened windows. |
|
14 */ |
|
15 (function(originalOpen) { |
|
16 var wins = []; |
|
17 (window.open = function() { |
|
18 var win = originalOpen.apply(window, arguments); |
|
19 if (win) |
|
20 wins[wins.length] = win; |
|
21 return win; |
|
22 }).close = function(n) { |
|
23 if (arguments.length < 1) |
|
24 n = wins.length; |
|
25 while (n --> 0) { |
|
26 var win = wins.pop(); |
|
27 if (win) win.close(); |
|
28 else break; |
|
29 } |
|
30 }; |
|
31 })(window.open); |
|
32 |
|
33 function _alter_helper(uri, fn) { |
|
34 var hash_splat = uri.split("#"), |
|
35 splat = hash_splat.shift().split("/"); |
|
36 fn(splat); |
|
37 hash_splat.unshift(splat.join("/")); |
|
38 return hash_splat.join("#"); |
|
39 } |
|
40 |
|
41 function alter_host(uri, host) { |
|
42 return _alter_helper(uri, function(splat) { |
|
43 splat.splice(2, 1, host); |
|
44 }); |
|
45 } |
|
46 |
|
47 function alter_file(uri, file) { |
|
48 return _alter_helper(uri, function(splat) { |
|
49 splat[splat.length - 1] = file; |
|
50 }); |
|
51 } |
|
52 |
|
53 (function() { |
|
54 |
|
55 var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"] |
|
56 .getService(SpecialPowers.Ci.nsIPrefService), |
|
57 pm = SpecialPowers.Cc["@mozilla.org/permissionmanager;1"] |
|
58 .getService(SpecialPowers.Ci.nsIPermissionManager), |
|
59 ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"] |
|
60 .getService(SpecialPowers.Ci.nsIIOService); |
|
61 |
|
62 ALLOW_ACTION = pm.ALLOW_ACTION; |
|
63 DENY_ACTION = pm.DENY_ACTION; |
|
64 UNKNOWN_ACTION = pm.UNKNOWN_ACTION; |
|
65 |
|
66 /** |
|
67 * This ridiculously over-engineered function makes an accessor function from |
|
68 * any given preference string. Such accessors may be passed as the first |
|
69 * parameter to the |hold| function defined below. |
|
70 */ |
|
71 makePrefAccessor = function(pref) { |
|
72 var splat = pref.split('.'), |
|
73 basePref = splat.pop(), |
|
74 branch, kind; |
|
75 |
|
76 try { |
|
77 branch = prefService.getBranch(splat.join('.') + '.'); |
|
78 } catch (x) { |
|
79 alert("Calling prefService.getBranch failed: " + |
|
80 "did you forget to enable UniversalXPConnect?"); |
|
81 throw x; |
|
82 } |
|
83 |
|
84 switch (branch.getPrefType(basePref)) { |
|
85 case branch.PREF_STRING: kind = "CharPref"; break; |
|
86 case branch.PREF_INT: kind = "IntPref"; break; |
|
87 case branch.PREF_BOOL: kind = "BoolPref"; break; |
|
88 case branch.PREF_INVALID: kind = "ComplexValue"; |
|
89 } |
|
90 |
|
91 return function(value) { |
|
92 var oldValue = branch['get' + kind](basePref); |
|
93 if (arguments.length > 0) |
|
94 branch['set' + kind](basePref, value); |
|
95 return oldValue; |
|
96 }; |
|
97 }; |
|
98 |
|
99 makePopupPrivAccessor = function(uri) { |
|
100 uri = ioService.newURI(uri, null, null); |
|
101 var principal = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"] |
|
102 .getService(SpecialPowers.Ci.nsIScriptSecurityManager) |
|
103 .getNoAppCodebasePrincipal(uri); |
|
104 |
|
105 return function(permission) { |
|
106 var old = pm.testPermissionFromPrincipal(principal, "popup"); |
|
107 if (arguments.length) { |
|
108 pm.removeFromPrincipal(principal, "popup"); |
|
109 pm.addFromPrincipal(principal, "popup", permission); |
|
110 } |
|
111 return old; |
|
112 }; |
|
113 }; |
|
114 |
|
115 })(); |
|
116 |
|
117 /** |
|
118 * This function takes an accessor function, a new value, and a callback |
|
119 * function. It assigns the new value to the accessor, saving the old value, |
|
120 * then calls the callback function with the new and old values. Before |
|
121 * returning, |hold| sets the accessor back to the old value, even if the |
|
122 * callback function misbehaved (i.e., threw). |
|
123 * |
|
124 * For sanity's sake, |hold| also ensures that the accessor still has the new |
|
125 * value at the time the old value is reassigned. The accessor's value might |
|
126 * have changed to something entirely different during the execution of the |
|
127 * callback function, but it must have changed back. |
|
128 * |
|
129 * Without such a mechanism it would be very difficult to verify that these |
|
130 * tests leave the browser's preferences/privileges as they were originally. |
|
131 */ |
|
132 function hold(accessor, value, body) { |
|
133 var old_value = accessor(value); |
|
134 try { return body(value, old_value) } |
|
135 finally { |
|
136 old_value = accessor(old_value); |
|
137 if (old_value !== value) |
|
138 throw [accessor, value, old_value]; |
|
139 } |
|
140 } |