/* * Copyright(c) 2011 * OJC Technologies * all rights reserved * @author: Jake Smith */ function RealCursor(sideIndicator) { this.LEFT = "left"; this.RIGHT = "right"; this.isVirtual = false; this.side = sideIndicator; this.softret = document.createElement("span"); this.softret.setAttribute("id", this.side.toString() + "softreturn"); this.cursor = new PhysicalCursor("span", this.side.toString() + "cursorspan", this.side == "right" ? "cyan" : "orange"); this.atStartOfPage = false; this.atEndOfPage = false; this.parentNode = null; this.startOff = null; this.endOff = null; this.overText = false; this.isTarget = function(clickTargetElement) { // TODO: deal with floating cursor objects return (this.cursor.element == clickTargetElement); } this.placeAt = function(node, startOffset, endOffset) { var before, after, range, string; string = node.nodeValue; this.parentNode = node.parentNode; range = string.substring(startOffset, endOffset); before = string.substring(0, startOffset); after = string.substring(endOffset); range = document.createTextNode(range); before = document.createTextNode(before); after = document.createTextNode(after); this.startOff = startOffset; this.endOff = endOffset; this.cursor.push(range); this.parentNode.replaceChild(after, node); this.parentNode.insertBefore(this.cursor.element, after); this.parentNode.insertBefore(before, this.cursor.element); this.parentNode.normalize(); this.printWidth(); } this.remove = function() { var textNode; textNode = this.cursor.pop(); if (textNode == null || this.atEndOfPage) { this.parentNode.removeChild(this.cursor.element); } else { this.parentNode.replaceChild(textNode, this.cursor.element); this.parentNode.normalize(); this.parentNode = null; this.atStartOfPage = false; this.atEndOfPage = false; this.startOff = null; this.endOff = null; } } this.insert = function(text) { var textNode; textNode = document.createTextNode(text); this.parentNode.insertBefore(textNode, this.cursor.element); this.parentNode.normalize(); } this.del = function() { this.cursor.pop(); this.rightSideGoesRight(); } this.bksps = function() { this.cursor.pop(); this.leftSideGoesLeft(); } this.isCollapsed = function() { var functor; functor = new CursorFunctor(); return functor.isNodeCollapsed(this.cursor.element); } this.moveLeft = function() { var tempNode; if (this.atStartOfPage) { // TODO return; } if (this.isVirtual) { this.isVirtual = false; this.removeSoftReturn(); } tempNode = this.cursor.pop(); if (this.atEndOfPage) { //dumps EOL/EOF indicator this.atEndOfPage = false; } else { if (this.cursor.element.nextSibling == null) { this.parentNode.appendChild(tempNode); } else { this.parentNode.insertBefore(tempNode, this.cursor.element.nextSibling); } } this.leftSideGoesLeft(); if (this.isCollapsed()) { this.isVirtual = this.insertSoftReturn(); } this.printWidth(); } this.removeSoftReturn = function() { printer.print("enter removeSoftReturn"); printer.print("this.softret.parentNode = " + this.softret.parentNode); this.softret.parentNode.replaceChild(this.softret.firstChild, this.softret); printer.print("exit removeSoftReturn"); } this.insertSoftReturn = function() { var functor, p; return false; printer.print("enter insertSoftReturn"); functor = new CursorFunctor(); for (p = functor.getNodePreceding(this.cursor.element); p != null; p = functor.getNodePreceding(p)) { printer.print("p = " + p.toString()); if (p.parentNode == null) continue; p.parentNode.replaceChild(this.softret, p); printer.print("1"); this.softret.appendChild(p); printer.print("2"); if (!functor.isNodeCollapsed(this.softret)) break; printer.print("3"); this.softret.parentNode.replaceChild(p, this.softret); printer.print("4"); } if (p == null) { printer.print("exit insertSoftReturn false"); return false; } else { printer.print("exit insertSoftReturn true"); return true; } } this.moveRight = function() { var tempNode; if (this.atEndOfPage) { // TODO return; } tempNode = this.cursor.pop(); if (this.atStartOfPage) { this.atStartOfPage = false; } else { this.parentNode.insertBefore(tempNode, this.cursor.element); } this.rightSideGoesRight(); this.printWidth(); } this.overBreakingWS = function() { var functor, cursorText, result; result = false; functor = new CursorFunctor(); cursorText = this.cursor.contents.nodeValue; if (functor.isBreakingWhitespace(cursorText)) { result = true; } return result; } this.overChar = function() { var functor, result, cursorText; result = false; functor = new CursorFunctor(); cursorText = this.cursor.contents.nodeValue; if (!functor.isWhitespace(cursorText)) { result = true; } return result; } this.overNonBreakWS = function() { var functor, cursorText, result; result = false; functor = new CursorFunctor(); cursorText = this.cursor.contents.nodeValue; if (functor.isNBSP(cursorText)) { result = true; } return result; } //-----------------------// // "Private" functions // //-----------------------// this.rightSideGoesRight = function() { var nextSib, tempNode, selectorEnd; var tempText, selText, functor, nextNode; functor = new CursorFunctor(); nextSib = this.cursor.element.nextSibling; nextNode = functor.getNodeFollowing(this.cursor.element); if (nextNode == null) { //at end of page tempNode = document.createTextNode("_"); this.cursor.push(tempNode); this.atEndOfPage = true; } else if (nextNode == nextSib) { // within-node shifting right if (nextSib.nodeType == Node.TEXT_NODE) { tempText = nextSib.nodeValue; if (functor.isToPreserveWhitespace(this.parentNode)) { selectorEnd = 1; } else { selectorEnd = functor.getEndOffset(tempText, 0); } selText = tempText.substring(0, selectorEnd); tempText = tempText.substring(selectorEnd); tempNode = document.createTextNode(tempText); this.parentNode.replaceChild(tempNode, nextSib); tempNode = document.createTextNode(selText); this.cursor.push(tempNode); } else { this.placeOverNonTextNode(nextNode); } } else { // jumping elements this.parentNode.removeChild(this.cursor.element); if (nextNode.nodeType != Node.TEXT_NODE) { this.placeOverNonTextNode(nextNode); } else { tempText = nextNode.nodeValue if (functor.isToPreserveWhitespace(this.parentNode)) { selectorEnd = 1; } else { selectorEnd = functor.getEndOffset(tempText, 0); } this.parentNode = nextNode.parentNode; this.placeAt(nextNode, 0, selectorEnd); } } this.parentNode.normalize(); } this.leftSideGoesLeft = function() { var functor, prevSib, prevNode, tempText; var selectorStart, tempNode, selText; functor = new CursorFunctor(); prevSib = this.cursor.element.previousSibling; prevNode = functor.getNodePreceding(this.cursor.element); if (prevNode == null) { if (false) { tempNode = document.createTextNode("$"); this.cursor.push(tempNode); } this.atStartOfPage = true; } else if (prevNode == prevSib) { if (prevNode.nodeType != Node.TEXT_NODE) { this.placeOverNonTextNode(prevNode); } else { tempText = prevSib.nodeValue; if (functor.isToPreserveWhitespace(this.parentNode)) { selectorStart = tempText.length - 1; } else { selectorStart = functor.getStartOffset(tempText, tempText.length - 1); } selText = tempText.substring(selectorStart); tempText = tempText.substring(0, selectorStart); tempNode = document.createTextNode(tempText); this.parentNode.replaceChild(tempNode, prevSib); tempNode = document.createTextNode(selText); this.cursor.push(tempNode); } } else { //jumping nodes this.parentNode.removeChild(this.cursor.element); if (prevNode.nodeType != Node.TEXT_NODE) { this.placeOverNonTextNode(prevNode); } else { tempText = prevNode.nodeValue if (functor.isToPreserveWhitespace(this.parentNode)) { selectorStart = tempText.length - 1; } else { selectorStart = functor.getStartOffset(tempText, tempText.length - 1); } this.placeAt(prevNode, selectorStart, tempText.length); } } this.parentNode.normalize(); } this.placeOverNonTextNode = function(nextNode) { var tempNode; tempNode = nextNode; this.parentNode = nextNode.parentNode; this.parentNode.replaceChild(this.cursor.element, nextNode); this.cursor.push(tempNode); this.startOff = 0; this.endOff = 1; printer.print(this.side + "cursor over non-TextNode"); } this.printWidth = function() { var rect; rect = this.cursor.element.getBoundingClientRect(); printer.print(this.side + " cursor width: " + rect.width); } } // RealCursor()