<!doctype html>
<html>
  <head>
    <title>Pointer Event: Boundary compatibility events for multiple primary pointers</title>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
    <link rel="author" title="Google" href="http://www.google.com "/>
    <meta name="assert" content="When more than one primary pointers are active, each will have an independent sequence of pointer boundary events but the compatibilty mouse boundary events have their own sequence."/>
    <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
    <script type="text/javascript" src="pointerevent_support.js"></script>
    <script type="text/javascript">
      var test_pointerEvent = async_test("Multi-pointer boundary compat events");
      add_completion_callback(end_of_test);

      var detected_pointertypes = {};
      var event_log = [];

      // These two ids help us detect two different pointing devices.
      var first_entry_pointer_id = -1;
      var second_entry_pointer_id = -1;

      // Current node for each pointer id
      var current_node_for_id = {};

      function end_of_test() {
          showLoggedEvents();
          showPointerTypes();
      }

      function end_of_interaction() {
          test(function () {
              assert_equals(event_log.join(", "),
                  "mouseover@target0, mouseenter@target0, mouseout@target0, mouseleave@target0, " +
                  "mouseover@target1, mouseenter@target1, mouseout@target1, mouseleave@target1, " +
                  "mouseover@target0, mouseenter@target0, mouseout@target0, mouseleave@target0"
              );
          }, "Event log");

          test_pointerEvent.done(); // complete test
      }

      function log_event(label) {
          event_log.push(label);
      }

      function run() {
          on_event(document.getElementById("done"), "click", end_of_interaction);

          var target_list = ["target0", "target1"];
          var pointer_event_list = ["pointerenter", "pointerleave", "pointerover", "pointerout", "pointerdown"];
          var mouse_event_list = ["mouseenter", "mouseleave", "mouseover", "mouseout"];

          target_list.forEach(function(targetId) {
              var target = document.getElementById(targetId);

              pointer_event_list.forEach(function(eventName) {
                  on_event(target, eventName, function (event) {
                      var label = event.type + "@" + targetId;

                      detected_pointertypes[event.pointerType] = true;

                      if (!event.isPrimary) {
                          test(function () {
                              assert_unreached("Non-primary pointer " + label);
                          }, "Non-primary pointer " + label);
                      }

                      if (event.type === "pointerenter") {
                          var pointer_id = event.pointerId;
                          if (current_node_for_id[pointer_id] !== undefined) {
                              test(function () {
                                  assert_unreached("Double entry " + label);
                              }, "Double entry " + label);
                          }
                          current_node_for_id[pointer_id] = event.target;

                          // Test that two different pointing devices are used
                          if (first_entry_pointer_id === -1) {
                              first_entry_pointer_id = pointer_id;
                          } else if (second_entry_pointer_id === -1) {
                              second_entry_pointer_id = pointer_id;
                              test(function () {
                                  assert_true(first_entry_pointer_id !== second_entry_pointer_id);
                              }, "Different pointing devices");
                          }
                      } else if (event.type === "pointerleave") {
                          var pointer_id = event.pointerId;
                          if (current_node_for_id[pointer_id] !== event.target) {
                              test(function () {
                                  assert_unreached("Double exit " + label);
                              }, "Double exit " + label);
                          }
                          current_node_for_id[pointer_id] = undefined;
                      }
                  });
              });

              mouse_event_list.forEach(function(eventName) {
                  on_event(target, eventName, function (event) {
                      log_event(event.type + "@" + targetId);
                  });
              });
          });
      }
    </script>
    <style>
      #target0, #target1 {
        margin: 20px;
      }

      #done {
        margin: 20px;
        border: 2px solid black;
      }
  </style>
  </head>
  <body onload="run()">
    <h1>Pointer Event: Boundary compatibility events for multiple primary pointers</h1>
    <h4>
      When more than one primary pointers are active, each will have an independent sequence of pointer boundary events but the compatibilty mouse boundary events have their own sequence.
    </h4>
    Instruction:
    <ol>
      <li>Move the mouse directly into Target0 (without going through Target1), and then leave the mouse there unmoved.</li>
      <li>Tap directly on Target1 with a finger or a stylus, and then lift the finger/stylus off the screen/digitizer without crossing Target1 boundary.</li>
      <li>Move the mouse into Target0 (if not there already) and move inside it.</li>
      <li>Click Done (without passing over Target1).</li>
    </ol>
    <div id="done">
      Done
    </div>
    <div id="target0">
      Target0
    </div>
    <div id="target1">
      Target1
    </div>
    <div id="complete-notice">
      <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
      <p>The following events were logged: <span id="event-log"></span>.</p>
    </div>
    <div id="log"></div>
  </body>
</html>
