tor-browser

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

pointerevent_capture_suppressing_mouse.html (9879B)


      1 <!doctype html>
      2 <html>
      3  <head>
      4    <title>Set/Release capture</title>
      5    <meta name="viewport" content="width=device-width">
      6    <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
      7    <script src="/resources/testharness.js"></script>
      8    <script src="/resources/testharnessreport.js"></script>
      9    <script src="/resources/testdriver.js"></script>
     10    <script src="/resources/testdriver-actions.js"></script>
     11    <script src="/resources/testdriver-vendor.js"></script>
     12    <!-- Additional helper script for common checks across event types -->
     13    <script type="text/javascript" src="pointerevent_support.js"></script>
     14  </head>
     15  <body>
     16    <div class="spacer"></div>
     17    <div id="target0"></div>
     18    <div class="spacer"></div>
     19    <div id="target1"></div>
     20    <div class="spacer"></div>
     21    <input type="button" id="captureButton" value="Set Capture">
     22  </body>
     23  <script type='text/javascript'>
     24    window.onload = () => {
     25      let eventLog = [];
     26      let nextUncheckedEventIndex = 0;
     27      const target0 = document.getElementById('target0');
     28      const target1 = document.getElementById('target1');
     29      const captureButton = document.getElementById('captureButton');
     30 
     31      function eventLabel(target, eventName) {
     32        return `${eventName}@${target.id}`;
     33      }
     34 
     35      function recordEvent(target, eventName) {
     36        eventLog.push(eventLabel(target, eventName));
     37      }
     38 
     39      // Ensure match to the next sequence of events in the event log.
     40      function assert_next_events(target, expectedEventNames, message) {
     41        for (let i = 0; i < expectedEventNames.length; i++) {
     42          assert_true(nextUncheckedEventIndex < eventLog.length,
     43                      `${message}: empty event queue`);
     44          const observed = eventLog[nextUncheckedEventIndex++];
     45          const expected = eventLabel(target, expectedEventNames[i]);
     46          assert_equals(observed, expected,`${message}: Event  mismatch`);
     47        }
     48      }
     49 
     50      // After validating the expected events, all entries in the event map
     51      // must be false or we have recorded an unexpected event.
     52      function assert_empty_event_queue(message) {
     53        const uncheckedEvents = eventLog.length - nextUncheckedEventIndex;
     54        assert_equals(uncheckedEvents, 0,
     55                      `${message}: Unexpected events ` +
     56                      `${eventLog.slice(-uncheckedEvents).join(", ")}`);
     57      }
     58 
     59      // Adds listeners for all element-pointerevent combinations. Each listener
     60      // records the event for validation. the pointerdown event on the button
     61      // triggers an extra step of triggering pointer capture.
     62      function addEventListeners(t) {
     63        // Adds a single event that is removed at the conclusion of the test.
     64        const addListener = (target, eventName, fn) => {
     65          const callback = (e) => {
     66            recordEvent(target, eventName);
     67            // Additional event handling is optional.
     68            if (fn)
     69              fn(e);
     70          };
     71          target.addEventListener(eventName, callback);
     72          t.add_cleanup(() => {
     73             target.removeEventListener(eventName, callback);
     74          });
     75        };
     76        [target0, target1, captureButton].forEach(el => {
     77          ['gotpointercapture', 'lostpointercapture', 'pointerenter',
     78           'pointerleave', 'pointermove', 'pointerout',
     79           'pointerover'].forEach(eventName => {
     80             addListener(el, eventName);
     81           });
     82        });
     83        addListener(captureButton, 'pointerdown', (e) => {
     84          target0.setPointerCapture(e.pointerId);
     85        });
     86        t.add_cleanup(() => {
     87          eventLog = [];
     88          nextUncheckedEventIndex = 0;
     89        });
     90      }
     91 
     92      // Trigger and wait for a pointer move.  The wait is to ensure there is
     93      // no coalescence of pointer move events.
     94      async function moveTo(x, y, target) {
     95        const movePromise = getEvent('pointermove', target);
     96        let actions = new test_driver.Actions()
     97                      .pointerMove(x, y, { origin: target })
     98                      .send();
     99        await actions;
    100        await movePromise;
    101      }
    102 
    103      promise_test(async t => {
    104        // Reset pointer position.
    105        await moveTo(0, 0, document.body);
    106        addEventListeners(t);
    107        // Move to the first target.
    108        await moveTo(0, 0, target0);
    109        assert_next_events(target0,["pointerover", "pointerenter", "pointermove"],
    110                           'Move to first target');
    111        assert_empty_event_queue('Check after first move');
    112 
    113        // Move to the second taret.
    114        await moveTo(0, 0, target1);
    115        assert_next_events(target0, ['pointerout', 'pointerleave'],
    116                           'Exit first target');
    117        assert_next_events(target1,
    118                      ["pointerover", "pointerenter", "pointermove"],
    119                      'Move to second target');
    120        assert_empty_event_queue('Check after second move');
    121 
    122        // Move to the capture button.
    123        await moveTo(0, 0, captureButton);
    124        assert_next_events(target1, ['pointerout', 'pointerleave'],
    125                           'Exit second target');
    126        assert_next_events(
    127            captureButton, ["pointerover", "pointerenter", "pointermove"],
    128            'Move to button');
    129        assert_empty_event_queue('Check after third move');
    130      }, 'Validate pointer events track pointer movement without pointer '
    131         + 'capture.');
    132 
    133      async function runCaptureAndHoverTargetActionSequence(t, hoverTarget) {
    134        const pointerUpPromise = getEvent('pointerup', document);
    135        const actionsPromise =
    136            new test_driver.Actions()
    137                // Start outside capture button.
    138                .pointerMove(0, 0)
    139                .pointerDown()
    140                .pointerUp()
    141                // Move to the capture button
    142                .pointerMove(0, 0, {origin: captureButton})
    143                // Trigger pointer capture
    144                .pointerDown()
    145                // Hover over the target element
    146                .pointerMove(10, 0, {origin: hoverTarget})
    147                // Release capture
    148                .pointerUp()
    149                .send();
    150        await actionsPromise;
    151        await pointerUpPromise;
    152      }
    153 
    154      promise_test(async t => {
    155        // Reset pointer position.
    156        await moveTo(0, 0, document.body);
    157        addEventListeners(t);
    158 
    159        // On entry for this sub-test, the pointer is at the document origin.
    160        await runCaptureAndHoverTargetActionSequence(t, captureButton);
    161        assert_next_events(
    162            captureButton,
    163            ['pointerover', 'pointerenter', 'pointermove'],
    164            'Move to button from origin');
    165        assert_next_events(
    166            captureButton,
    167            ['pointerdown', 'pointerout', 'pointerleave'],
    168            'Pointer down on button to trigger capture');
    169        assert_next_events(
    170            target0,
    171            ['pointerover', 'pointerenter', 'gotpointercapture', 'pointermove'],
    172            'Capture triggered while hovering over button');
    173        assert_next_events(
    174            target0,
    175            ['lostpointercapture', 'pointerout', 'pointerleave'],
    176            'Lose pointer capture while hovering over button');
    177        // Post pointer capture.
    178        assert_next_events(
    179            captureButton,
    180            ['pointerover', 'pointerenter'],
    181            'Post capture while hovering over button');
    182        assert_empty_event_queue('Check after button hover');
    183 
    184        // On entry for this sub-test, the pointer is over the button.
    185        await runCaptureAndHoverTargetActionSequence(t, target0);
    186        assert_next_events(
    187            captureButton,
    188            ['pointerout', 'pointerleave'],
    189            'Move from button to document origin');
    190        assert_next_events(
    191            captureButton,
    192            ['pointerover', 'pointerenter', 'pointermove'],
    193            'Move from document origin to button');
    194        assert_next_events(
    195            captureButton,
    196            [ 'pointerdown', 'pointerout', 'pointerleave'],
    197            'Pointer down on button to trigger capture');
    198        assert_next_events(
    199            target0,
    200            ['pointerover', 'pointerenter', 'gotpointercapture', 'pointermove'],
    201            'Capture triggered while hovering over capture target');
    202        assert_next_events(
    203            target0,
    204            ['lostpointercapture'],
    205            'Lose pointer capture while hovering over capture target');
    206        assert_empty_event_queue('Check after hover on capture target');
    207 
    208 
    209        // On entry for this sub-test, the pointer is over the capture target.
    210        await runCaptureAndHoverTargetActionSequence(t, target1);
    211        assert_next_events(
    212            target0,
    213            ['pointerout', 'pointerleave'],
    214            'Move from capture target to button');
    215        assert_next_events(
    216            captureButton,
    217            ['pointerover', 'pointerenter', 'pointermove'],
    218            'Move from capture target to button');
    219        assert_next_events(
    220            captureButton,
    221            [ 'pointerdown', 'pointerout', 'pointerleave'],
    222            'Pointer down on button to trigger capture');
    223        assert_next_events(
    224            target0,
    225            ['pointerover', 'pointerenter', 'gotpointercapture', 'pointermove'],
    226            'Capture triggered while hovering over non-capture target');
    227        assert_next_events(
    228            target0,
    229            ['lostpointercapture', 'pointerout', 'pointerleave'],
    230            'Lose pointer capture while hovering over non-capture target');
    231        assert_next_events(
    232            target1,
    233            ["pointerover", "pointerenter"],
    234            'Post capture while hovering over non-capture target');
    235        assert_empty_event_queue('Check after hover on non-capture target ');
    236      }, 'Test pointer capture.');
    237    };
    238  </script>
    239 </html>