<!doctype html>
<html>
  <head>
    <title>Pointer Events properties tests</title>
    <meta name="viewport" content="width=device-width">
    <meta name="variant" content="?mouse">
    <meta name="variant" content="?pen">
    <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script src="/resources/testdriver.js"></script>
    <script src="/resources/testdriver-actions.js"></script>
    <script src="/resources/testdriver-vendor.js"></script>
    <!-- Additional helper script for common checks across event types -->
    <script type="text/javascript" src="pointerevent_support.js"></script>
    <script>
      var input_pointertype = location.search.substring(1);
      var detected_eventTypes = {};
      var eventList = [
          'pointerover', 'pointerenter', 'pointermove', 'pointerdown',
          'pointerup', 'pointerout', 'pointerleave'
      ];
      var expectedPointerId = NaN;

      function resetTestState() {
        detected_eventTypes = {};
        document.getElementById("square1").style.visibility = 'visible';
        document.getElementById('innerFrame').contentDocument
            .getElementById("square2").style.visibility = 'hidden';
        expectedPointerId = NaN;
      }
      function checkPointerEventAttributes(
          event, targetBoundingClientRect, testNamePrefix) {
        if (detected_eventTypes[event.type])
          return;
        var expectedEventType =
            eventList[Object.keys(detected_eventTypes).length];
        detected_eventTypes[event.type] = true;
        var pointerTestName = (testNamePrefix ? testNamePrefix + ' ' : '')
          + expectedPointerType + ' ' + expectedEventType;

        test(function() {
          assert_equals(event.type, expectedEventType);
        }, pointerTestName + "'s type should be " + expectedEventType);

        // Test button and buttons
        if (event.type == 'pointerdown') {
          test(function() {
            assert_equals(event.button, 2);
          }, pointerTestName + "'s button attribute is 2 when right mouse "
              + "button is pressed.");
          test(function() {
            assert_equals(event.buttons, 2);
          }, pointerTestName + "'s buttons attribute is 2 when right mouse "
              + "button is pressed.");
        } else if (event.type == 'pointerup') {
          test(function() {
            assert_equals(event.button, 2);
          }, pointerTestName + "'s button attribute is 0 when right mouse "
              + "button is just released.");
          test(function() {
            assert_equals(event.buttons, 0);
          }, pointerTestName + "'s buttons attribute is 0 when right mouse "
              + "button is just released.");
        } else {
          test(function() {
            assert_equals(event.button, -1);
          }, pointerTestName + "'s button is -1 when mouse buttons are in "
              + "released state.");
          test(function() {
            assert_equals(event.buttons, 0);
          }, pointerTestName + "'s buttons is 0 when mouse buttons are in "
              + "released state.");
        }

        // Test clientX and clientY
        if (event.type != 'pointerout' && event.type != 'pointerleave' ) {
          test(function () {
            assert_greater_than_equal(
                event.clientX, targetBoundingClientRect.left,
                "clientX should be greater or equal than left of the box");
            assert_greater_than_equal(
                event.clientY, targetBoundingClientRect.top,
                "clientY should be greater or equal than top of the box");
            assert_less_than_equal(
                event.clientX, targetBoundingClientRect.right,
                "clientX should be less or equal than right of the box");
            assert_less_than_equal(
                event.clientY, targetBoundingClientRect.bottom,
                "clientY should be less or equal than bottom of the box");
          }, pointerTestName + "'s ClientX and ClientY attributes are correct.");
        } else {
          test(function () {
            assert_true(
                event.clientX < targetBoundingClientRect.left
                    || event.clientX >= targetBoundingClientRect.right
                    || event.clientY < targetBoundingClientRect.top
                    || event.clientY >= targetBoundingClientRect.bottom,
                "ClientX/Y should be out of the boundaries of the box");
          }, pointerTestName + "'s ClientX and ClientY attributes are correct.");
        }

        check_PointerEvent(event, testNamePrefix);

        // Test isPrimary
        test(function () {
          assert_equals(event.isPrimary, true);
        }, pointerTestName + ".isPrimary attribute is correct.");

        // Test pointerId value
        if (isNaN(expectedPointerId)) {
          expectedPointerId = event.pointerId;
        } else {
          test(function () {
            assert_equals(event.pointerId, expectedPointerId);
          }, pointerTestName + ".pointerId should be the same as previous "
              + "pointer events for this active pointer.");
        }
      }

      async function run() {
        var test_pointerEvent = setup_pointerevent_test(
            "pointerevent attributes", [input_pointertype]);
        var square1 = document.getElementById("square1");
        var rectSquare1 = square1.getBoundingClientRect();
        var innerFrame = document.getElementById('innerFrame');
        var square2 = innerFrame.contentDocument.getElementById('square2');
        var rectSquare2 = square2.getBoundingClientRect();
        var actions_promise;

        eventList.forEach(function(eventName) {
          on_event(square1, eventName, function (event) {
            if (square1.style.visibility == 'hidden')
              return;
            checkPointerEventAttributes(event, rectSquare1, "");
            if (Object.keys(detected_eventTypes).length == eventList.length) {
              square1.style.visibility = 'hidden';
              detected_eventTypes = {};
              square2.style.visibility = 'visible';
              expectedPointerId = NaN;
            }
          });
          on_event(square2, eventName, function (event) {
            checkPointerEventAttributes(event, rectSquare2, "Inner frame");
            if (Object.keys(detected_eventTypes).length == eventList.length) {
              square2.style.visibility = 'hidden';
              test_pointerEvent.done();
            }
          });
        });

        // Inject mouse or pen inputs.
        await rightClickInTarget(input_pointertype, square1);
        await moveToDocument(input_pointertype);
        await rightClickInTarget(input_pointertype, square2);
        await moveToDocument(input_pointertype);
      }
    </script>
  </head>
  <body onload="run()">
    <h1>Pointer Events hoverable pointer attributes test</h1>
    <h2 id="pointerTypeDescription"></h2>
    <div id="square1" class="square"></div>
    <iframe id="innerFrame"
        src="resources/pointerevent_attributes_hoverable_pointers-iframe.html">
    </iframe>
  </body>
</html>
