test_moz_mouse_pixel_scroll_event.html (18214B)
1 <!DOCTYPE HTML> 2 <html id="root"> 3 <head> 4 <title>Test for MozMousePixelScroll events</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="/tests/SimpleTest/EventUtils.js"></script> 7 <script src="/tests/SimpleTest/paint_listener.js"></script> 8 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 9 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 10 <style> 11 html, body { margin: 0 } 12 13 .scrollable { 14 overflow: auto; 15 line-height: 1; 16 margin: 15px; 17 box-sizing: border-box; 18 } 19 .scrollable > div { 20 width: 1000px; 21 height: 1000px; 22 font-size: 1000px; 23 line-height: 1; 24 } 25 /* Ensure viewport is scrollable */ 26 .viewport-padding { height: 200vh; width: 200vh; } 27 </style> 28 </head> 29 <body> 30 <p id="display"></p> 31 <div id="Scrollable128" class="scrollable" style="font-size: 128px; width: 100px; height: 100px;"> 32 <div> 33 <div id="Scrollable96" class="scrollable" style="font-size: 96px; width: 150px; height: 150px;"> 34 <div> 35 <div id="Scrollable64" class="scrollable" style="font-size: 64px; width: 200px; height: 200px;"> 36 <div> 37 </div> 38 </div> 39 </div> 40 </div> 41 </div> 42 </div> 43 <div id="Scrollable32" class="scrollable" style="font-size: 32px; width: 50px; height: 50px;"> 44 <div> 45 </div> 46 </div> 47 <div class="viewport-padding"></div> 48 <div id="content" style="display: none"></div> 49 <pre id="test"> 50 <script> 51 52 SimpleTest.waitForExplicitFinish(); 53 SimpleTest.waitForFocus(startTest, window); 54 55 var gScrollable128 = document.getElementById("Scrollable128"); 56 var gScrollable96 = document.getElementById("Scrollable96"); 57 var gScrollable64 = document.getElementById("Scrollable64"); 58 var gScrollable32 = document.getElementById("Scrollable32"); 59 var gRoot = document.documentElement; 60 61 // TODO(emilio): page scrolling seems to interact weirdly with 62 // Android (probably due to the visual viewport? but I can't repro 63 // on the emulator). It's probably not a big deal though since you 64 // can't usually do page scrolling on Android, and chances are 65 // actual behavior is correct and we just need to tweak the test. 66 const kIsAndroid = navigator.userAgent.includes("Android"); 67 68 function* prepareScrollUnits() 69 { 70 var result = -1; 71 function handler(aEvent) 72 { 73 result = aEvent.detail; 74 aEvent.preventDefault(); 75 setTimeout(runTest, 0); 76 } 77 window.addEventListener("MozMousePixelScroll", handler, { capture: true, passive: false }); 78 79 yield waitForAllPaints(function () { setTimeout(runTest, 0); }); 80 81 yield synthesizeWheel(gScrollable128, 10, 10, 82 { deltaMode: WheelEvent.DOM_DELTA_LINE, 83 deltaY: 1.0, lineOrPageDeltaY: 1 }); 84 gScrollable128.wheelLineHeight = result; 85 ok(result > 96 && result < 200, "prepareScrollUnits: gScrollable128.wheelLineHeight may be illegal value, got " + result); 86 87 result = -1; 88 yield synthesizeWheel(gScrollable96, 10, 10, 89 { deltaMode: WheelEvent.DOM_DELTA_LINE, 90 deltaY: 1.0, lineOrPageDeltaY: 1 }); 91 gScrollable96.wheelLineHeight = result; 92 ok(result > 64 && result < gScrollable128.wheelLineHeight, "prepareScrollUnits: gScrollable96.wheelLineHeight may be illegal value, got " + result); 93 94 result = -1; 95 yield synthesizeWheel(gScrollable64, 10, 10, 96 { deltaMode: WheelEvent.DOM_DELTA_LINE, 97 deltaY: 1.0, lineOrPageDeltaY: 1 }); 98 gScrollable64.wheelLineHeight = result; 99 ok(result > 32 && result < gScrollable96.wheelLineHeight, "prepareScrollUnits: gScrollable64.wheelLineHeight may be illegal value, got " + result); 100 101 result = -1; 102 yield synthesizeWheel(gScrollable32, 10, 10, 103 { deltaMode: WheelEvent.DOM_DELTA_LINE, 104 deltaY: 1.0, lineOrPageDeltaY: 1 }); 105 gScrollable32.wheelLineHeight = result; 106 ok(result > 16 && result < gScrollable64.wheelLineHeight, "prepareScrollUnits: gScrollable32.wheelLineHeight may be illegal value, got " + result); 107 108 result = -1; 109 yield synthesizeWheel(gRoot, 10, 10, 110 { deltaMode: WheelEvent.DOM_DELTA_LINE, 111 deltaY: 1.0, lineOrPageDeltaY: 1 }); 112 gRoot.wheelLineHeight = result; 113 ok(result > 10 && result < gScrollable32.wheelLineHeight, "prepareScrollUnits: gRoot.wheelLineHeight may be illegal value, got " + result); 114 115 result = -1; 116 yield synthesizeWheel(gScrollable128, 10, 10, 117 { deltaMode: WheelEvent.DOM_DELTA_LINE, 118 deltaX: 1.0, lineOrPageDeltaX: 1 }); 119 gScrollable128.wheelHorizontalLine = result; 120 ok(result > 50 && result < 200, "prepareScrollUnits: gScrollable128.wheelHorizontalLine may be illegal value, got " + result); 121 122 result = -1; 123 yield synthesizeWheel(gScrollable96, 10, 10, 124 { deltaMode: WheelEvent.DOM_DELTA_LINE, 125 deltaX: 1.0, lineOrPageDeltaX: 1 }); 126 gScrollable96.wheelHorizontalLine = result; 127 ok(result > 30 && result < gScrollable128.wheelHorizontalLine, "prepareScrollUnits: gScrollable96.wheelHorizontalLine may be illegal value, got " + result); 128 129 result = -1; 130 yield synthesizeWheel(gScrollable64, 10, 10, 131 { deltaMode: WheelEvent.DOM_DELTA_LINE, 132 deltaX: 1.0, lineOrPageDeltaX: 1 }); 133 gScrollable64.wheelHorizontalLine = result; 134 ok(result > 20 && result < gScrollable96.wheelHorizontalLine, "prepareScrollUnits: gScrollable64.wheelHorizontalLine may be illegal value, got " + result); 135 136 result = -1; 137 yield synthesizeWheel(gScrollable32, 10, 10, 138 { deltaMode: WheelEvent.DOM_DELTA_LINE, 139 deltaX: 1.0, lineOrPageDeltaX: 1 }); 140 gScrollable32.wheelHorizontalLine = result; 141 ok(result > 12 && result < gScrollable64.wheelHorizontalLine, "prepareScrollUnits: gScrollable32.wheelHorizontalLine may be illegal value, got " + result); 142 143 result = -1; 144 yield synthesizeWheel(gRoot, 10, 10, 145 { deltaMode: WheelEvent.DOM_DELTA_LINE, 146 deltaX: 1.0, lineOrPageDeltaX: 1 }); 147 gRoot.wheelHorizontalLine = result; 148 ok(result > 5 && result < gScrollable32.wheelHorizontalLine, "prepareScrollUnits: gRoot.wheelHorizontalLine may be illegal value, got " + result); 149 150 result = -1; 151 yield synthesizeWheel(gScrollable128, 10, 10, 152 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 153 deltaY: 1.0, lineOrPageDeltaY: 1 }); 154 gScrollable128.wheelPageHeight = result; 155 ok(result >= (100 - gScrollable128.wheelLineHeight * 2) && result <= 100, 156 "prepareScrollUnits: gScrollable128.wheelPageHeight is strange value, got " + result); 157 158 result = -1; 159 yield synthesizeWheel(gScrollable96, 10, 10, 160 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 161 deltaY: 1.0, lineOrPageDeltaY: 1 }); 162 gScrollable96.wheelPageHeight = result; 163 ok(result >= (150 - gScrollable96.wheelLineHeight * 2) && result <= 150, 164 "prepareScrollUnits: gScrollable96.wheelPageHeight is strange value, got " + result); 165 166 result = -1; 167 yield synthesizeWheel(gScrollable64, 10, 10, 168 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 169 deltaY: 1.0, lineOrPageDeltaY: 1 }); 170 gScrollable64.wheelPageHeight = result; 171 ok(result >= (200 - gScrollable64.wheelLineHeight * 2) && result <= 200, 172 "prepareScrollUnits: gScrollable64.wheelPageHeight is strange value, got " + result); 173 174 result = -1; 175 yield synthesizeWheel(gScrollable32, 10, 10, 176 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 177 deltaY: 1.0, lineOrPageDeltaY: 1 }); 178 gScrollable32.wheelPageHeight = result; 179 ok(result >= (50 - gScrollable32.wheelLineHeight * 2) && result <= 50, 180 "prepareScrollUnits: gScrollable32.wheelPageHeight is strange value, got " + result); 181 182 result = -1; 183 yield synthesizeWheel(gRoot, 10, 10, 184 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 185 deltaY: 1.0, lineOrPageDeltaY: 1 }); 186 gRoot.wheelPageHeight = result; 187 if (!kIsAndroid) { 188 ok(window.innerHeight - result < 100 && window.innerHeight - result > 0, 189 "prepareScrollUnits: gRoot.wheelPageHeight is strange value, got " + result); 190 } 191 192 result = -1; 193 yield synthesizeWheel(gScrollable128, 10, 10, 194 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 195 deltaX: 1.0, lineOrPageDeltaX: 1 }); 196 gScrollable128.wheelPageWidth = result; 197 ok(result >= (100 - gScrollable128.wheelLineHeight * 2) && result <= 100, 198 "prepareScrollUnits: gScrollable128.wheelPageWidth is strange value, got " + result); 199 200 result = -1; 201 yield synthesizeWheel(gScrollable96, 10, 10, 202 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 203 deltaX: 1.0, lineOrPageDeltaX: 1 }); 204 gScrollable96.wheelPageWidth = result; 205 ok(result >= (150 - gScrollable96.wheelLineHeight * 2) && result <= 150, 206 "prepareScrollUnits: gScrollable96.wheelPageWidth is strange value, got " + result); 207 208 result = -1; 209 yield synthesizeWheel(gScrollable64, 10, 10, 210 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 211 deltaX: 1.0, lineOrPageDeltaX: 1 }); 212 gScrollable64.wheelPageWidth = result; 213 ok(result >= (200 - gScrollable64.wheelLineHeight * 2) && result <= 200, 214 "prepareScrollUnits: gScrollable64.wheelPageWidth is strange value, got " + result); 215 216 result = -1; 217 yield synthesizeWheel(gScrollable32, 10, 10, 218 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 219 deltaX: 1.0, lineOrPageDeltaX: 1 }); 220 gScrollable32.wheelPageWidth = result; 221 ok(result >= (50 - gScrollable32.wheelLineHeight * 2) && result <= 50, 222 "prepareScrollUnits: gScrollable32.wheelPageWidth is strange value, got " + result); 223 224 result = -1; 225 yield synthesizeWheel(gRoot, 10, 10, 226 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 227 deltaX: 1.0, lineOrPageDeltaX: 1 }); 228 gRoot.wheelPageWidth = result; 229 if (!kIsAndroid) { 230 ok(window.innerWidth - result < 100 && window.innerWidth - result > 0, 231 "prepareScrollUnits: gRoot.wheelPageWidth is strange value, got " + result); 232 } 233 234 window.removeEventListener("MozMousePixelScroll", handler, true); 235 } 236 237 function* doTests() 238 { 239 let tests = []; 240 241 { 242 const kAllScrollables = [gRoot, gScrollable128, gScrollable96, gScrollable64, gScrollable32]; 243 function resetAllScrollables() { 244 for (let scrollable of kAllScrollables) { 245 scrollable.style.overflow = ""; 246 scrollable.scrollLeft = 0; 247 scrollable.scrollTop = 0; 248 } 249 } 250 251 function closestScrollable(s) { 252 if (s == gScrollable32 || s == gRoot) { 253 return gRoot; 254 } 255 let closest = kAllScrollables[kAllScrollables.indexOf(s) - 1]; 256 ok(closest, `Should find a closest scrollable for ${s.id}`); 257 return closest; 258 } 259 260 const kAllScrollDirections = [ 261 { 262 direction: "both", 263 x: 1, 264 y: 1, 265 }, 266 { 267 direction: "horizontal", 268 x: 1, 269 y: 0, 270 }, 271 { 272 direction: "vertical", 273 x: 0, 274 y: 1, 275 }, 276 ]; 277 278 for (let deltaMode of [WheelEvent.DOM_DELTA_LINE, WheelEvent.DOM_DELTA_PAGE]) { 279 if (deltaMode == WheelEvent.DOM_DELTA_PAGE && kIsAndroid) { 280 // See comment around kIsAndroid. 281 continue; 282 } 283 284 for (let scrollable of kAllScrollables) { 285 for (let { x, y, direction } of kAllScrollDirections) { 286 tests.push({ 287 description: `Should be computed from nearest scrollable element (${scrollable.id}, ${deltaMode}, ${direction})`, 288 target: scrollable, 289 event: { 290 deltaMode, 291 deltaX: x, 292 deltaY: y, 293 lineOrPageDeltaX: x, 294 lineOrPageDeltaY: y, 295 }, 296 prepare () { 297 resetAllScrollables(); 298 }, 299 cleanup () { 300 }, 301 expected: { 302 x: x ? scrollable : null, 303 y: y ? scrollable : null, 304 } 305 }); 306 307 tests.push({ 308 description: `Should be computed from actual scroll target or root if not scrollable in the direction (${scrollable.id}, ${deltaMode}, ${direction})`, 309 target: scrollable, 310 event: { 311 deltaMode, 312 deltaX: -x, 313 deltaY: -y, 314 lineOrPageDeltaX: -x, 315 lineOrPageDeltaY: -y 316 }, 317 prepare () { 318 resetAllScrollables(); 319 }, 320 cleanup () { 321 }, 322 expected: { 323 x: x ? gRoot : null, 324 y: y ? gRoot : null, 325 } 326 }); 327 328 // Root's page delta depends on whether there's an horizontal scrollbar 329 // or not, so this test on the root would be off by a few pixels. 330 if (scrollable != gRoot || deltaMode != WheelEvent.DOM_DELTA_PAGE) { 331 tests.push({ 332 description: `Should be computed from actual scroll target or root if scrollable in the direction but overflow: hidden (${scrollable.id}, ${deltaMode}, ${direction})`, 333 target: scrollable, 334 event: { 335 deltaMode, 336 deltaX: x, 337 deltaY: y, 338 lineOrPageDeltaX: x, 339 lineOrPageDeltaY: y, 340 }, 341 prepare () { 342 resetAllScrollables(); 343 scrollable.style.overflow = "hidden"; 344 }, 345 cleanup () { 346 scrollable.style.overflow = ""; 347 }, 348 expected: { 349 x: x ? closestScrollable(scrollable) : null, 350 y: y ? closestScrollable(scrollable) : null, 351 } 352 }); 353 } 354 } 355 } 356 } 357 } 358 359 var currentTest, description, firedX, firedY; 360 var expectedHandlerCalls; 361 362 function handler(aEvent) 363 { 364 aEvent.preventDefault(); 365 366 if (aEvent.axis != MouseScrollEvent.HORIZONTAL_AXIS && 367 aEvent.axis != MouseScrollEvent.VERTICAL_AXIS) { 368 ok(false, 369 description + "The event had invalid axis (" + aEvent.axis + ")"); 370 if (--expectedHandlerCalls == 0) { 371 setTimeout(runTest, 0); 372 } 373 return; 374 } 375 376 var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS); 377 if ((isHorizontal && !currentTest.expected.x) || 378 (!isHorizontal && !currentTest.expected.y)) { 379 ok(false, 380 description + "The event fired unexpectedly (" + 381 (isHorizontal ? "Horizontal" : "Vertical") + ")"); 382 if (--expectedHandlerCalls == 0) { 383 setTimeout(runTest, 0); 384 } 385 return; 386 } 387 388 if (isHorizontal) { 389 firedX = true; 390 } else { 391 firedY = true; 392 } 393 394 var expectedDetail = 395 (currentTest.event.deltaMode == WheelEvent.DOM_DELTA_LINE) ? 396 (isHorizontal ? currentTest.expected.x.wheelHorizontalLine : 397 currentTest.expected.y.wheelLineHeight) : 398 (isHorizontal ? currentTest.expected.x.wheelPageWidth : 399 currentTest.expected.y.wheelPageHeight); 400 is(Math.abs(aEvent.detail), expectedDetail, 401 description + ((isHorizontal) ? "horizontal" : "vertical") + " event detail is wrong"); 402 403 if (--expectedHandlerCalls == 0) { 404 setTimeout(runTest, 0); 405 } 406 } 407 408 window.addEventListener("MozMousePixelScroll", handler, { capture: true, passive: false }); 409 410 for (var i = 0; i < tests.length; i++) { 411 currentTest = tests[i]; 412 description = "doTests, " + currentTest.description + " (deltaMode: " + 413 (currentTest.event.deltaMode == WheelEvent.DOM_DELTA_LINE ? 414 "DOM_DELTA_LINE" : "DOM_DELTA_PAGE") + 415 ", deltaX: " + currentTest.event.deltaX + 416 ", deltaY: " + currentTest.event.deltaY + "): "; 417 currentTest.prepare(); 418 firedX = firedY = false; 419 expectedHandlerCalls = (currentTest.expected.x ? 1 : 0) 420 + (currentTest.expected.y ? 1 : 0); 421 yield synthesizeWheel(currentTest.target, 10, 10, currentTest.event); 422 if (currentTest.expected.x) { 423 ok(firedX, description + "Horizontal MozMousePixelScroll event wasn't fired"); 424 } 425 if (currentTest.expected.y) { 426 ok(firedY, description + "Vertical MozMousePixelScroll event wasn't fired"); 427 } 428 currentTest.cleanup(); 429 } 430 431 window.removeEventListener("MozMousePixelScroll", handler, true); 432 } 433 434 function* testBody() 435 { 436 yield* prepareScrollUnits(); 437 yield* doTests(); 438 } 439 440 var gTestContinuation = null; 441 442 function runTest() 443 { 444 if (!gTestContinuation) { 445 gTestContinuation = testBody(); 446 } 447 var ret = gTestContinuation.next(); 448 if (ret.done) { 449 SimpleTest.finish(); 450 } 451 } 452 453 function startTest() { 454 SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100], 455 ["mousewheel.default.delta_multiplier_y", 100], 456 ["mousewheel.default.delta_multiplier_z", 100], 457 ["mousewheel.with_alt.delta_multiplier_x", 100], 458 ["mousewheel.with_alt.delta_multiplier_y", 100], 459 ["mousewheel.with_alt.delta_multiplier_z", 100], 460 ["mousewheel.with_control.delta_multiplier_x", 100], 461 ["mousewheel.with_control.delta_multiplier_y", 100], 462 ["mousewheel.with_control.delta_multiplier_z", 100], 463 ["mousewheel.with_meta.delta_multiplier_x", 100], 464 ["mousewheel.with_meta.delta_multiplier_y", 100], 465 ["mousewheel.with_meta.delta_multiplier_z", 100], 466 ["mousewheel.with_shift.delta_multiplier_x", 100], 467 ["mousewheel.with_shift.delta_multiplier_y", 100], 468 ["mousewheel.with_shift.delta_multiplier_z", 100], 469 // If APZ is enabled we should ensure the preventDefault calls work even 470 // if the test is running slowly. 471 ["apz.content_response_timeout", 2000], 472 ]}, runTest); 473 } 474 475 </script> 476 </pre> 477 </body> 478 </html>