view script.js @ 1:eb3679d92996

put JS and CSS code in separated files
author Sonny Piers <sonny.piers@gmail.com>
date Sun, 18 Dec 2011 19:49:32 +0100
parents
children 683f56999fb3
line wrap: on
line source

//    -  Mutation Events:
//    -  https://developer.mozilla.org/en/XUL/Events#Mutation_DOM_events

var gBreadCrumb = null;
function updateBreadCrumb(node, action) {
  if (!gBreadCrumb || !node || (node == document.body)) return;
  var
    body = document.body,
    text = node.nodeName,
    tmp  = node.parentNode;
  while (tmp && tmp != body) {
    text = tmp.nodeName + " > " + text;
    tmp = tmp.parentNode;
  }
  text = action + ": " + text;
  gBreadCrumb.innerHTML = text;
  console.log(text);
}

// retrieve the startContainer of the current selection
var gLastFocusNode = null;
function getSelectionStart() {
  var node = document.getSelection().anchorNode;
  return (node.nodeName == "#text" ? node.parentNode : node);
}
function onCaretMove(event, action) {
  var selection = document.getSelection();
  var node = selection.isCollapsed ? selection.focusNode
           : selection.getRangeAt(0).commonAncestorContainer;
  if (node != gLastFocusNode) {
    updateBreadCrumb(node, action);
    gLastFocusNode = node;
  }
}

window.addEventListener("DOMContentLoaded", function() {
  gBreadCrumb = document.querySelector("#breadcrumb");

  function onAttrModified(event) { updateBreadCrumb(event.target, "keypress"); }
  function onNodeInserted(event) { updateBreadCrumb(event.target, "inserted"); }
  function onNodeRemoved(event)  { updateBreadCrumb(event.target, "removed "); }

  function onKeyUp(event) { onCaretMove(event, "keyup"); }
  function onClick(event) { onCaretMove(event, "click"); }

  // listening to mutation events on 'document' freezes Firefox :-/
  var i, editors = document.querySelectorAll("*[contenteditable]");
  for (i = 0; i < editors.length; i++) {
    // mutation events -- do we really need them?
    editors[i].addEventListener("DOMAttrModified", onAttrModified, false);
    editors[i].addEventListener("DOMNodeInserted", onNodeInserted, false);
    editors[i].addEventListener("DOMNodeRemoved",  onNodeRemoved,  false);
    // caret movements
    //editors[i].addEventListener("textinput", onKeyUp, false);
    editors[i].addEventListener("keyup",   onKeyUp, false);
    editors[i].addEventListener("mouseup", onClick, false);
  }
}, false);



// editor

var
  gActiveEditor = null, // active editing host
  gCommandDump  = null; // command dump field
function ExecCommand(toolbarElement) {
  var argVal, argStr,
    type    = toolbarElement.getAttribute("type"),
    command = toolbarElement.getAttribute("data-command");
  switch (type) {    // get the execCommand argument according to the button type
    case "button":   // toolbar button: no argument
      argVal = argStr = false;
      break;
    case "checkbox": // styleWithCSS: boolean argument
      argVal = argStr = "" + toolbarElement.checked + "";
      break;
    default:         // <select> menu: string argument
      if (!toolbarElement.selectedIndex) return;
      argVal = toolbarElement.value;
      argStr = "'" + argVal.replace("<", "&lt;").replace(">", "&gt;") + "'";
      toolbarElement.selectedIndex = 0; // reset drop-down list
  }
  document.execCommand(command, false, argVal); // send requested action
  if (gActiveEditor) gActiveEditor.focus();     // re-focus the editable element
  gCommandDump.innerHTML = "document.execCommand('" + command + "', false, '" + argStr + "');";
}
window.addEventListener("DOMContentLoaded", function() {
  var i,
    buttons = document.querySelectorAll("*[data-command]"),
    editors = document.querySelectorAll("*[contenteditable]");
  for (i = 0; i < buttons.length; i++) {
    buttons[i].onclick  = function() { ExecCommand(this); };
    buttons[i].onchange = function() { ExecCommand(this); };
  }
  for (i = 0; i < editors.length; i++)
    editors[i].onfocus = function() { gActiveEditor = this; };
  gCommandDump = document.querySelector("#execCommand");
  ExecCommand(document.querySelector("#useCSS"));
}, false);