test_dom_wheel_event.html (37891B)
1 <!DOCTYPE HTML> 2 <html style="font-size: 32px;"> 3 <head> 4 <title>Test for D3E WheelEvent</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 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 9 </head> 10 <body> 11 <p id="display"></p> 12 <div id="scrollable" style="font-family: monospace; font-size: 16px; line-height: 1; overflow: auto; width: 200px; height: 200px;"> 13 <div id="scrolled" style="font-size: 64px; width: 5000px; height: 5000px;"> 14 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 15 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 16 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 17 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 18 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 19 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 20 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 21 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 22 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 23 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 24 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 25 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 26 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 27 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 28 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 29 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 30 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 31 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 32 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 33 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 34 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 35 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 36 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 37 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 38 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 39 Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br> 40 </div> 41 </div> 42 <div id="content" style="display: none"> 43 44 </div> 45 <pre id="test"> 46 <script type="application/javascript"> 47 48 SimpleTest.waitForExplicitFinish(); 49 SimpleTest.waitForFocus(runTest, window); 50 51 var gScrollableElement = document.getElementById("scrollable"); 52 var gScrolledElement = document.getElementById("scrolled"); 53 54 var gLineHeight = 0; 55 var gHorizontalLine = 0; 56 var gPageHeight = 0; 57 var gPageWidth = 0; 58 59 function sendWheelAndWait(aX, aY, aEvent) 60 { 61 sendWheelAndPaint(gScrollableElement, aX, aY, aEvent, continueTest); 62 } 63 64 function* prepareScrollUnits() 65 { 66 var result = -1; 67 function handler(aEvent) 68 { 69 result = aEvent.detail; 70 aEvent.preventDefault(); 71 } 72 window.addEventListener("MozMousePixelScroll", handler, { capture: true, passive: false }); 73 74 yield sendWheelAndWait(10, 10, 75 { deltaMode: WheelEvent.DOM_DELTA_LINE, 76 deltaY: 1.0, lineOrPageDeltaY: 1 }); 77 gLineHeight = result; 78 ok(gLineHeight > 10 && gLineHeight < 25, "prepareScrollUnits: gLineHeight may be illegal value, got " + gLineHeight); 79 80 result = -1; 81 yield sendWheelAndWait(10, 10, 82 { deltaMode: WheelEvent.DOM_DELTA_LINE, 83 deltaX: 1.0, lineOrPageDeltaX: 1 }); 84 gHorizontalLine = result; 85 ok(gHorizontalLine > 5 && gHorizontalLine < 16, "prepareScrollUnits: gHorizontalLine may be illegal value, got " + gHorizontalLine); 86 87 result = -1; 88 yield sendWheelAndWait(10, 10, 89 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 90 deltaY: 1.0, lineOrPageDeltaY: 1 }); 91 gPageHeight = result; 92 // XXX Cannot we know the actual scroll port size? 93 ok(gPageHeight >= 150 && gPageHeight <= 200, 94 "prepareScrollUnits: gPageHeight is strange value, got " + gPageHeight); 95 96 result = -1; 97 yield sendWheelAndWait(10, 10, 98 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 99 deltaX: 1.0, lineOrPageDeltaX: 1 }); 100 gPageWidth = result; 101 ok(gPageWidth >= 150 && gPageWidth <= 200, 102 "prepareScrollUnits: gPageWidth is strange value, got " + gPageWidth); 103 104 window.removeEventListener("MozMousePixelScroll", handler, true); 105 } 106 107 function testMakingUntrustedEvent() 108 { 109 const kCreateEventArgs = [ 110 "WheelEvent", "wheelevent", "wheelEvent", "Wheelevent" 111 ]; 112 113 for (var i = 0; i < kCreateEventArgs.length; i++) { 114 try { 115 // We never support WheelEvent construction with document.createEvent(). 116 var event = document.createEvent(kCreateEventArgs[i]); 117 ok(false, "document.createEvent(" + kCreateEventArgs[i] + ") should throw an error"); 118 } catch (e) { 119 ok(true, "document.createEvent(" + kCreateEventArgs[i] + ") threw an error"); 120 } 121 } 122 123 var wheelEvent = new WheelEvent("wheel"); 124 ok(wheelEvent instanceof WheelEvent, 125 "new WheelEvent() should create an instance of WheelEvent"); 126 ok(typeof(wheelEvent.initWheelEvent) != "function", 127 "WheelEvent must not have initWheelEvent()"); 128 } 129 130 // delta_multiplier prefs should cause changing delta values of trusted events only. 131 // And also legacy events' detail value should be changed too. 132 function* testDeltaMultiplierPrefs() 133 { 134 const kModifierAlt = 0x01; 135 const kModifierControl = 0x02; 136 const kModifierMeta = 0x04; 137 const kModifierShift = 0x08; 138 139 const kTests = [ 140 { name: "default", 141 expected: [ 0, kModifierShift | kModifierAlt, kModifierShift | kModifierControl, 142 kModifierShift | kModifierMeta, 143 kModifierControl | kModifierAlt, kModifierMeta | kModifierAlt ], 144 unexpected: [ kModifierAlt, kModifierControl, kModifierMeta, kModifierShift ] }, 145 { name: "with_alt", 146 expected: [ kModifierAlt ], 147 unexpected: [0, kModifierControl, kModifierMeta, kModifierShift, 148 kModifierShift | kModifierAlt, kModifierControl | kModifierAlt, 149 kModifierMeta | kModifierAlt ] }, 150 { name: "with_control", 151 expected: [ kModifierControl ], 152 unexpected: [0, kModifierAlt, kModifierMeta, kModifierShift, 153 kModifierShift | kModifierControl, kModifierControl | kModifierAlt, 154 kModifierMeta | kModifierControl ] }, 155 { name: "with_meta", 156 expected: [ kModifierMeta ], 157 unexpected: [0, kModifierAlt, kModifierControl, kModifierShift, 158 kModifierShift | kModifierMeta, kModifierControl | kModifierMeta, 159 kModifierMeta | kModifierAlt ] }, 160 { name: "with_shift", 161 expected: [ kModifierShift ], 162 unexpected: [0, kModifierAlt, kModifierControl, kModifierMeta, 163 kModifierShift | kModifierAlt, kModifierControl | kModifierShift, 164 kModifierMeta | kModifierShift ] }, 165 ]; 166 167 // Note that this test doesn't support complicated lineOrPageDelta values which are computed with 168 // accumulated delta values by the prefs. If you need to test the lineOrPageDelta accumulation, 169 // use test_continuous_dom_wheel_event.html. 170 const kEvents = [ 171 { deltaMode: WheelEvent.DOM_DELTA_PIXEL, 172 deltaX: gHorizontalLine, deltaY: gLineHeight, deltaZ: gLineHeight, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 }, 173 { deltaMode: WheelEvent.DOM_DELTA_LINE, 174 deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 }, 175 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 176 deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 }, 177 { deltaMode: WheelEvent.DOM_DELTA_PIXEL, 178 deltaX: -gHorizontalLine, deltaY: -gLineHeight, deltaZ: -gLineHeight, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, 179 { deltaMode: WheelEvent.DOM_DELTA_LINE, 180 deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, 181 { deltaMode: WheelEvent.DOM_DELTA_LINE, skipDeltaModeCheck: true, 182 deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, 183 { deltaMode: WheelEvent.DOM_DELTA_PAGE, 184 deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, 185 ]; 186 187 const kDeltaMultiplierPrefs = [ 188 "delta_multiplier_x", "delta_multiplier_y", "delta_multiplier_z" 189 ]; 190 191 const kPrefValues = [ 192 200, 50, 0, -50, -150 193 ]; 194 195 var currentTest, currentModifiers, currentEvent, currentPref, currentMultiplier, testingExpected; 196 var expectedAsyncHandlerCalls; 197 var description; 198 var calledHandlers = { wheel: false, 199 DOMMouseScroll: { horizontal: false, vertical: false }, 200 MozMousePixelScroll: { horizontal: false, vertical: false } }; 201 202 function deltaToPixels(mode, delta, horizontal) { 203 switch (mode) { 204 case WheelEvent.DOM_DELTA_PIXEL: 205 return delta; 206 case WheelEvent.DOM_DELTA_LINE: 207 return delta * (horizontal ? gHorizontalLine : gLineHeight); 208 case WheelEvent.DOM_DELTA_PAGE: 209 return delta * (horizontal ? gPageWidth : gPageHeight); 210 } 211 throw new Error("Unknown delta mode"); 212 } 213 214 function defaultScrollMultiplier(horizontal) { 215 if (!SpecialPowers.getBoolPref("mousewheel.system_scroll_override.enabled")) { 216 return 1; 217 } 218 return SpecialPowers.getIntPref(`mousewheel.system_scroll_override.${horizontal ? "horizontal" : "vertical"}.factor`) / 100; 219 } 220 221 function wheelEventHandler(aEvent) { 222 calledHandlers.wheel = true; 223 224 var expectedDeltaX = currentEvent.deltaX; 225 var expectedDeltaY = currentEvent.deltaY; 226 var expectedDeltaZ = currentEvent.deltaZ; 227 228 if (testingExpected) { 229 switch (currentPref.charAt(currentPref.length - 1)) { 230 case "x": 231 expectedDeltaX *= currentMultiplier; 232 break; 233 case "y": 234 expectedDeltaY *= currentMultiplier; 235 break; 236 case "z": 237 expectedDeltaZ *= currentMultiplier; 238 break; 239 } 240 } else if (aEvent.isTrusted && aEvent.deltaMode == WheelEvent.DOM_DELTA_LINE) { 241 expectedDeltaX *= defaultScrollMultiplier(true); 242 expectedDeltaY *= defaultScrollMultiplier(false); 243 } 244 is(aEvent.deltaMode, currentEvent.deltaMode, description + "deltaMode (" + currentEvent.deltaMode + ") was invalid"); 245 is(aEvent.deltaX, expectedDeltaX, description + "deltaX (" + currentEvent.deltaX + ") was invalid"); 246 is(aEvent.deltaY, expectedDeltaY, description + "deltaY (" + currentEvent.deltaY + ") was invalid"); 247 is(aEvent.deltaZ, expectedDeltaZ, description + "deltaZ (" + currentEvent.deltaZ + ") was invalid"); 248 is(aEvent.wheelDeltaX, -Math.round(aEvent.isTrusted ? 3 * deltaToPixels(aEvent.deltaMode, expectedDeltaX, true) : expectedDeltaX), `${description}wheelDeltaX (${aEvent.wheelDeltaX}) was invalid`); 249 is(aEvent.wheelDeltaY, -Math.round(aEvent.isTrusted ? 3 * deltaToPixels(aEvent.deltaMode, expectedDeltaY, false) : expectedDeltaY), `${description}wheelDeltaY (${aEvent.wheelDeltaY}) was invalid`); 250 is(aEvent.wheelDelta, aEvent.wheelDeltaY || aEvent.wheelDeltaX, description + "wheelDelta was invalid"); 251 252 if (expectedAsyncHandlerCalls > 0 && --expectedAsyncHandlerCalls == 0) { 253 setTimeout(continueTest, 0); 254 } 255 } 256 257 function legacyEventHandler(aEvent) { 258 var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS); 259 var isScrollEvent = (aEvent.type == "DOMMouseScroll"); 260 if (isScrollEvent) { 261 if (isHorizontal) { 262 calledHandlers.DOMMouseScroll.horizontal = true; 263 } else { 264 calledHandlers.DOMMouseScroll.vertical = true; 265 } 266 } else { 267 if (isHorizontal) { 268 calledHandlers.MozMousePixelScroll.horizontal = true; 269 } else { 270 calledHandlers.MozMousePixelScroll.vertical = true; 271 } 272 } 273 var eventName = (isHorizontal ? "Horizontal " : "Vertical ") + aEvent.type + " "; 274 var expectedDetail; 275 if (isScrollEvent) { 276 expectedDetail = isHorizontal ? currentEvent.lineOrPageDeltaX : currentEvent.lineOrPageDeltaY; 277 if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE && expectedDetail) { 278 expectedDetail = ((expectedDetail > 0) ? UIEvent.SCROLL_PAGE_DOWN : UIEvent.SCROLL_PAGE_UP); 279 } 280 } else { 281 expectedDetail = isHorizontal ? currentEvent.deltaX : currentEvent.deltaY; 282 if (expectedDetail) { 283 if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_LINE) { 284 expectedDetail *= (isHorizontal ? gHorizontalLine : gLineHeight); 285 } else if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE) { 286 if (expectedDetail > 0) { 287 expectedDetail = (isHorizontal ? gPageWidth : gPageHeight); 288 } else { 289 expectedDetail = (isHorizontal ? -gPageWidth : -gPageHeight); 290 } 291 } 292 } 293 } 294 if (testingExpected) { 295 if ((isHorizontal && currentPref.charAt(currentPref.length - 1) == "x") || 296 (!isHorizontal && currentPref.charAt(currentPref.length - 1) == "y")) { 297 // If it's a page scroll event, the detail value is UIEvent.SCROLL_PAGE_DOWN or 298 // UIEvent.SCROLL_PAGE_UP. If the delta value sign is reverted, we need to 299 // revert the expected detail value too. Otherwise, don't touch it. 300 if (isScrollEvent && currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE) { 301 if (currentMultiplier < 0) { 302 expectedDetail = ((expectedDetail == UIEvent.SCROLL_PAGE_UP) ? UIEvent.SCROLL_PAGE_DOWN : UIEvent.SCROLL_PAGE_UP); 303 } 304 } else { 305 expectedDetail *= currentMultiplier; 306 expectedDetail = expectedDetail < 0 ? Math.ceil(expectedDetail) : Math.floor(expectedDetail); 307 } 308 } 309 } 310 is(aEvent.detail, expectedDetail, description + eventName + "detail was invalid"); 311 312 aEvent.preventDefault(); 313 314 if (expectedAsyncHandlerCalls > 0 && --expectedAsyncHandlerCalls == 0) { 315 setTimeout(continueTest, 0); 316 } 317 } 318 319 window.addEventListener("wheel", wheelEventHandler, { capture: true, passive: false }); 320 window.addEventListener("DOMMouseScroll", legacyEventHandler, { capture: true, passive: false }); 321 window.addEventListener("MozMousePixelScroll", legacyEventHandler, { capture: true, passive: false }); 322 323 function* dispatchEvent(aIsExpected) { 324 for (var i = 0; i < kEvents.length; i++) { 325 currentEvent = kEvents[i]; 326 currentEvent.shiftKey = (currentModifiers & kModifierShift) != 0; 327 currentEvent.ctrlKey = (currentModifiers & kModifierControl) != 0; 328 currentEvent.altKey = (currentModifiers & kModifierAlt) != 0; 329 currentEvent.metaKey = (currentModifiers & kModifierMeta) != 0; 330 var modifierList = ""; 331 if (currentEvent.shiftKey) { 332 modifierList += "Shift "; 333 } 334 if (currentEvent.ctrlKey) { 335 modifierList += "Control "; 336 } 337 if (currentEvent.altKey) { 338 modifierList += "Alt "; 339 } 340 if (currentEvent.metaKey) { 341 modifierList += "Meta "; 342 } 343 344 for (var j = 0; j < kPrefValues.length; j++) { 345 currentMultiplier = kPrefValues[j] / 100; 346 for (var k = 0; k < kDeltaMultiplierPrefs.length; k++) { 347 currentPref = "mousewheel." + currentTest.name + "." + kDeltaMultiplierPrefs[k]; 348 349 yield SpecialPowers.pushPrefEnv({"set": [[currentPref, kPrefValues[j]]]}, continueTest); 350 351 gScrollableElement.scrollTop = gScrollableElement.scrollBottom = 1000; 352 353 // trusted event's delta valuses should be reverted by the pref. 354 testingExpected = aIsExpected; 355 356 var expectedProps = { 357 deltaX: currentEvent.deltaX * currentMultiplier, 358 deltaY: currentEvent.deltaY * currentMultiplier, 359 dletaZ: currentEvent.deltaZ * currentMultiplier, 360 lineOrPageDeltaX: currentEvent.lineOrPageDeltaX * currentMultiplier, 361 lineOrPageDeltaY: currentEvent.lineOrPageDeltaY * currentMultiplier, 362 }; 363 364 var expectedWheel = expectedProps.deltaX != 0 || expectedProps.deltaY != 0 || expectedProps.deltaZ != 0; 365 var expectedDOMMouseX = expectedProps.lineOrPageDeltaX >= 1 || expectedProps.lineOrPageDeltaX <= -1; 366 var expectedDOMMouseY = expectedProps.lineOrPageDeltaY >= 1 || expectedProps.lineOrPageDeltaY <= -1; 367 var expectedMozMouseX = expectedProps.deltaX >= 1 || expectedProps.deltaX <= -1; 368 var expectedMozMouseY = expectedProps.deltaY >= 1 || expectedProps.deltaY <= -1; 369 370 expectedAsyncHandlerCalls = 0; 371 if (expectedWheel) ++expectedAsyncHandlerCalls; 372 if (expectedDOMMouseX) ++expectedAsyncHandlerCalls; 373 if (expectedDOMMouseY) ++expectedAsyncHandlerCalls; 374 if (expectedMozMouseX) ++expectedAsyncHandlerCalls; 375 if (expectedMozMouseY) ++expectedAsyncHandlerCalls; 376 377 description = "testDeltaMultiplierPrefs, pref: " + currentPref + "=" + kPrefValues[j] + 378 ", deltaMode: " + currentEvent.deltaMode + ", modifiers: \"" + modifierList + "\", (trusted event): "; 379 yield synthesizeWheel(gScrollableElement, 10, 10, currentEvent); 380 381 is(calledHandlers.wheel, 382 expectedWheel, 383 description + "wheel event was (not) fired"); 384 is(calledHandlers.DOMMouseScroll.horizontal, 385 expectedDOMMouseX, 386 description + "Horizontal DOMMouseScroll event was (not) fired"); 387 is(calledHandlers.DOMMouseScroll.vertical, 388 expectedDOMMouseY, 389 description + "Vertical DOMMouseScroll event was (not) fired"); 390 is(calledHandlers.MozMousePixelScroll.horizontal, 391 expectedMozMouseX, 392 description + "Horizontal MozMousePixelScroll event was (not) fired"); 393 is(calledHandlers.MozMousePixelScroll.vertical, 394 expectedMozMouseY, 395 description + "Vertical MozMousePixelScroll event was (not) fired"); 396 397 calledHandlers = { wheel: false, 398 DOMMouseScroll: { horizontal: false, vertical: false }, 399 MozMousePixelScroll: { horizontal: false, vertical: false } }; 400 401 // untrusted event's delta values shouldn't be reverted by the pref. 402 testingExpected = false; 403 var props = { 404 bubbles: true, 405 cancelable: true, 406 shiftKey: currentEvent.shiftKey, 407 ctrlKey: currentEvent.ctrlKey, 408 altKey: currentEvent.altKey, 409 metaKey: currentEvent.metaKey, 410 deltaX: currentEvent.deltaX, 411 deltaY: currentEvent.deltaY, 412 deltaZ: currentEvent.deltaZ, 413 deltaMode: currentEvent.deltaMode, 414 }; 415 var untrustedEvent = new WheelEvent("wheel", props); 416 417 description = "testDeltaMultiplierPrefs, pref: " + currentPref + "=" + kPrefValues[j] + 418 ", deltaMode: " + currentEvent.deltaMode + ", modifiers: \"" + modifierList + "\", (untrusted event): "; 419 gScrollableElement.dispatchEvent(untrustedEvent); 420 421 ok(calledHandlers.wheel, description + "wheel event was not fired for untrusted event"); 422 ok(!calledHandlers.DOMMouseScroll.horizontal, 423 description + "Horizontal DOMMouseScroll event was fired for untrusted event"); 424 ok(!calledHandlers.DOMMouseScroll.vertical, 425 description + "Vertical DOMMouseScroll event was fired for untrusted event"); 426 ok(!calledHandlers.MozMousePixelScroll.horizontal, 427 description + "Horizontal MozMousePixelScroll event was fired for untrusted event"); 428 ok(!calledHandlers.MozMousePixelScroll.vertical, 429 description + "Vertical MozMousePixelScroll event was fired for untrusted event"); 430 431 yield SpecialPowers.pushPrefEnv({"set": [[currentPref, 100]]}, continueTest); 432 433 calledHandlers = { wheel: false, 434 DOMMouseScroll: { horizontal: false, vertical: false }, 435 MozMousePixelScroll: { horizontal: false, vertical: false } }; 436 437 } 438 // We should skip other value tests if testing with modifier key. 439 // If we didn't do so, it would test too many times, but we don't need to do so. 440 if (kTests.name != "default") { 441 break; 442 } 443 } 444 } 445 } 446 447 for (var i = 0; i < kTests.length; i++) { 448 currentTest = kTests[i]; 449 for (var j = 0; j < currentTest.expected.length; j++) { 450 currentModifiers = currentTest.expected[j]; 451 yield* dispatchEvent(true); 452 } 453 for (var k = 0; k < currentTest.unexpected.length; k++) { 454 currentModifiers = currentTest.unexpected[k]; 455 yield* dispatchEvent(false); 456 } 457 } 458 459 window.removeEventListener("wheel", wheelEventHandler, true); 460 window.removeEventListener("DOMMouseScroll", legacyEventHandler, true); 461 window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true); 462 } 463 464 // Untrusted wheel events shouldn't cause legacy mouse scroll events. 465 function testDispatchingUntrustEvent() 466 { 467 var descriptionBase = "testDispatchingUntrustEvent, "; 468 var description, wheelEventFired; 469 function wheelEventHandler(aEvent) 470 { 471 wheelEventFired = true; 472 } 473 474 function legacyEventHandler(aEvent) 475 { 476 ok(false, aEvent.type + " must not be fired"); 477 } 478 479 window.addEventListener("wheel", wheelEventHandler, true); 480 window.addEventListener("DOMMouseScroll", legacyEventHandler, true); 481 window.addEventListener("MozMousePixelScroll", legacyEventHandler, true); 482 483 description = descriptionBase + "dispatching a pixel wheel event: "; 484 wheelEventFired = false; 485 var untrustedPixelEvent = new WheelEvent("wheel", { 486 bubbles: true, cancelable: true, 487 deltaX: 24.0, deltaY: 24.0, 488 deltaMode: WheelEvent.DOM_DELTA_PIXEL, 489 }); 490 gScrolledElement.dispatchEvent(untrustedPixelEvent); 491 ok(wheelEventFired, description + "wheel event wasn't fired"); 492 493 description = descriptionBase + "dispatching a line wheel event: "; 494 wheelEventFired = false; 495 var untrustedLineEvent = new WheelEvent("wheel", { 496 bubbles: true, cancelable: true, 497 deltaX: 3.0, deltaY: 3.0, 498 deltaMode: WheelEvent.DOM_DELTA_LINE, 499 }); 500 gScrolledElement.dispatchEvent(untrustedLineEvent); 501 ok(wheelEventFired, description + "wheel event wasn't fired"); 502 503 description = descriptionBase + "dispatching a page wheel event: "; 504 wheelEventFired = false; 505 var untrustedPageEvent = new WheelEvent("wheel", { 506 bubbles: true, cancelable: true, 507 deltaX: 1.0, deltaY: 1.0, 508 deltaMode: WheelEvent.DOM_DELTA_PAGE, 509 }); 510 gScrolledElement.dispatchEvent(untrustedPageEvent); 511 ok(wheelEventFired, description + "wheel event wasn't fired"); 512 513 window.removeEventListener("wheel", wheelEventHandler, true); 514 window.removeEventListener("DOMMouseScroll", legacyEventHandler, true); 515 window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true); 516 } 517 518 function* testEventOrder() 519 { 520 const kWheelEvent = 0x0001; 521 const kDOMMouseScrollEvent = 0x0002; 522 const kMozMousePixelScrollEvent = 0x0004; 523 const kVerticalScrollEvent = 0x0010; 524 const kHorizontalScrollEvent = 0x0020; 525 const kInSystemGroup = 0x0100; 526 const kDefaultPrevented = 0x1000; 527 528 var currentTest; 529 530 const kTests = [ 531 { 532 description: "Testing the order of the events without preventDefault()", 533 expectedEvents: [ kWheelEvent, 534 kDOMMouseScrollEvent | kVerticalScrollEvent, 535 kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, 536 kMozMousePixelScrollEvent | kVerticalScrollEvent, 537 kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup, 538 kDOMMouseScrollEvent | kHorizontalScrollEvent, 539 kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 540 kMozMousePixelScrollEvent | kHorizontalScrollEvent, 541 kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 542 kWheelEvent | kInSystemGroup], 543 resultEvents: [], 544 doPreventDefaultAt: 0, 545 }, 546 { 547 description: "Testing the order of the events, calling preventDefault() at default group wheel event", 548 expectedEvents: [ kWheelEvent, 549 kWheelEvent | kInSystemGroup | kDefaultPrevented], 550 resultEvents: [], 551 doPreventDefaultAt: kWheelEvent, 552 }, 553 { 554 description: "Testing the order of the events, calling preventDefault() at default group DOMMouseScroll event", 555 expectedEvents: [ kWheelEvent, 556 kDOMMouseScrollEvent | kVerticalScrollEvent, 557 kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, 558 kMozMousePixelScrollEvent | kVerticalScrollEvent | kDefaultPrevented, 559 kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, 560 kDOMMouseScrollEvent | kHorizontalScrollEvent, 561 kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 562 kMozMousePixelScrollEvent | kHorizontalScrollEvent, 563 kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 564 kWheelEvent | kInSystemGroup | kDefaultPrevented], 565 resultEvents: [], 566 doPreventDefaultAt: kDOMMouseScrollEvent | kVerticalScrollEvent, 567 }, 568 { 569 description: "Testing the order of the events, calling preventDefault() at default group MozMousePixelScroll event", 570 expectedEvents: [ kWheelEvent, 571 kDOMMouseScrollEvent | kVerticalScrollEvent, 572 kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, 573 kMozMousePixelScrollEvent | kVerticalScrollEvent, 574 kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, 575 kDOMMouseScrollEvent | kHorizontalScrollEvent, 576 kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 577 kMozMousePixelScrollEvent | kHorizontalScrollEvent, 578 kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 579 kWheelEvent | kInSystemGroup | kDefaultPrevented], 580 resultEvents: [], 581 doPreventDefaultAt: kMozMousePixelScrollEvent | kVerticalScrollEvent, 582 }, 583 { 584 description: "Testing the order of the events, calling preventDefault() at system group DOMMouseScroll event", 585 expectedEvents: [ kWheelEvent, 586 kDOMMouseScrollEvent | kVerticalScrollEvent, 587 kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, 588 kMozMousePixelScrollEvent | kVerticalScrollEvent | kDefaultPrevented, 589 kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, 590 kDOMMouseScrollEvent | kHorizontalScrollEvent, 591 kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 592 kMozMousePixelScrollEvent | kHorizontalScrollEvent, 593 kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 594 kWheelEvent | kInSystemGroup | kDefaultPrevented], 595 resultEvents: [], 596 doPreventDefaultAt: kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, 597 }, 598 { 599 description: "Testing the order of the events, calling preventDefault() at system group MozMousePixelScroll event", 600 expectedEvents: [ kWheelEvent, 601 kDOMMouseScrollEvent | kVerticalScrollEvent, 602 kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, 603 kMozMousePixelScrollEvent | kVerticalScrollEvent, 604 kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup, 605 kDOMMouseScrollEvent | kHorizontalScrollEvent, 606 kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 607 kMozMousePixelScrollEvent | kHorizontalScrollEvent, 608 kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, 609 kWheelEvent | kInSystemGroup | kDefaultPrevented], 610 resultEvents: [], 611 doPreventDefaultAt: kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup, 612 }, 613 ]; 614 615 function getEventDescription(aEvent) 616 { 617 var result = ""; 618 if (aEvent & kWheelEvent) { 619 result = "wheel" 620 } else { 621 if (aEvent & kDOMMouseScrollEvent) { 622 result = "DOMMouseScroll"; 623 } else if (aEvent & kMozMousePixelScrollEvent) { 624 result = "MozMousePixelScroll"; 625 } 626 if (aEvent & kVerticalScrollEvent) { 627 result += ", vertical"; 628 } else { 629 result += ", horizontal"; 630 } 631 } 632 if (aEvent & kInSystemGroup) { 633 result += ", system group"; 634 } 635 if (aEvent & kDefaultPrevented) { 636 result += ", defaultPrevented"; 637 } 638 return result; 639 } 640 641 function pushEvent(aEvent, aIsSystemGroup) 642 { 643 var event = 0; 644 if (aEvent.type == "wheel") { 645 event = kWheelEvent; 646 } else { 647 if (aEvent.type == "DOMMouseScroll") { 648 event = kDOMMouseScrollEvent; 649 } else if (aEvent.type == "MozMousePixelScroll") { 650 event = kMozMousePixelScrollEvent; 651 } 652 if (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS) { 653 event |= kHorizontalScrollEvent; 654 } else { 655 event |= kVerticalScrollEvent; 656 } 657 } 658 if (aIsSystemGroup) { 659 event |= kInSystemGroup; 660 } 661 if (aEvent.defaultPrevented) { 662 event |= kDefaultPrevented; 663 } 664 currentTest.resultEvents.push(event); 665 666 if (event == currentTest.doPreventDefaultAt) { 667 aEvent.preventDefault(); 668 } 669 670 if (currentTest.resultEvents.length == currentTest.expectedEvents.length) { 671 setTimeout(continueTest, 0); 672 } 673 } 674 675 function handler(aEvent) 676 { 677 pushEvent(aEvent, false); 678 } 679 680 function systemHandler(aEvent) 681 { 682 pushEvent(aEvent, true); 683 } 684 685 window.addEventListener("wheel", handler, { capture: true, passive: false }); 686 window.addEventListener("DOMMouseScroll", handler, { capture: true, passive: false }); 687 window.addEventListener("MozMousePixelScroll", handler, { capture: true, passive: false }); 688 689 SpecialPowers.wrap(window).addEventListener("wheel", systemHandler, { capture: true, passive: false, mozSystemGroup: true }); 690 SpecialPowers.wrap(window).addEventListener("DOMMouseScroll", systemHandler, { capture: true, passive: false, mozSystemGroup: true }); 691 SpecialPowers.wrap(window).addEventListener("MozMousePixelScroll", systemHandler, { capture: true, passive: false, mozSystemGroup: true }); 692 693 for (var i = 0; i < kTests.length; i++) { 694 currentTest = kTests[i]; 695 yield synthesizeWheel(gScrollableElement, 10, 10, 696 { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, deltaY: 1.0 }); 697 698 for (var j = 0; j < currentTest.expectedEvents.length; j++) { 699 if (currentTest.resultEvents.length == j) { 700 ok(false, currentTest.description + ": " + 701 getEventDescription(currentTest.expectedEvents[j]) + " wasn't fired"); 702 break; 703 } 704 is(getEventDescription(currentTest.resultEvents[j]), 705 getEventDescription(currentTest.expectedEvents[j]), 706 currentTest.description + ": " + (j + 1) + "th event is mismatched"); 707 } 708 if (currentTest.expectedEvents.length < currentTest.resultEvents.length) { 709 ok(false, currentTest.description + ": " + 710 getEventDescription(currentTest.resultEvents[currentTest.expectedEvents.length]) + 711 " was fired unexpectedly"); 712 } 713 } 714 715 window.removeEventListener("wheel", handler, true); 716 window.removeEventListener("DOMMouseScroll", handler, true); 717 window.removeEventListener("MozMousePixelScroll", handler, true); 718 719 window.removeEventListener("wheel", systemHandler, true); 720 window.removeEventListener("DOMMouseScroll", systemHandler, true); 721 window.removeEventListener("MozMousePixelScroll", systemHandler, true); 722 } 723 724 var gOnWheelAttrHandled = new Array; 725 var gOnWheelAttrCount = 0; 726 727 function* testOnWheelAttr() 728 { 729 function onWheelHandledString(attr) { 730 return `gOnWheelAttrHandled['${attr}'] = true; 731 ++gOnWheelAttrCount; 732 if (gOnWheelAttrCount == 3) { 733 setTimeout(continueTest, 0); 734 };`; 735 } 736 737 document.documentElement.setAttribute("onwheel", onWheelHandledString("html")); 738 document.body.setAttribute("onwheel", onWheelHandledString("body")); 739 gScrollableElement.setAttribute("onwheel", onWheelHandledString("div")); 740 var target = document.getElementById("onwheel"); 741 yield synthesizeWheel(gScrollableElement, 10, 10, 742 { deltaMode: WheelEvent.DOM_DELTA_LINE, 743 deltaX: 1.0, deltaY: 2.0 }); 744 ok(gOnWheelAttrHandled.html, "html element's onwheel attribute isn't performed"); 745 ok(gOnWheelAttrHandled.body, "body element's onwheel attribute isn't performed"); 746 ok(gOnWheelAttrHandled.div, "div element's onwheel attribute isn't performed"); 747 } 748 749 var gOnWheelPropHandled = new Array; 750 var gOnWheelPropCount = 0; 751 752 function* testOnWheelProperty() 753 { 754 const handleOnWheelProp = prop => e => { 755 gOnWheelPropHandled[prop] = true; 756 ++gOnWheelPropCount; 757 if (gOnWheelPropCount == 5) { 758 setTimeout(continueTest, 0); 759 } 760 } 761 762 window.onwheel = handleOnWheelProp('window'); 763 document.onwheel = handleOnWheelProp('document'); 764 document.documentElement.onwheel = handleOnWheelProp('html'); 765 document.body.onwheel = handleOnWheelProp('body'); 766 gScrollableElement.onwheel = handleOnWheelProp('div'); 767 768 var target = document.getElementById("onwheel"); 769 yield synthesizeWheel(gScrollableElement, 10, 10, 770 { deltaMode: WheelEvent.DOM_DELTA_LINE, 771 deltaX: 1.0, deltaY: 2.0 }); 772 773 ok(gOnWheelPropHandled.window, "window's onwheel property isn't performed"); 774 ok(gOnWheelPropHandled.document, "document's onwheel property isn't performed"); 775 ok(gOnWheelPropHandled.html, "html element's onwheel property isn't performed"); 776 ok(gOnWheelPropHandled.body, "body element's onwheel property isn't performed"); 777 ok(gOnWheelPropHandled.div, "div element's onwheel property isn't performed"); 778 } 779 780 function* testBody() 781 { 782 yield* prepareScrollUnits(); 783 testMakingUntrustedEvent(); 784 yield* testDeltaMultiplierPrefs(); 785 testDispatchingUntrustEvent(); 786 yield* testEventOrder(); 787 yield* testOnWheelAttr(); 788 yield* testOnWheelProperty(); 789 } 790 791 var gTestContinuation = null; 792 793 function continueTest() 794 { 795 if (!gTestContinuation) { 796 gTestContinuation = testBody(); 797 } 798 var ret = gTestContinuation.next(); 799 if (ret.done) { 800 SimpleTest.finish(); 801 } 802 } 803 804 function runTest() 805 { 806 SpecialPowers.pushPrefEnv({"set": [ 807 // FIXME(emilio): This test is broken in HiDPI, unclear if 808 // MozMousePixelScroll is not properly converting to CSS pixels, or 809 // whether sendWheelAndWait expectes device rather than CSS pixels, or 810 // something else. 811 ["layout.css.devPixelsPerPx", 1.0], 812 813 ["dom.event.wheel-deltaMode-lines.disabled", true], 814 815 ["mousewheel.default.delta_multiplier_x", 100], 816 ["mousewheel.default.delta_multiplier_y", 100], 817 ["mousewheel.default.delta_multiplier_z", 100], 818 ["mousewheel.with_alt.delta_multiplier_x", 100], 819 ["mousewheel.with_alt.delta_multiplier_y", 100], 820 ["mousewheel.with_alt.delta_multiplier_z", 100], 821 ["mousewheel.with_control.delta_multiplier_x", 100], 822 ["mousewheel.with_control.delta_multiplier_y", 100], 823 ["mousewheel.with_control.delta_multiplier_z", 100], 824 ["mousewheel.with_meta.delta_multiplier_x", 100], 825 ["mousewheel.with_meta.delta_multiplier_y", 100], 826 ["mousewheel.with_meta.delta_multiplier_z", 100], 827 ["mousewheel.with_shift.delta_multiplier_x", 100], 828 ["mousewheel.with_shift.delta_multiplier_y", 100], 829 ["mousewheel.with_shift.delta_multiplier_z", 100], 830 ]}, continueTest); 831 } 832 </script> 833 </pre> 834 </body> 835 </html>