﻿<!doctype html>
<meta charset=utf-8>
<html>
<head>
    <title>Test Actions</title>
    <style>
      div { padding:0px; margin: 0px; }
      #trackPointer { position: fixed; }
      #resultContainer { width: 600px; height: 60px; }
      .area { width: 100px; height: 50px; background-color: #ccc; }
      .block { width: 5px; height: 5px; border: solid 1px red; }
      .box { display: flex;}
      #dragArea { position: relative; }
      #dragTarget { position: absolute; top:22px; left:47px;}
    </style>
    <script>
        "use strict";
        var els = {};
        var allEvents = { events: [] };
        function displayMessage(message) {
            document.getElementById("events").innerHTML = "<p>" + message + "</p>";
        }

        function appendMessage(message) {
            document.getElementById("events").innerHTML += "<p>" + message + "</p>";
        }

        /**
         * Escape |key| if it's in a surrogate-half character range.
         *
         * Example: given "\ud83d" return "U+d83d".
         *
         * Otherwise JSON.stringify will convert it to U+FFFD (REPLACEMENT CHARACTER)
         * when returning a value from executeScript, for example.
         */
        function escapeSurrogateHalf(key) {
          if (typeof key !== "undefined" && key.length === 1) {
            var charCode = key.charCodeAt(0);
            var highSurrogate = charCode >= 0xD800 && charCode <= 0xDBFF;
            var surrogate = highSurrogate || (charCode >= 0xDC00 && charCode <= 0xDFFF);
            if (surrogate) {
              key = "U+" + charCode.toString(16);
            }
          }
          return key;
        }

        function recordKeyboardEvent(event) {
          var key = escapeSurrogateHalf(event.key);
          allEvents.events.push({
            "code": event.code,
            "key": key,
            "which": event.which,
            "location": event.location,
            "ctrl": event.ctrlKey,
            "meta": event.metaKey,
            "shift": event.shiftKey,
            "repeat": event.repeat,
            "type": event.type
          });
          appendMessage(event.type + " " +
              "code: " + event.code + ", " +
              "key: " + key + ", " +
              "which: " + event.which + ", " +
              "keyCode: " + event.keyCode);
        }

        function recordPointerEvent(event) {
          if (event.type === "contextmenu") {
            event.preventDefault();
          }
          allEvents.events.push({
            "type": event.type,
            "button": event.button,
            "buttons": event.buttons,
            "pageX": event.pageX,
            "pageY": event.pageY,
            "ctrlKey": event.ctrlKey,
            "metaKey": event.metaKey,
            "altKey": event.altKey,
            "shiftKey": event.shiftKey,
            "target": event.target.id
          });
          appendMessage(event.type + " " +
              "button: " + event.button + ", " +
              "pageX: " + event.pageX + ", " +
              "pageY: " + event.pageY + ", " +
              "button: " + event.button + ", " +
              "buttons: " + event.buttons + ", " +
              "ctrlKey: " + event.ctrlKey + ", " +
              "altKey: " + event.altKey + ", " +
              "metaKey: " + event.metaKey + ", " +
              "shiftKey: " + event.shiftKey + ", " +
              "target id: " + event.target.id);
        }

        function recordFirstPointerMove(event) {
          recordPointerEvent(event);
          window.removeEventListener("mousemove", recordFirstPointerMove);
        }

        function grabOnce(event) {
          grab(event);
          els.dragTarget.removeEventListener("mousedown", grabOnce);
        }

        function dropOnce(moveHandler) {
          return function (event) {
            moveHandler(event);
            els.dragArea.removeEventListener("mouseup", dropOnce);
          }
        }

        function resetEvents() {
          allEvents.events.length = 0;
          displayMessage("");
        }

        function drop(moveHandler) {
          return function (event) {
            els.dragArea.removeEventListener("mousemove", moveHandler);
            els.dragTarget.style.backgroundColor = "yellow";
            els.dragTarget.addEventListener("mousedown", grab);
            recordPointerEvent(event);
          };
        }

        function move(el, offsetX, offsetY, timeout) {
          return function(event) {
            setTimeout(function() {
              el.style.top = event.clientY + offsetY + "px";
              el.style.left = event.clientX + offsetX + "px";
            }, timeout);
          };
        }

        function grab(event) {
          event.target.style.backgroundColor = "red";
          let boxRect = event.target.getBoundingClientRect();
          let areaRect = event.target.parentElement.getBoundingClientRect();
          let moveHandler = move(
              event.target,
              // coordinates of dragTarget must be relative to dragArea such that
              // dragTarget remains under the pointer
              -(areaRect.left + (event.clientX - boxRect.left)),
              -(areaRect.top + (event.clientY - boxRect.top)),
              20);
          els.dragArea.addEventListener("mousemove", moveHandler);
          els.dragArea.addEventListener("mouseup", dropOnce(drop(moveHandler)));
        }

        document.addEventListener("DOMContentLoaded", function() {
          var keyReporter = document.getElementById("keys");
          keyReporter.addEventListener("keyup", recordKeyboardEvent);
          keyReporter.addEventListener("keypress", recordKeyboardEvent);
          keyReporter.addEventListener("keydown", recordKeyboardEvent);

          var outer = document.getElementById("outer");
          outer.addEventListener("click", recordPointerEvent);
          outer.addEventListener("dblclick", recordPointerEvent);
          outer.addEventListener("mousedown", recordPointerEvent);
          outer.addEventListener("mouseup", recordPointerEvent);
          outer.addEventListener("contextmenu", recordPointerEvent);

          window.addEventListener("mousemove", recordFirstPointerMove);
          //visual cue for mousemove
          var pointer = document.getElementById("trackPointer");
          window.addEventListener("mousemove", move(pointer, 15, 15, 30));
          // drag and drop
          els.dragArea = document.getElementById("dragArea");
          els.dragArea.addEventListener("dragstart", recordPointerEvent);
          els.dragTarget = document.getElementById("dragTarget");
          els.dragTarget.addEventListener("mousedown", grabOnce);

          var draggable = document.getElementById("draggable");
          draggable.addEventListener("dragstart", recordPointerEvent);
          draggable.addEventListener("dragenter", recordPointerEvent);
          draggable.addEventListener("dragend", recordPointerEvent);
          draggable.addEventListener("dragleave", recordPointerEvent);
          draggable.addEventListener("dragover", recordPointerEvent);

          var droppable = document.getElementById("droppable");
          droppable.addEventListener("drop", recordPointerEvent);
        });
    </script>
</head>
<body>
  <div id="trackPointer" class="block"></div>
  <div>
    <h2>KeyReporter</h2>
    <input type="text" id="keys" size="80">
  </div>
  <div>
    <h2>ClickReporter</h2>
    <div id="outer" class="area">
    </div>
  </div>
  <div>
    <h2>DragReporter</h2>
    <div id="dragArea" class="area">
      <div id="dragTarget" class="block"></div>
    </div>
  </div>
  <div>
    <h2>draggable</h2>
    <div class=box>
      <div id=draggable draggable="true" class="area"></div>&nbsp;
      <div id=droppable dropzone="true" class="area"></div>
    </div>
  </div>
  <div id="resultContainer">
    <h2>Events</h2>
    <div id="events"></div>
  </div>
</body>
</html>
