<html>
  <head>
    <meta name="viewport" content="width=device-width" />
  </head>
  <body>
    <form action="about:blank">
      <input id="input_text" type="text" size="10"/>
      <br/>
    </form>
    <form>
      <textarea id="textarea" rows="4" cols="20"></textarea>
      <br/>
      <textarea id="textarea2" rows="4" cols="20" autocomplete="off"></textarea>
      <br/>
      <input id="input_number1" type="number" /><br/>
      <input id="input_number2" type="number" /><br/>
      <br/>
      <span id="plain_text">This is Plain Text One</span><br/>
      <br/>
      <div id="contenteditable1" contenteditable>contenteditable1</div>
      <br/>
      <input id="search1" type="search" size="10" size="10"/>
      <br/>
      <input id="input_text1" type="text" size="10" size="10"/><br/>
      <input id="input_radio" type="radio" style="width:50px;height:50px" /><br/>
      <br/>
    </form>

    <!-- We may trigger different sets of events for CONTENTEDITABLE and INPUT / TEXTAREA -->
    <div id="contenteditable_event" contenteditable><b>ab</b>cd<i>ef<b>gh</b></i></div>
    <a id="link" href="about:blank">hello</a>

    <script>
var selectionChangeEventLog = "";
var otherEventLog = "";
var mutationObserver = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    addEventLog(mutation.type, mutation.detail);
  });
})

var mutationConfig = { attributes: false, childList: false, characterData: true };

function addOtherEventLog(type, detail) {
  if (otherEventLog.length > 0) {
    otherEventLog += ',';
  }
  if (detail == null) {
    otherEventLog += type;
  } else {
    otherEventLog += type + '(' + detail + ')';
  }
}

function addSelectionChangeEventLog(type, detail) {
  if (selectionChangeEventLog.length > 0) {
    selectionChangeEventLog += ',';
  }
  if (detail == null) {
    selectionChangeEventLog += type;
  } else {
    selectionChangeEventLog += type + '(' + detail + ')';
  }
}

// selectionchange event is queued, so it races with the other events.
// crbug.com/628964
function getEventLogs() {
  if (otherEventLog.length > 0 && selectionChangeEventLog.length > 0)
    return otherEventLog + ',' + selectionChangeEventLog;
  return otherEventLog + selectionChangeEventLog;
}

function clearEventLogs() {
  selectionChangeEventLog = '';
  otherEventLog = '';
}

function addEventListener(element, event_name) {
  element.addEventListener(event_name, function (e) { addOtherEventLog(event_name, e.data); });
}

function addKeyEventListener(element, event_name) {
  element.addEventListener(event_name, function (e) { addOtherEventLog(event_name, e.keyCode); });
}

function addSelectionEventListener(event_name) {
  // Note that listeners added to the element are not effective for now.
  document.addEventListener(event_name, function (e) { addSelectionChangeEventLog(event_name, e.data); });
}

function registerListenersAndObserver(element) {
  addKeyEventListener(element, "keydown");
  addKeyEventListener(element, "keypress");
  addKeyEventListener(element, "keyup");
  addEventListener(element, "compositionstart");
  addEventListener(element, "compositionupdate");
  addEventListener(element, "compositionend");
  addEventListener(element, "beforeedit");
  addEventListener(element, "edit");
  addEventListener(element, "select");
  addEventListener(element, "change");
  addEventListener(element, "input");
  mutationObserver.observe(element, mutationConfig);
}

var inputText = document.getElementById("input_text");
var contenteditableEvent = document.getElementById("contenteditable_event");

// SelectionEventListener should be outside registerListenersAndObserver() to avoid duplication.
addSelectionEventListener("selectionchange");

registerListenersAndObserver(inputText);
registerListenersAndObserver(contenteditableEvent);
    </script>

  </body>
</html>
