tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>