<!DOCTYPE HTML> <html style="font-size: 32px;"> <head> <title>Test for D3E WheelEvent</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> </head> <body> <p id="display"></p> <div id="scrollable" style="font-family: monospace; font-size: 16px; line-height: 1; overflow: auto; width: 200px; height: 200px;"> <div id="scrolled" style="font-size: 64px; width: 5000px; height: 5000px;"> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> </div> </div> <div id="content" style="display: none"> </div> <pre id="test"> <script type="application/javascript"> SimpleTest.waitForExplicitFinish(); SimpleTest.waitForFocus(runTest, window); var gScrollableElement = document.getElementById("scrollable"); var gScrolledElement = document.getElementById("scrolled"); var gLineHeight = 0; var gHorizontalLine = 0; var gPageHeight = 0; var gPageWidth = 0; function sendWheelAndWait(aX, aY, aEvent) { sendWheelAndPaint(gScrollableElement, aX, aY, aEvent, continueTest); } function* prepareScrollUnits() { var result = -1; function handler(aEvent) { result = aEvent.detail; aEvent.preventDefault(); } window.addEventListener("MozMousePixelScroll", handler, true); yield sendWheelAndWait(10, 10, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaY: 1.0, lineOrPageDeltaY: 1 }); gLineHeight = result; ok(gLineHeight > 10 && gLineHeight < 25, "prepareScrollUnits: gLineHeight may be illegal value, got " + gLineHeight); result = -1; yield sendWheelAndWait(10, 10, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, lineOrPageDeltaX: 1 }); gHorizontalLine = result; ok(gHorizontalLine > 5 && gHorizontalLine < 16, "prepareScrollUnits: gHorizontalLine may be illegal value, got " + gHorizontalLine); result = -1; yield sendWheelAndWait(10, 10, { deltaMode: WheelEvent.DOM_DELTA_PAGE, deltaY: 1.0, lineOrPageDeltaY: 1 }); gPageHeight = result; // XXX Cannot we know the actual scroll port size? ok(gPageHeight >= 150 && gPageHeight <= 200, "prepareScrollUnits: gPageHeight is strange value, got " + gPageHeight); result = -1; yield sendWheelAndWait(10, 10, { deltaMode: WheelEvent.DOM_DELTA_PAGE, deltaX: 1.0, lineOrPageDeltaX: 1 }); gPageWidth = result; ok(gPageWidth >= 150 && gPageWidth <= 200, "prepareScrollUnits: gPageWidth is strange value, got " + gPageWidth); window.removeEventListener("MozMousePixelScroll", handler, true); } function testMakingUntrustedEvent() { const kCreateEventArgs = [ "WheelEvent", "wheelevent", "wheelEvent", "Wheelevent" ]; for (var i = 0; i < kCreateEventArgs.length; i++) { try { // We never support WheelEvent construction with document.createEvent(). var event = document.createEvent(kCreateEventArgs[i]); ok(false, "document.createEvent(" + kCreateEventArgs[i] + ") should throw an error"); } catch (e) { ok(true, "document.createEvent(" + kCreateEventArgs[i] + ") threw an error"); } } var wheelEvent = new WheelEvent("wheel"); ok(wheelEvent instanceof WheelEvent, "new WheelEvent() should create an instance of WheelEvent"); ok(typeof(wheelEvent.initWheelEvent) != "function", "WheelEvent must not have initWheelEvent()"); } // delta_multiplier prefs should cause changing delta values of trusted events only. // And also legacy events' detail value should be changed too. function* testDeltaMultiplierPrefs() { const kModifierAlt = 0x01; const kModifierControl = 0x02; const kModifierMeta = 0x04; const kModifierShift = 0x08; const kModifierWin = 0x10; const kTests = [ { name: "default", expected: [ 0, kModifierShift | kModifierAlt, kModifierShift | kModifierControl, kModifierShift | kModifierMeta, kModifierShift | kModifierWin, kModifierControl | kModifierAlt, kModifierMeta | kModifierAlt ], unexpected: [ kModifierAlt, kModifierControl, kModifierMeta, kModifierShift, kModifierWin ] }, { name: "with_alt", expected: [ kModifierAlt ], unexpected: [0, kModifierControl, kModifierMeta, kModifierShift, kModifierWin, kModifierShift | kModifierAlt, kModifierControl | kModifierAlt, kModifierMeta | kModifierAlt ] }, { name: "with_control", expected: [ kModifierControl ], unexpected: [0, kModifierAlt, kModifierMeta, kModifierShift, kModifierWin, kModifierShift | kModifierControl, kModifierControl | kModifierAlt, kModifierMeta | kModifierControl ] }, { name: "with_meta", expected: [ kModifierMeta ], unexpected: [0, kModifierAlt, kModifierControl, kModifierShift, kModifierWin, kModifierShift | kModifierMeta, kModifierControl | kModifierMeta, kModifierMeta | kModifierAlt ] }, { name: "with_shift", expected: [ kModifierShift ], unexpected: [0, kModifierAlt, kModifierControl, kModifierMeta, kModifierWin, kModifierShift | kModifierAlt, kModifierControl | kModifierShift, kModifierMeta | kModifierShift ] }, { name: "with_win", expected: [ kModifierWin ], unexpected: [0, kModifierAlt, kModifierControl, kModifierMeta, kModifierShift, kModifierShift | kModifierWin ] }, ]; // Note that this test doesn't support complicated lineOrPageDelta values which are computed with // accumulated delta values by the prefs. If you need to test the lineOrPageDelta accumulation, // use test_continuous_dom_wheel_event.html. const kEvents = [ { deltaMode: WheelEvent.DOM_DELTA_PIXEL, deltaX: gHorizontalLine, deltaY: gLineHeight, deltaZ: gLineHeight, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 }, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 }, { deltaMode: WheelEvent.DOM_DELTA_PAGE, deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 }, { deltaMode: WheelEvent.DOM_DELTA_PIXEL, deltaX: -gHorizontalLine, deltaY: -gLineHeight, deltaZ: -gLineHeight, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, { deltaMode: WheelEvent.DOM_DELTA_PAGE, deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 }, ]; const kDeltaMultiplierPrefs = [ "delta_multiplier_x", "delta_multiplier_y", "delta_multiplier_z" ]; const kPrefValues = [ 200, 50, 0, -50, -150 ]; var currentTest, currentModifiers, currentEvent, currentPref, currentMultiplier, testingExpected; var expectedAsyncHandlerCalls; var description; var calledHandlers = { wheel: false, DOMMouseScroll: { horizontal: false, vertical: false }, MozMousePixelScroll: { horizontal: false, vertical: false } }; function wheelEventHandler(aEvent) { calledHandlers.wheel = true; var expectedDeltaX = currentEvent.deltaX; var expectedDeltaY = currentEvent.deltaY; var expectedDeltaZ = currentEvent.deltaZ; if (testingExpected) { switch (currentPref.charAt(currentPref.length - 1)) { case "x": expectedDeltaX *= currentMultiplier; break; case "y": expectedDeltaY *= currentMultiplier; break; case "z": expectedDeltaZ *= currentMultiplier; break; } } is(aEvent.deltaX, expectedDeltaX, description + "deltaX (" + currentEvent.deltaX + ") was invalid"); is(aEvent.deltaY, expectedDeltaY, description + "deltaY (" + currentEvent.deltaY + ") was invalid"); is(aEvent.deltaZ, expectedDeltaZ, description + "deltaZ (" + currentEvent.deltaZ + ") was invalid"); if (expectedAsyncHandlerCalls > 0 && --expectedAsyncHandlerCalls == 0) { setTimeout(continueTest, 0); } } function legacyEventHandler(aEvent) { var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS); var isScrollEvent = (aEvent.type == "DOMMouseScroll"); if (isScrollEvent) { if (isHorizontal) { calledHandlers.DOMMouseScroll.horizontal = true; } else { calledHandlers.DOMMouseScroll.vertical = true; } } else { if (isHorizontal) { calledHandlers.MozMousePixelScroll.horizontal = true; } else { calledHandlers.MozMousePixelScroll.vertical = true; } } var eventName = (isHorizontal ? "Horizontal " : "Vertical ") + aEvent.type + " "; var expectedDetail; if (isScrollEvent) { expectedDetail = isHorizontal ? currentEvent.lineOrPageDeltaX : currentEvent.lineOrPageDeltaY; if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE && expectedDetail) { expectedDetail = ((expectedDetail > 0) ? UIEvent.SCROLL_PAGE_DOWN : UIEvent.SCROLL_PAGE_UP); } } else { expectedDetail = isHorizontal ? currentEvent.deltaX : currentEvent.deltaY; if (expectedDetail) { if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_LINE) { expectedDetail *= (isHorizontal ? gHorizontalLine : gLineHeight); } else if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE) { if (expectedDetail > 0) { expectedDetail = (isHorizontal ? gPageWidth : gPageHeight); } else { expectedDetail = (isHorizontal ? -gPageWidth : -gPageHeight); } } } } if (testingExpected) { if ((isHorizontal && currentPref.charAt(currentPref.length - 1) == "x") || (!isHorizontal && currentPref.charAt(currentPref.length - 1) == "y")) { // If it's a page scroll event, the detail value is UIEvent.SCROLL_PAGE_DOWN or // UIEvent.SCROLL_PAGE_UP. If the delta value sign is reverted, we need to // revert the expected detail value too. Otherwise, don't touch it. if (isScrollEvent && currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE) { if (currentMultiplier < 0) { expectedDetail = ((expectedDetail == UIEvent.SCROLL_PAGE_UP) ? UIEvent.SCROLL_PAGE_DOWN : UIEvent.SCROLL_PAGE_UP); } } else { expectedDetail *= currentMultiplier; expectedDetail = expectedDetail < 0 ? Math.ceil(expectedDetail) : Math.floor(expectedDetail); } } } is(aEvent.detail, expectedDetail, description + eventName + "detail was invalid"); aEvent.preventDefault(); if (expectedAsyncHandlerCalls > 0 && --expectedAsyncHandlerCalls == 0) { setTimeout(continueTest, 0); } } window.addEventListener("wheel", wheelEventHandler, true); window.addEventListener("DOMMouseScroll", legacyEventHandler, true); window.addEventListener("MozMousePixelScroll", legacyEventHandler, true); function* dispatchEvent(aIsExpected) { for (var i = 0; i < kEvents.length; i++) { currentEvent = kEvents[i]; currentEvent.shiftKey = (currentModifiers & kModifierShift) != 0; currentEvent.ctrlKey = (currentModifiers & kModifierControl) != 0; currentEvent.altKey = (currentModifiers & kModifierAlt) != 0; currentEvent.metaKey = (currentModifiers & kModifierMeta) != 0; currentEvent.osKey = (currentModifiers & kModifierWin) != 0; var modifierList = ""; if (currentEvent.shiftKey) { modifierList += "Shift "; } if (currentEvent.ctrlKey) { modifierList += "Control "; } if (currentEvent.altKey) { modifierList += "Alt "; } if (currentEvent.metaKey) { modifierList += "Meta "; } if (currentEvent.osKey) { modifierList += "Win "; } for (var j = 0; j < kPrefValues.length; j++) { currentMultiplier = kPrefValues[j] / 100; for (var k = 0; k < kDeltaMultiplierPrefs.length; k++) { currentPref = "mousewheel." + currentTest.name + "." + kDeltaMultiplierPrefs[k]; yield SpecialPowers.pushPrefEnv({"set": [[currentPref, kPrefValues[j]]]}, continueTest); gScrollableElement.scrollTop = gScrollableElement.scrollBottom = 1000; // trusted event's delta valuses should be reverted by the pref. testingExpected = aIsExpected; var expectedProps = { deltaX: currentEvent.deltaX * currentMultiplier, deltaY: currentEvent.deltaY * currentMultiplier, dletaZ: currentEvent.deltaZ * currentMultiplier, lineOrPageDeltaX: currentEvent.lineOrPageDeltaX * currentMultiplier, lineOrPageDeltaY: currentEvent.lineOrPageDeltaY * currentMultiplier, }; var expectedWheel = expectedProps.deltaX != 0 || expectedProps.deltaY != 0 || expectedProps.deltaZ != 0; var expectedDOMMouseX = expectedProps.lineOrPageDeltaX >= 1 || expectedProps.lineOrPageDeltaX <= -1; var expectedDOMMouseY = expectedProps.lineOrPageDeltaY >= 1 || expectedProps.lineOrPageDeltaY <= -1; var expectedMozMouseX = expectedProps.deltaX >= 1 || expectedProps.deltaX <= -1; var expectedMozMouseY = expectedProps.deltaY >= 1 || expectedProps.deltaY <= -1; expectedAsyncHandlerCalls = 0; if (expectedWheel) ++expectedAsyncHandlerCalls; if (expectedDOMMouseX) ++expectedAsyncHandlerCalls; if (expectedDOMMouseY) ++expectedAsyncHandlerCalls; if (expectedMozMouseX) ++expectedAsyncHandlerCalls; if (expectedMozMouseY) ++expectedAsyncHandlerCalls; description = "testDeltaMultiplierPrefs, pref: " + currentPref + "=" + kPrefValues[j] + ", deltaMode: " + currentEvent.deltaMode + ", modifiers: \"" + modifierList + "\", (trusted event): "; yield synthesizeWheel(gScrollableElement, 10, 10, currentEvent); is(calledHandlers.wheel, expectedWheel, description + "wheel event was (not) fired"); is(calledHandlers.DOMMouseScroll.horizontal, expectedDOMMouseX, description + "Horizontal DOMMouseScroll event was (not) fired"); is(calledHandlers.DOMMouseScroll.vertical, expectedDOMMouseY, description + "Vertical DOMMouseScroll event was (not) fired"); is(calledHandlers.MozMousePixelScroll.horizontal, expectedMozMouseX, description + "Horizontal MozMousePixelScroll event was (not) fired"); is(calledHandlers.MozMousePixelScroll.vertical, expectedMozMouseY, description + "Vertical MozMousePixelScroll event was (not) fired"); calledHandlers = { wheel: false, DOMMouseScroll: { horizontal: false, vertical: false }, MozMousePixelScroll: { horizontal: false, vertical: false } }; // untrusted event's delta values shouldn't be reverted by the pref. testingExpected = false; var props = { bubbles: true, cancelable: true, shiftKey: currentEvent.shiftKey, ctrlKey: currentEvent.ctrlKey, altKey: currentEvent.altKey, metaKey: currentEvent.metaKey, deltaX: currentEvent.deltaX, deltaY: currentEvent.deltaY, deltaZ: currentEvent.deltaZ, deltaMode: currentEvent.deltaMode, }; var untrustedEvent = new WheelEvent("wheel", props); description = "testDeltaMultiplierPrefs, pref: " + currentPref + "=" + kPrefValues[j] + ", deltaMode: " + currentEvent.deltaMode + ", modifiers: \"" + modifierList + "\", (untrusted event): "; gScrollableElement.dispatchEvent(untrustedEvent); ok(calledHandlers.wheel, description + "wheel event was not fired for untrusted event"); ok(!calledHandlers.DOMMouseScroll.horizontal, description + "Horizontal DOMMouseScroll event was fired for untrusted event"); ok(!calledHandlers.DOMMouseScroll.vertical, description + "Vertical DOMMouseScroll event was fired for untrusted event"); ok(!calledHandlers.MozMousePixelScroll.horizontal, description + "Horizontal MozMousePixelScroll event was fired for untrusted event"); ok(!calledHandlers.MozMousePixelScroll.vertical, description + "Vertical MozMousePixelScroll event was fired for untrusted event"); yield SpecialPowers.pushPrefEnv({"set": [[currentPref, 100]]}, continueTest); calledHandlers = { wheel: false, DOMMouseScroll: { horizontal: false, vertical: false }, MozMousePixelScroll: { horizontal: false, vertical: false } }; } // We should skip other value tests if testing with modifier key. // If we didn't do so, it would test too many times, but we don't need to do so. if (kTests.name != "default") { break; } } } } for (var i = 0; i < kTests.length; i++) { currentTest = kTests[i]; for (var j = 0; j < currentTest.expected.length; j++) { currentModifiers = currentTest.expected[j]; yield* dispatchEvent(true); } for (var k = 0; k < currentTest.unexpected.length; k++) { currentModifiers = currentTest.unexpected[k]; yield* dispatchEvent(false); } } window.removeEventListener("wheel", wheelEventHandler, true); window.removeEventListener("DOMMouseScroll", legacyEventHandler, true); window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true); } // Untrusted wheel events shouldn't cause legacy mouse scroll events. function testDispatchingUntrustEvent() { var descriptionBase = "testDispatchingUntrustEvent, "; var description, wheelEventFired; function wheelEventHandler(aEvent) { wheelEventFired = true; } function legacyEventHandler(aEvent) { ok(false, aEvent.type + " must not be fired"); } window.addEventListener("wheel", wheelEventHandler, true); window.addEventListener("DOMMouseScroll", legacyEventHandler, true); window.addEventListener("MozMousePixelScroll", legacyEventHandler, true); description = descriptionBase + "dispatching a pixel wheel event: "; wheelEventFired = false; var untrustedPixelEvent = new WheelEvent("wheel", { bubbles: true, cancelable: true, deltaX: 24.0, deltaY: 24.0, deltaMode: WheelEvent.DOM_DELTA_PIXEL, }); gScrolledElement.dispatchEvent(untrustedPixelEvent); ok(wheelEventFired, description + "wheel event wasn't fired"); description = descriptionBase + "dispatching a line wheel event: "; wheelEventFired = false; var untrustedLineEvent = new WheelEvent("wheel", { bubbles: true, cancelable: true, deltaX: 3.0, deltaY: 3.0, deltaMode: WheelEvent.DOM_DELTA_LINE, }); gScrolledElement.dispatchEvent(untrustedLineEvent); ok(wheelEventFired, description + "wheel event wasn't fired"); description = descriptionBase + "dispatching a page wheel event: "; wheelEventFired = false; var untrustedPageEvent = new WheelEvent("wheel", { bubbles: true, cancelable: true, deltaX: 1.0, deltaY: 1.0, deltaMode: WheelEvent.DOM_DELTA_PAGE, }); gScrolledElement.dispatchEvent(untrustedPageEvent); ok(wheelEventFired, description + "wheel event wasn't fired"); window.removeEventListener("wheel", wheelEventHandler, true); window.removeEventListener("DOMMouseScroll", legacyEventHandler, true); window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true); } function* testEventOrder() { const kWheelEvent = 0x0001; const kDOMMouseScrollEvent = 0x0002; const kMozMousePixelScrollEvent = 0x0004; const kVerticalScrollEvent = 0x0010; const kHorizontalScrollEvent = 0x0020; const kInSystemGroup = 0x0100; const kDefaultPrevented = 0x1000; var currentTest; const kTests = [ { description: "Testing the order of the events without preventDefault()", expectedEvents: [ kWheelEvent, kDOMMouseScrollEvent | kVerticalScrollEvent, kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kVerticalScrollEvent, kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup, kDOMMouseScrollEvent | kHorizontalScrollEvent, kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kHorizontalScrollEvent, kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kWheelEvent | kInSystemGroup], resultEvents: [], doPreventDefaultAt: 0, }, { description: "Testing the order of the events, calling preventDefault() at default group wheel event", expectedEvents: [ kWheelEvent, kWheelEvent | kInSystemGroup | kDefaultPrevented], resultEvents: [], doPreventDefaultAt: kWheelEvent, }, { description: "Testing the order of the events, calling preventDefault() at default group DOMMouseScroll event", expectedEvents: [ kWheelEvent, kDOMMouseScrollEvent | kVerticalScrollEvent, kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, kMozMousePixelScrollEvent | kVerticalScrollEvent | kDefaultPrevented, kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, kDOMMouseScrollEvent | kHorizontalScrollEvent, kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kHorizontalScrollEvent, kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kWheelEvent | kInSystemGroup | kDefaultPrevented], resultEvents: [], doPreventDefaultAt: kDOMMouseScrollEvent | kVerticalScrollEvent, }, { description: "Testing the order of the events, calling preventDefault() at default group MozMousePixelScroll event", expectedEvents: [ kWheelEvent, kDOMMouseScrollEvent | kVerticalScrollEvent, kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kVerticalScrollEvent, kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, kDOMMouseScrollEvent | kHorizontalScrollEvent, kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kHorizontalScrollEvent, kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kWheelEvent | kInSystemGroup | kDefaultPrevented], resultEvents: [], doPreventDefaultAt: kMozMousePixelScrollEvent | kVerticalScrollEvent, }, { description: "Testing the order of the events, calling preventDefault() at system group DOMMouseScroll event", expectedEvents: [ kWheelEvent, kDOMMouseScrollEvent | kVerticalScrollEvent, kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kVerticalScrollEvent | kDefaultPrevented, kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented, kDOMMouseScrollEvent | kHorizontalScrollEvent, kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kHorizontalScrollEvent, kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kWheelEvent | kInSystemGroup | kDefaultPrevented], resultEvents: [], doPreventDefaultAt: kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, }, { description: "Testing the order of the events, calling preventDefault() at system group MozMousePixelScroll event", expectedEvents: [ kWheelEvent, kDOMMouseScrollEvent | kVerticalScrollEvent, kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kVerticalScrollEvent, kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup, kDOMMouseScrollEvent | kHorizontalScrollEvent, kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kMozMousePixelScrollEvent | kHorizontalScrollEvent, kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup, kWheelEvent | kInSystemGroup | kDefaultPrevented], resultEvents: [], doPreventDefaultAt: kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup, }, ]; function getEventDescription(aEvent) { var result = ""; if (aEvent & kWheelEvent) { result = "wheel" } else { if (aEvent & kDOMMouseScrollEvent) { result = "DOMMouseScroll"; } else if (aEvent & kMozMousePixelScrollEvent) { result = "MozMousePixelScroll"; } if (aEvent & kVerticalScrollEvent) { result += ", vertical"; } else { result += ", horizontal"; } } if (aEvent & kInSystemGroup) { result += ", system group"; } if (aEvent & kDefaultPrevented) { result += ", defaultPrevented"; } return result; } function pushEvent(aEvent, aIsSystemGroup) { var event = 0; if (aEvent.type == "wheel") { event = kWheelEvent; } else { if (aEvent.type == "DOMMouseScroll") { event = kDOMMouseScrollEvent; } else if (aEvent.type == "MozMousePixelScroll") { event = kMozMousePixelScrollEvent; } if (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS) { event |= kHorizontalScrollEvent; } else { event |= kVerticalScrollEvent; } } if (aIsSystemGroup) { event |= kInSystemGroup; } if (aEvent.defaultPrevented) { event |= kDefaultPrevented; } currentTest.resultEvents.push(event); if (event == currentTest.doPreventDefaultAt) { aEvent.preventDefault(); } if (currentTest.resultEvents.length == currentTest.expectedEvents.length) { setTimeout(continueTest, 0); } } function handler(aEvent) { pushEvent(aEvent, false); } function systemHandler(aEvent) { pushEvent(aEvent, true); } window.addEventListener("wheel", handler, true); window.addEventListener("DOMMouseScroll", handler, true); window.addEventListener("MozMousePixelScroll", handler, true); SpecialPowers.addSystemEventListener(window, "wheel", systemHandler, true); SpecialPowers.addSystemEventListener(window, "DOMMouseScroll", systemHandler, true); SpecialPowers.addSystemEventListener(window, "MozMousePixelScroll", systemHandler, true); for (var i = 0; i < kTests.length; i++) { currentTest = kTests[i]; yield synthesizeWheel(gScrollableElement, 10, 10, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, deltaY: 1.0 }); for (var j = 0; j < currentTest.expectedEvents.length; j++) { if (currentTest.resultEvents.length == j) { ok(false, currentTest.description + ": " + getEventDescription(currentTest.expectedEvents[j]) + " wasn't fired"); break; } is(getEventDescription(currentTest.resultEvents[j]), getEventDescription(currentTest.expectedEvents[j]), currentTest.description + ": " + (j + 1) + "th event is mismatched"); } if (currentTest.expectedEvents.length < currentTest.resultEvents.length) { ok(false, currentTest.description + ": " + getEventDescription(currentTest.resultEvents[currentTest.expectedEvents.length]) + " was fired unexpectedly"); } } window.removeEventListener("wheel", handler, true); window.removeEventListener("DOMMouseScroll", handler, true); window.removeEventListener("MozMousePixelScroll", handler, true); SpecialPowers.removeSystemEventListener(window, "wheel", systemHandler, true); SpecialPowers.removeSystemEventListener(window, "DOMMouseScroll", systemHandler, true); SpecialPowers.removeSystemEventListener(window, "MozMousePixelScroll", systemHandler, true); } var gOnWheelAttrHandled = new Array; var gOnWheelAttrCount = 0; function* testOnWheelAttr() { function onWheelHandledString(attr) { return `gOnWheelAttrHandled['${attr}'] = true; ++gOnWheelAttrCount; if (gOnWheelAttrCount == 3) { setTimeout(continueTest, 0); };`; } document.documentElement.setAttribute("onwheel", onWheelHandledString("html")); document.body.setAttribute("onwheel", onWheelHandledString("body")); gScrollableElement.setAttribute("onwheel", onWheelHandledString("div")); var target = document.getElementById("onwheel"); yield synthesizeWheel(gScrollableElement, 10, 10, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, deltaY: 2.0 }); ok(gOnWheelAttrHandled['html'], "html element's onwheel attribute isn't performed"); ok(gOnWheelAttrHandled['body'], "body element's onwheel attribute isn't performed"); ok(gOnWheelAttrHandled['div'], "div element's onwheel attribute isn't performed"); } var gOnWheelPropHandled = new Array; var gOnWheelPropCount = 0; function* testOnWheelProperty() { const handleOnWheelProp = prop => e => { gOnWheelPropHandled[prop] = true; ++gOnWheelPropCount; if (gOnWheelPropCount == 5) { setTimeout(continueTest, 0); } } window.onwheel = handleOnWheelProp('window'); document.onwheel = handleOnWheelProp('document'); document.documentElement.onwheel = handleOnWheelProp('html'); document.body.onwheel = handleOnWheelProp('body'); gScrollableElement.onwheel = handleOnWheelProp('div'); var target = document.getElementById("onwheel"); yield synthesizeWheel(gScrollableElement, 10, 10, { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, deltaY: 2.0 }); ok(gOnWheelPropHandled['window'], "window's onwheel property isn't performed"); ok(gOnWheelPropHandled['document'], "document's onwheel property isn't performed"); ok(gOnWheelPropHandled['html'], "html element's onwheel property isn't performed"); ok(gOnWheelPropHandled['body'], "body element's onwheel property isn't performed"); ok(gOnWheelPropHandled['div'], "div element's onwheel property isn't performed"); } function* testBody() { yield* prepareScrollUnits(); testMakingUntrustedEvent(); yield* testDeltaMultiplierPrefs(); testDispatchingUntrustEvent(); yield* testEventOrder(); yield* testOnWheelAttr(); yield* testOnWheelProperty(); } var gTestContinuation = null; function continueTest() { if (!gTestContinuation) { gTestContinuation = testBody(); } var ret = gTestContinuation.next(); if (ret.done) { SimpleTest.finish(); } } function runTest() { SpecialPowers.pushPrefEnv({"set": [ ["mousewheel.default.delta_multiplier_x", 100], ["mousewheel.default.delta_multiplier_y", 100], ["mousewheel.default.delta_multiplier_z", 100], ["mousewheel.with_alt.delta_multiplier_x", 100], ["mousewheel.with_alt.delta_multiplier_y", 100], ["mousewheel.with_alt.delta_multiplier_z", 100], ["mousewheel.with_control.delta_multiplier_x", 100], ["mousewheel.with_control.delta_multiplier_y", 100], ["mousewheel.with_control.delta_multiplier_z", 100], ["mousewheel.with_meta.delta_multiplier_x", 100], ["mousewheel.with_meta.delta_multiplier_y", 100], ["mousewheel.with_meta.delta_multiplier_z", 100], ["mousewheel.with_shift.delta_multiplier_x", 100], ["mousewheel.with_shift.delta_multiplier_y", 100], ["mousewheel.with_shift.delta_multiplier_z", 100], ["mousewheel.with_win.delta_multiplier_x", 100], ["mousewheel.with_win.delta_multiplier_y", 100], ["mousewheel.with_win.delta_multiplier_z", 100]]}, continueTest); } </script> </pre> </body> </html>