steal('jquery', 'jquery/dom/compare').then(function ($){ $.fn.range = function (){ return $.Range(this[0]); } ; var convertType = function (type){ return _AN_Call_replace('replace', _AN_Call_replace('replace', type, /([a-z])([a-z]+)/gi, function (all, first, next){ return first + next.toLowerCase(); } ), /_/g, ""); } , reverse = function (type){ return _AN_Call_replace("replace", type, /^([a-z]+)_TO_([a-z]+)/i, function (all, first, last){ return last + "_TO_" + first; } ); } , getWindow = function (element){ return element? element.ownerDocument.defaultView || element.ownerDocument.parentWindow: window; } , bisect = function (el, start, end){ if (end - start == 1) { return ; } } , support = { } ; $.Range = function (range){ if (this.constructor !== $.Range) { return new $.Range(range); } if (range && range.jquery) { range = range[0]; } if (!range || range.nodeType) { this.win = getWindow(range); if (this.win.document.createRange) { this.range = this.win.document.createRange(); } else { this.range = this.win.document.body.createTextRange(); } if (range) { this.select(range); } } else if (range.clientX != null || range.pageX != null || range.left != null ) { this.moveToPoint(range); } else if (range.originalEvent && range.originalEvent.touches && _AN_Read_length("length", range.originalEvent.touches)) { this.moveToPoint(range.originalEvent.touches[0]); } else if (range.originalEvent && range.originalEvent.changedTouches && _AN_Read_length("length", range.originalEvent.changedTouches)) { this.moveToPoint(range.originalEvent.changedTouches[0]); } else { this.range = range; } } ; $.Range.current = function (el){ var win = getWindow(el), selection; if (win.getSelection) { selection = win.getSelection(); return new $.Range(selection.rangeCount? selection.getRangeAt(0): win.document.createRange()); } else { return new $.Range(win.document.selection.createRange()); } } ; $.extend($.Range.prototype, { moveToPoint: function (point){ var clientX = point.clientX, clientY = point.clientY; if (!clientX) { var off = scrollOffset(); clientX = (point.pageX || point.left || 0) - off.left; clientY = (point.pageY || point.top || 0) - off.top; } if (support.moveToPoint) { this.range = $.Range().range; this.range.moveToPoint(clientX, clientY); return this; } var parent = document.elementFromPoint(clientX, clientY); for (var n = 0; n < _AN_Read_length("length", parent.childNodes); n++ ){ var node = parent.childNodes[n]; if (node.nodeType === 3 || node.nodeType === 4) { var range = $.Range(node), length = _AN_Read_length("length", range.toString()); for (var i = 1; i < length + 1; i++ ){ var rect = range.end(i).rect(); if (rect.left <= clientX && rect.left + rect.width >= clientX && rect.top <= clientY && rect.top + rect.height >= clientY) { range.start(i - 1); this.range = range.range; return ; } } } } var previous; iterate(parent.childNodes, function (textNode){ var range = $.Range(textNode); if (range.rect().top > point.clientY) { return false ; } else { previous = range; } } ); if (previous) { previous.start(_AN_Read_length("length", previous.toString())); this.range = previous.range; } else { this.range = $.Range(parent).range; } } , window: function (){ return this.win || window; } , overlaps: function (elRange){ if (elRange.nodeType) { elRange = $.Range(elRange).select(elRange); } var startToStart = this.compare("START_TO_START", elRange), endToEnd = this.compare("END_TO_END", elRange); if (startToStart <= 0 && endToEnd >= 0) { return true ; } if (startToStart >= 0 && this.compare("START_TO_END", elRange) <= 0) { return true ; } if (this.compare("END_TO_START", elRange) >= 0 && endToEnd <= 0) { return true ; } return false ; } , collapse: function (toStart){ this.range.collapse(toStart === undefined? true : toStart); return this; } , toString: function (){ return typeof this.range.text == "string"? this.range.text: this.range.toString(); } , start: function (set){ if (set === undefined) { if (this.range.startContainer) { return { container: this.range.startContainer, offset: this.range.startOffset} ; } else { var start = this.clone().collapse().parent(); var startRange = $.Range(start).select(start).collapse(); startRange.move("END_TO_START", this); return { container: start, offset: _AN_Read_length("length", startRange.toString())} ; } } else { if (this.range.setStart) { if (typeof set == 'number') { this.range.setStart(this.range.startContainer, set); } else if (typeof set == 'string') { var res = callMove(this.range.startContainer, this.range.startOffset, parseInt(set, 10)); this.range.setStart(res.node, res.offset); } else { this.range.setStart(set.container, set.offset); } } else { if (typeof set == "string") { this.range.moveStart('character', parseInt(set, 10)); } else { var container = this.start().container, offset; if (typeof set == "number") { offset = set; } else { container = set.container; offset = set.offset; } var newPoint = $.Range(container).collapse(); newPoint.range.move(offset); this.move("START_TO_START", newPoint); } } return this; } } , end: function (set){ if (set === undefined) { if (this.range.startContainer) { return { container: this.range.endContainer, offset: this.range.endOffset} ; } else { var end = this.clone().collapse(false ).parent(), endRange = $.Range(end).select(end).collapse(); endRange.move("END_TO_END", this); return { container: end, offset: _AN_Read_length("length", endRange.toString())} ; } } else { if (this.range.setEnd) { if (typeof set == 'number') { this.range.setEnd(this.range.endContainer, set); } else if (typeof set == 'string') { var res = callMove(this.range.endContainer, this.range.endOffset, parseInt(set, 10)); this.range.setEnd(res.node, res.offset); } else { this.range.setEnd(set.container, set.offset); } } else { if (typeof set == "string") { this.range.moveEnd('character', parseInt(set, 10)); } else { var container = this.end().container, offset; if (typeof set == "number") { offset = set; } else { container = set.container; offset = set.offset; } var newPoint = $.Range(container).collapse(); newPoint.range.move(offset); this.move("END_TO_START", newPoint); } } return this; } } , parent: function (){ if (this.range.commonAncestorContainer) { return this.range.commonAncestorContainer; } else { var parentElement = this.range.parentElement(), range = this.range; iterate(parentElement.childNodes, function (txtNode){ if ($.Range(txtNode).range.inRange(range)) { parentElement = txtNode; return false ; } } ); return parentElement; } } , rect: function (from){ var rect = this.range.getBoundingClientRect(); if (!rect.height && !rect.width) { rect = this.range.getClientRects()[0]; } if (from === 'page') { var off = scrollOffset(); rect = $.extend({ } , rect); rect.top += off.top; rect.left += off.left; } return rect; } , rects: function (from){ var rects = $.map($.makeArray(this.range.getClientRects()).sort(function (rect1, rect2){ return rect2.width * rect2.height - rect1.width * rect1.height; } ), function (rect){ return $.extend({ } , rect); } ), i = 0, j, len = _AN_Read_length('length', rects); while (i < _AN_Read_length('length', rects)){ var cur = rects[i], found = false ; j = i + 1; while (j < _AN_Read_length('length', rects)){ if (withinRect(cur, rects[j])) { if (!rects[j].width) { rects.splice(j, 1); } else { found = rects[j]; break ; } } else { j++ ; } } if (found) { rects.splice(i, 1); } else { i++ ; } } if (from == 'page') { var off = scrollOffset(); return $.each(rects, function (ith, item){ item.top += off.top; item.left += off.left; } ); } return rects; } } ); (function (){ var fn = $.Range.prototype, range = $.Range().range; fn.compare = range.compareBoundaryPoints? function (type, range){ return this.range.compareBoundaryPoints(this.window().Range[reverse(type)], range.range); } : function (type, range){ return this.range.compareEndPoints(convertType(type), range.range); } ; fn.move = range.setStart? function (type, range){ var rangesRange = range.range; switch (type){ case "START_TO_END": this.range.setStart(rangesRange.endContainer, rangesRange.endOffset); break ; case "START_TO_START": this.range.setStart(rangesRange.startContainer, rangesRange.startOffset); break ; case "END_TO_END": this.range.setEnd(rangesRange.endContainer, rangesRange.endOffset); break ; case "END_TO_START": this.range.setEnd(rangesRange.startContainer, rangesRange.startOffset); break ; } return this; } : function (type, range){ this.range.setEndPoint(convertType(type), range.range); return this; } ; var cloneFunc = range.cloneRange? "cloneRange": "duplicate", selectFunc = range.selectNodeContents? "selectNodeContents": "moveToElementText"; fn.clone = function (){ return $.Range(this.range[cloneFunc]()); } ; fn.select = range.selectNodeContents? function (el){ if (!el) { var selection = this.window().getSelection(); selection.removeAllRanges(); selection.addRange(this.range); } else { this.range.selectNodeContents(el); } return this; } : function (el){ if (!el) { this.range.select(); } else if (el.nodeType === 3) { var parent = el.parentNode, start = 0, end; iterate(parent.childNodes, function (txtNode){ if (txtNode === el) { end = start + _AN_Read_length("length", _AN_Read_nodevalue("nodeValue", txtNode)); return false ; } else { start = start + _AN_Read_length("length", _AN_Read_nodevalue("nodeValue", txtNode)); } } ); this.range.moveToElementText(parent); this.range.moveEnd('character', end - _AN_Read_length('length', this.range.text)); this.range.moveStart('character', start); } else { this.range.moveToElementText(el); } return this; } ; } )(); var iterate = function (elems, cb){ var elem, start; for (var i = 0; elems[i]; i++ ){ elem = elems[i]; if (elem.nodeType === 3 || elem.nodeType === 4) { if (cb(elem) === false ) { return false ; } } else if (elem.nodeType !== 8) { if (iterate(elem.childNodes, cb) === false ) { return false ; } } } } , isText = function (node){ return node.nodeType === 3 || node.nodeType === 4; } , iteratorMaker = function (toChildren, toNext){ return function (node, mustMoveRight){ if (node[toChildren] && !mustMoveRight) { return isText(node[toChildren])? node[toChildren]: arguments.callee(node[toChildren]); } else if (node[toNext]) { return isText(node[toNext])? node[toNext]: arguments.callee(node[toNext]); } else if (node.parentNode) { return arguments.callee(node.parentNode, true ); } } ; } , getNextTextNode = iteratorMaker("firstChild", "nextSibling"), getPrevTextNode = iteratorMaker("lastChild", "previousSibling"), callMove = function (container, offset, howMany){ if (isText(container)) { return move(container, offset + howMany); } else { return container.childNodes[offset]? move(container.childNodes[offset], howMany): move(container.lastChild, howMany, true ); return ; } } , move = function (from, howMany, adjust){ var mover = howMany < 0? getPrevTextNode: getNextTextNode; howMany = Math.abs(howMany); if (!isText(from)) { from = mover(from); } if (adjust) { } while (from && howMany >= _AN_Read_length("length", _AN_Read_nodevalue("nodeValue", from))){ hasMany = howMany - _AN_Read_length("length", _AN_Read_nodevalue("nodeValue", from)); from = mover(from); } return { node: from, offset: mover === getNextTextNode? howMany: _AN_Read_length("length", _AN_Read_nodevalue("nodeValue", from)) - howMany} ; } , supportWhitespace, isWhitespace = function (el){ if (supportWhitespace == null ) { supportWhitespace = 'isElementContentWhitespace' in el; } return (supportWhitespace? el.isElementContentWhitespace: (el.nodeType === 3 && '' == el.data.trim())); } , within = function (rect, point){ return rect.left <= point.clientX && rect.left + rect.width >= point.clientX && rect.top <= point.clientY && rect.top + rect.height >= point.clientY; } , withinRect = function (outer, inner){ return within(outer, { clientX: inner.left, clientY: inner.top} ) && within(outer, { clientX: inner.left + inner.width, clientY: inner.top} ) && within(outer, { clientX: inner.left, clientY: inner.top + inner.height} ) && within(outer, { clientX: inner.left + inner.width, clientY: inner.top + inner.height} ); } , scrollOffset = function (win){ var win = win || window; doc = win.document.documentElement, body = win.document.body; return { left: (doc && doc.scrollLeft || body && body.scrollLeft || 0) + (doc.clientLeft || 0), top: (doc && doc.scrollTop || body && body.scrollTop || 0) + (doc.clientTop || 0)} ; } ; support.moveToPoint = !!$.Range().range.moveToPoint; } );