Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 <!DOCTYPE HTML>
2 <html id="html" style="height:100%">
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=780847
5 -->
6 <head>
7 <title>Test radii for mouse events</title>
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
9 <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
11 <style>
12 .target { position:absolute; left:100px; top:100px; width:100px; height:100px; background:blue; }
13 </style>
14 </head>
15 <body id="body" onload="setTimeout(startTest, 0)" style="margin:0; width:100%; height:100%; overflow:hidden">
16 <p id="display"></p>
17 <div id="content">
18 <div id="ruler" style="position:absolute; left:0; top:0; width:1mozmm; height:0;"></div>
20 <div class="target" id="t" onmousedown="x=1"></div>
22 <div class="target" id="t2" hidden></div>
24 <input class="target" id="t3_1" hidden></input>
25 <a href="#" class="target" id="t3_2" hidden></a>
26 <label class="target" id="t3_3" hidden></label>
27 <button class="target" id="t3_4" hidden></button>
28 <select class="target" id="t3_5" hidden></select>
29 <textarea class="target" id="t3_6" hidden></textarea>
30 <div role="button" class="target" id="t3_7" hidden></div>
31 <div role="key" class="target" id="t3_8" hidden></div>
32 <img class="target" id="t3_9" hidden></img>
34 <div class="target" style="transform:translate(-80px,0);" id="t4" onmousedown="x=1" hidden></div>
36 <div class="target" style="left:0; z-index:1" id="t5_left" onmousedown="x=1" hidden></div>
37 <div class="target" style="left:106px;" id="t5_right" onmousedown="x=1" hidden></div>
38 <div class="target" style="left:0; top:210px;" id="t5_below" onmousedown="x=1" hidden></div>
40 <div class="target" id="t6" onmousedown="x=1" hidden>
41 <div id="t6_inner" style="position:absolute; left:-20px; top:20px; width:60px; height:60px; background:yellow;"></div>
42 </div>
44 <div class="target" id="t7" onmousedown="x=1" hidden></div>
45 <div class="target" id="t7_over" hidden></div>
47 <div id="t8" contenteditable="true" class="target" hidden></div>
49 <div id="t9" class="target" ontouchend="x=1" hidden></div>
51 <div id="t10_left" class="target" style="left:-50px;" onmousedown="x=1" hidden></div>
52 <div id="t10_right" class="target" style="left:auto;right:-50px" onmousedown="x=1" hidden></div>
53 <div id="t10_top" class="target" style="top:-50px;" onmousedown="x=1" hidden></div>
54 <div id="t10_bottom" class="target" style="top:auto;bottom:-50px;" onmousedown="x=1" hidden></div>
55 <div id="t10_over" style="position:absolute; left:0; top:0; width:100%; height:100%; background:yellow;" hidden></div>
56 </div>
57 <pre id="test">
58 <script type="application/javascript">
59 function startTest() {
60 SpecialPowers.pushPrefEnv({"set": [["ui.mouse.radius.enabled", true],
61 ["ui.mouse.radius.inputSource.touchOnly", false],
62 ["ui.mouse.radius.leftmm", 12],
63 ["ui.mouse.radius.topmm", 8],
64 ["ui.mouse.radius.rightmm", 4],
65 ["ui.mouse.radius.bottommm", 4],
66 ["ui.mouse.radius.visitedweight", 50]]}, runTest);
67 }
70 SimpleTest.waitForExplicitFinish();
72 function endTest() {
73 SimpleTest.finish();
74 }
76 var eventTarget;
77 window.onmousedown = function(event) { eventTarget = event.target; };
79 function testMouseClick(idPosition, dx, dy, idTarget, msg, options) {
80 eventTarget = null;
81 synthesizeMouse(document.getElementById(idPosition), dx, dy, options || {});
82 try {
83 is(eventTarget.id, idTarget,
84 "checking '" + idPosition + "' offset " + dx + "," + dy + " [" + msg + "]");
85 } catch (ex) {
86 ok(false, "checking '" + idPosition + "' offset " + dx + "," + dy + " [" + msg + "]; got " + eventTarget);
87 }
88 }
90 function setShowing(id, show) {
91 var e = document.getElementById(id);
92 e.hidden = !show;
93 }
95 var mm;
96 function runTest() {
97 mm = document.getElementById("ruler").getBoundingClientRect().width;
98 ok(4*mm >= 10, "WARNING: mm " + mm + " too small in this configuration. Test results will be bogus");
100 // Test basic functionality: clicks sufficiently close to the element
101 // should be allowed to hit the element. We test points just inside and
102 // just outside the edges we set up in the prefs.
103 testMouseClick("t", 100 + 13*mm, 10, "body", "basic functionality");
104 testMouseClick("t", 100 + 11*mm, 10, "t", "basic functionality");
105 testMouseClick("t", 10, 100 + 9*mm, "body", "basic functionality");
106 testMouseClick("t", 10, 100 + 7*mm, "t", "basic functionality");
107 testMouseClick("t", -5*mm, 10, "body", "basic functionality");
108 testMouseClick("t", -3*mm, 10, "t", "basic functionality");
109 testMouseClick("t", 10, -5*mm, "body", "basic functionality");
110 testMouseClick("t", 10, -3*mm, "t", "basic functionality");
112 // When inputSource.touchOnly is true, mouse input is not retargeted.
113 SpecialPowers.pushPrefEnv({"set": [["ui.mouse.radius.inputSource.touchOnly", true]]}, test2);
114 }
116 function test2() {
117 testMouseClick("t", 100 + 11*mm, 10, "body", "disabled for mouse input");
118 testMouseClick("t", 100 + 11*mm, 10, "t", "enabled for touch input", {
119 inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH
120 });
121 testMouseClick("t", 100 + 13*mm, 10, "body", "basic functionality for touch", {
122 inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH
123 });
124 SpecialPowers.pushPrefEnv({"set": [["ui.mouse.radius.inputSource.touchOnly", false]]}, test3);
125 }
127 function test3() {
128 setShowing("t", false);
130 // Now test the criteria we use to determine which elements are hittable
131 // this way.
133 setShowing("t2", true);
134 var t2 = document.getElementById("t2");
135 // Unadorned DIVs are not click radius targets
136 testMouseClick("t2", 100 + 11*mm, 10, "body", "unadorned DIV");
137 // DIVs with the right event handlers are click radius targets
138 t2.onmousedown = function() {};
139 testMouseClick("t2", 100 + 11*mm, 10, "t2", "DIV with onmousedown");
140 t2.onmousedown = null;
141 testMouseClick("t2", 100 + 11*mm, 10, "body", "DIV with onmousedown removed");
142 t2.onmouseup = function() {};
143 testMouseClick("t2", 100 + 11*mm, 10, "t2", "DIV with onmouseup");
144 t2.onmouseup = null;
145 t2.onclick = function() {};
146 testMouseClick("t2", 100 + 11*mm, 10, "t2", "DIV with onclick");
147 t2.onclick = null;
148 // Keypresses don't make click radius targets
149 t2.onkeypress = function() {};
150 testMouseClick("t2", 100 + 11*mm, 10, "body", "DIV with onkeypress");
151 t2.onkeypress = null;
152 setShowing("t2", false);
154 // Now check that certain elements are click radius targets and others are not
155 for (var i = 1; i <= 9; ++i) {
156 var id = "t3_" + i;
157 var shouldHit = i <= 8;
158 setShowing(id, true);
159 testMouseClick(id, 100 + 11*mm, 10, shouldHit ? id : "body",
160 "<" + document.getElementById(id).tagName + "> element");
161 setShowing(id, false);
162 }
164 // Check that our targeting computations take into account the effects of
165 // CSS transforms
166 setShowing("t4", true);
167 testMouseClick("t4", -1, 10, "t4", "translated DIV");
168 setShowing("t4", false);
170 // Test the prioritization of multiple targets based on distance to
171 // the target.
172 setShowing("t5_left", true);
173 setShowing("t5_right", true);
174 setShowing("t5_below", true);
175 testMouseClick("t5_left", 102, 10, "t5_left", "closest DIV is left");
176 testMouseClick("t5_left", 102.5, 10, "t5_left",
177 "closest DIV to midpoint is left because of its higher z-index");
178 testMouseClick("t5_left", 104, 10, "t5_right", "closest DIV is right");
179 testMouseClick("t5_left", 10, 104, "t5_left", "closest DIV is left");
180 testMouseClick("t5_left", 10, 105, "t5_left",
181 "closest DIV to midpoint is left because of its higher z-index");
182 testMouseClick("t5_left", 10, 106, "t5_below", "closest DIV is below");
183 setShowing("t5_left", false);
184 setShowing("t5_right", false);
185 setShowing("t5_below", false);
187 // Test behavior of nested elements.
188 // The following behaviors are questionable and may need to be changed.
189 setShowing("t6", true);
190 testMouseClick("t6_inner", -1, 10, "t6_inner",
191 "inner element is clickable because its parent is, even when it sticks outside parent");
192 testMouseClick("t6_inner", 19, -1, "t6_inner",
193 "when outside both inner and parent, but in range of both, the inner is selected");
194 testMouseClick("t6_inner", 25, -1, "t6",
195 "clicking in clickable parent close to inner activates parent, not inner");
196 setShowing("t6", false);
198 setShowing("t7", true);
199 setShowing("t7_over", true);
200 testMouseClick("t7", 100 + 11*mm, 10, "body", "covered div is not clickable");
201 testMouseClick("t7", 10, 10, "t7_over", "covered div is not clickable even within its bounds");
202 setShowing("t7", false);
203 setShowing("t7_over", false);
205 // Check that contenteditable elements are considered clickable for fluffing.
206 setShowing("t8", true);
207 var rect = document.getElementById("t8").getBoundingClientRect();
208 testMouseClick("t8", rect.left + 1, rect.top + 1, "t8", "content editable enabled for mouse input");
209 testMouseClick("t8", rect.left + 1, rect.top + 1, "t8", "content editable enabled for touch input", {
210 inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH
211 });
212 setShowing("t8", false);
214 // Check that elements are touchable
215 setShowing("t9", true);
216 var rect = document.getElementById("t9").getBoundingClientRect();
217 testMouseClick("t9", rect.left + 1, rect.top + 1, "t9", "div enabled with mouse input");
218 testMouseClick("t9", rect.left + 1, rect.top + 1, "t9", "div enabled with touch input", {
219 inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH
220 });
221 setShowing("t9", false);
223 setShowing("t10_over", true);
224 setShowing("t10_left", true);
225 setShowing("t10_right", true);
226 setShowing("t10_top", true);
227 setShowing("t10_bottom", true);
228 testMouseClick("t10_left", 51, 10, "t10_over", "element outside of visible area is not selected");
229 if (self.frameElement &&
230 (self.frameElement.offsetLeft + self.innerWidth >
231 SpecialPowers.wrap(top).innerWidth)) {
232 info("WARNING: Window is too narrow, can't test t10_right");
233 } else {
234 testMouseClick("t10_right", 49, 10, "t10_over", "element outside of visible area is not selected");
235 }
236 testMouseClick("t10_top", 10, 51, "t10_over", "element outside of visible area is not selected");
237 if (self.frameElement &&
238 (self.frameElement.offsetTop + self.innerHeight >
239 SpecialPowers.wrap(top).innerHeight)) {
240 info("WARNING: Window is too short, can't test t10_bottom");
241 } else {
242 testMouseClick("t10_bottom", 10, 49, "t10_over", "element outside of visible area is not selected");
243 }
244 setShowing("t10_over", false);
245 setShowing("t10_left", false);
246 setShowing("t10_right", false);
247 setShowing("t10_top", false);
248 setShowing("t10_bottom", false);
250 // Not yet tested:
251 // -- visited link weight
252 // -- "Closest" using Euclidean distance
253 endTest();
254 }
255 </script>
256 </pre>
257 </body>
258 </html>