/* * Copyright(c) 2011 * OJC Technologies * all rights reserved * @author: Jake Smith */ function ClickChooser(event) { this.x = event.pageX; this.y = event.pageY; this.getPositionInfo = function(terminalNodes) { var clickedTextNode, helper, posInfo, foundIndex; helper = new ProximityHelper(this.x, this.y); clickedTextNode = this.getClickedTextNode(terminalNodes); if (clickedTextNode == null) { posInfo = helper.getInfoFromRelation(terminalNodes); } else { foundIndex = this.specifyIndex(clickedTextNode); posInfo = new Array( helper.WITHIN, clickedTextNode, foundIndex); } return posInfo; } //-----------------------// // "Private" functions // //-----------------------// this.getClickedTextNode = function(terminalNodes) { var i, consideredNode; for (i = 0; i < terminalNodes.length; i += 1) { consideredNode = terminalNodes[i]; if (this.clickInBounds(consideredNode)) { return consideredNode; } } return null; // not in any of the terminal nodes } this.clickInBounds = function(textNode) { var i, rects, tempSpan, flag, parent; parent = textNode.parentNode; flag = false; tempSpan = makeTempSpan(textNode); parent.replaceChild(tempSpan, textNode); rects = tempSpan.getClientRects(); for (i = 0; i < rects.length; i += 1) { if (rectContains(rects[i], this.x, this.y)) { flag = true; } } parent.replaceChild(textNode, tempSpan); return flag; } this.specifyIndex = function(node) { var textLength, index, ERR; ERR = -1; textLength = node.nodeValue.length; if (textLength < 1) { index = ERR; // definitely not here } else if (textLength === 1) { index = (this.clickInBounds(node)) ? 0 : ERR; } else { // length > 1 index = this.splitAndSearch(node, textLength); } return index; } this.splitAndSearch = function(node, textLength) { var fence, index, parent; parent = node.parentNode fence = Math.ceil(textLength / 2); var newNode = node.splitText(fence); if (this.clickInBounds(node)) { index = this.specifyIndex(node); } else if (this.clickInBounds(newNode)) { index = fence + this.specifyIndex(newNode); } else { throw new Error("error: specifyIndex search"); } parent.normalize(); return index; } } // ClickChooser(event) // standalone 'helper' function function rectContains(rect, x, y) { var bool, l, r, t, b; l = rect.left + window.scrollX; r = rect.right + window.scrollX; t = Math.round(rect.top) + window.scrollY; b = Math.round(rect.bottom) + window.scrollY; // possibily rounding issues with Firefox (rect.top & bottom) if (x < l) { bool = false; } else if (x > r) { bool = false; } else if (y < t) { bool = false; } else if (y > b) { bool = false; } else { bool = true; } return bool; }