javascript keyboard buffer, part 3

Previously, we created a javascript keyboard buffer that can edit text in a static html page. Using those functions I’d like to add a buffer replay.

I would like to add an onclick event to a specified div such that it will activate the keyboard buffer and leverage the previously discussed handleKey() event handler, as well as the appendChar(el) function. E.g.,

//
// onclick event handler
// initialize this element for keyboard buffer
function initEditable() {
  selectElement(this);
  var SPECIAL = [8, 32, 37, 39, 222];
  document.onkeydown = handleKey(function(k) {return SPECIAL.contains(k)});
  document.onkeypress = handleKey(function(k) {return !SPECIAL.contains(k)});
}

targetDiv = $('target');
targetDiv.onclick = initEditable;

The function calls selectElement(this) which will need to modify the element to add a temporary link for starting a replay. Once selected, that div will be editable, I would like another temporary link that when pressed will remove all temporary links and remove the onkey events (making the div non-editable).

The following JavaScript will enable the target div to toggle between editable and non-editable:

//
// create <a> element
function newA(aid, alabel, ahref, fonclick) {
  var newA = document.createElement('a');
  newA.appendChild(document.createTextNode(alabel));
  newA.setAttribute('href', ahref);
  newA.setAttribute('id', aid);
  newA.onclick = fonclick;
  return newA;
}

//
// prepare <div>, add 'replay' and 'save' links
function selectElement(el) {
  clearSelected();
  origText = el.innerHTML;
  el.innerHTML = '';
  var newDiv = document.createElement('div');
  newDiv.innerHTML = origText;
  newDiv.setAttribute('id', 'editSelected');
  el.appendChild(newDiv);
  el.appendChild(newA('areplay', 'replay', '#', replayKeys));
  el.appendChild(newA('aclear', 'save', 'javascript:clearSelected()', null));
  el.onclick = null;
}

//
// clear any <div> that is intercepting onkey events
// and clear the buffer
function clearSelected() {
  document.onkeypress = null;
  document.onkeyup = null;
  document.onkeydown = null;
  BUFFER = [];
  bp = 0;
  var el = $('editSelected');
  if (el) {
    var oldText = el.innerHTML;
    var pel = el.parentNode;
    pel.removeChild(el);
    pel.removeChild($('areplay'));
    pel.removeChild($('aclear'));
    pel.innerHTML = oldText;
    pel.onclick = initEditable;
  }
}

When the target div is clicked it will activate the keyboard buffer such that all keystrokes will appear in the innerHTML of that div and link to a replayKeys() function. The replayKeys() function simply needs to process the BUFFER according to a timer, e.g.,

TIMER = 100;
//
// replay all keystrokes from buffer
function replayKeys() {
  el = $('editSelected');
  el.innerHTML = origText;
  bp = 0;
  replaying = setInterval(replayHandler, TIMEOUT);
}
function replayHandler() {
  el = $('editSelected');
  if (bp < BUFFER.length) {
    appendChar(el);
  } else {
    replaying ? clearInterval(replaying) : false;
  }
}

The built-in setInterval() function will call a specified function periodically according to the TIMEOUT value in milliseconds, and will continue running until the clearInterval() function is called.

Next, I’d like to combine all of this into a single JavaScript include such that it can register multiple editable div’s.