<!doctype html>
<!-- Modified from rbyers.github.io/eventTest.js

Changes were to remove some elements which don't make sense in this context,
including UI to toggle events and various non-mouse, keyboard, touch events.
There were also some formatting changes.  Finally, some test-friendly functions
like clearPreviousEvents() were added.

Add event handlers for all mouse, touch, and keyboard events.  Log any events
seen.  Intended to be queried by an autotest after input playback.

-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>Touch Event Test Page</title>
<script type="text/javascript">
var pageReady = false; // Used to determine whether test can run yet.
var lastEvent; // The last event seen.
var eventCount = 0; // Count of events seen.
var timeOfLastEvent; // Timestamp of when last event occurred.
var netScrollDelta = {x: 0, y: 0}; // Net scroll seen.
var clickCount = 0; // Total number of clicks seen.
var eventLog = ''; // Log of all events seen.
var preventDefaults = true; // Boolean whether to prevent default events.


// Reset previously seen events.
function clearPreviousEvents() {
  lastEvent = undefined;
  eventCount = 0;
  timeOfLastEvent = undefined;
  netScrollDelta = {x: 0, y: 0};
  clickCount = 0;
  eventLog = '';
  pageReady = true;
}

// Add the given event and message to the running eventLog.
function logEvent(event, msg) {
  eventCount += 1;
  if (!msg) {
    msg = '';
  }
  if (timeOfLastEvent && event.timeStamp) {
    msg += ' timeDelta=' + round(event.timeStamp - timeOfLastEvent) + 'ms';
  }
  timeOfLastEvent = event.timeStamp;
  lastEvent = event;
  msg = event.type + ': ' + msg + '\n';
  eventLog += msg;
  console.log(msg);
}

// Call preventDefault() on the event if preventDefaults is set.
function preventDefault(event) {
  if (preventDefaults) {
    event.preventDefault();
  }
}

// Round the given value to 2 decimal places.
function round(val) {
  return Math.round(val * 100) / 100;
}

// addEventListener with the given handler for the given event types.
function setHandlerState(events, handler) {
  for (var i = 0; i < events.length; i++) {
    document.addEventListener(events[i], handler);
  }
};

// mouse event handler
function mouseEventHandler(event)
{
  var msg = '';
  if (event.type == 'click') {
    clickCount += 1;
  }
  if (event.type == 'mousewheel') {
    msg += ', wheelDelta=' + round(event.wheelDelta) +
        ' (' + round(event.wheelDeltaX) + ',' +
        round(event.wheelDeltaY) + ')';
    netScrollDelta.x += event.wheelDeltaX;
    netScrollDelta.y += event.wheelDeltaY;
  }
  if (event.type == 'wheel') {
    msg += ', deltaX=' + round(event.deltaX) + ', deltaY=' +
        round(event.deltaY) + ', deltaZ=' + round(event.deltaZ);
    netScrollDelta.x += event.deltaX;
    netScrollDelta.y += event.deltaY;
  }
  if (event.type == 'mousewheel' || event.type == 'wheel') {
    msg += ', deltaMode=' + (
        event.deltaMode == 0 ? 'PIXEL' :
        event.deltaMode == 1 ? 'LINE' :
        event.deltaMode == 2 ? 'PAGE' :
        event.deltaMode);
  }
  if (event.type.toLowerCase().indexOf('pointer') != -1) {
    msg += ', pointerType=' + event.pointerType + ', pointerId=' +
        event.pointerId + ', width=' + round(event.width) +
        ', height=' + round(event.height) + ', pressure=' +
        round(event.pressure) + ', tiltX=' + round(event.tiltX) +
        ', tiltY=' + round(event.tiltY);
  }

  msg = ' client=' + round(event.clientX) + ',' + round(event.clientY) +
      ' screen=' + round(event.screenX) + ',' + round(event.screenY) +
      ' button=' + event.button + ' buttons=' + event.buttons +
      ' detail=' + event.detail + ' cancelable=' +
      event.cancelable + msg;

  preventDefault(event);
  logEvent(event, msg);
}

// Helper function for touch handler.
function makeTouchList(touches, verbose) {
  var touchStr = '';
  for (var i = 0; i < touches.length; i++) {
    var tgt = '';
    if (i > 0)
      touchStr += ' ';

    if (verbose)
      tgt = '-' + touches[i].target.id;
    var id = touches[i].identifier;
    if (id >= 100) {
      if (!(id in touchMap)) {
        touchMap[id] = nextId;
        nextId++;
      }
      id = '#' + touchMap[id];
    }

    touchStr += id + tgt;
  }
  return touchStr;
}

activeTouchData = {};

// Touch event handler.
function touchEventHandler(event) {
  var touchStr =
      ' touches=' + makeTouchList(event.touches, true) +
      ' changed=' + makeTouchList(event.changedTouches) +
      ' target=' + makeTouchList(event.targetTouches) +
      ' cancelable=' + event.cancelable;

  preventDefault(event);
  logEvent(event, touchStr);

  for (var i = 0; i < event.changedTouches.length; i++) {
    var touch = event.changedTouches[i];

    if (event.type == 'touchstart') {
      var touchData = {
        startTime: event.timeStamp,
        startX: touch.screenX,
        startY: touch.screenY,
        maxDist: 0,
        maxMDist: 0
      };
      activeTouchData[touch.identifier] = touchData;
    } else {
      var touchData = activeTouchData[touch.identifier];
      var distX = Math.abs(touch.screenX - touchData.startX);
      var distY = Math.abs(touch.screenY - touchData.startY);
      touchData.maxDist = Math.max(touchData.maxDist,
          Math.sqrt(distX * distX + distY * distY));
      touchData.maxMDist = Math.max(touchData.maxMDist, distX + distY);
      if (event.type == 'touchend') {
        msg = ('touch ' + touch.identifier + ' summary:' +
               ' dist=(' + distX + ',' + distY + ')' +
               ' max-dist=' + Math.round(touchData.maxDist) +
               ' max-manhattan-dist=' + touchData.maxMDist +
               ' dur=' + (Math.round(event.timeStamp - touchData.startTime)));
        logEvent(event, msg);
        delete activeTouchData[touch.identifier];
      }
    }
  }
}

// Key event handler.
function keyEventHandler(event) {
  var msg = '';
  if ('charCode' in event)
    msg += ' charCode=' + event.charCode;
  if ('keyCode' in event)
    msg += ' keyCode=' + event.keyCode;
  if ('key' in event)
    msg += ' key=' + event.key;
  if ('code' in event)
    msg += ' code=' + event.code;
  if ('location' in event) {
    if (event.location == KeyboardEvent.DOM_KEY_LOCATION_LEFT)
      msg += ' LOCATION_LEFT';
    else if (event.location == KeyboardEvent.DOM_KEY_LOCATION_NUMPAD)
      msg += ' LOCATION_NUMPAD';
    else if (event.location == KeyboardEvent.DOM_KEY_LOCATION_RIGHT)
      msg += ' LOCATION_RIGHT';
  }
  if (event.repeat)
    msg += ' repeat';
  if (event.isComposing)
    msg += ' isComposing';

  preventDefault(event);
  logEvent(event, msg);
}


// On load, set handlers for mouse, touch, and key events.
function onLoad() {
  setHandlerState(
      ['click', 'dblclick', 'contextmenu', 'mousedown', 'mouseup',
      'mouseover', 'mousemove', 'mouseout', 'mouseenter', 'mouseleave',
      'mousewheel', 'wheel'],
      mouseEventHandler);

  setHandlerState(
      ['dragstart', 'dragenter', 'dragleave', 'drop', 'dragend'],
      mouseEventHandler);

  setHandlerState(
      ['touchstart', 'touchmove', 'touchend', 'touchcancel'],
      touchEventHandler);

  setHandlerState(
      ['keydown', 'keyup', 'keypress'],
      keyEventHandler);

  pageReady = true;
}

</script>
</head>
<body onload="onLoad()">
</body>
</html>
