(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(["jquery"], function ($) { return (root.returnExportsGlobal = factory($)); }); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(require("jquery")); } else { factory(jQuery); } }(this, function ($) { /* Implement Github like autocomplete mentions http://ichord.github.com/At.js Copyright (c) 2013 chord.luo@gmail.com Licensed under the MIT license. */ /* 本插件操作 textarea 或者 input 内的插入符 只实现了获得插入符在文本框中的位置,我设置 插入符的位置. */ "use strict"; var EditableCaret, InputCaret, Mirror, Utils, discoveryIframeOf, methods, oDocument, oFrame, oWindow, pluginName, setContextBy; pluginName = 'caret'; EditableCaret = (function() { function EditableCaret($inputor) { this.$inputor = $inputor; this.domInputor = this.$inputor[0]; } EditableCaret.prototype.setPos = function(pos) { var fn, found, offset, sel; if (sel = oWindow.getSelection()) { offset = 0; found = false; (fn = function(pos, parent) { var node, range, _i, _len, _ref, _results; _ref = parent.childNodes; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { node = _ref[_i]; if (found) { break; } if (node.nodeType === 3) { if (offset + node.length >= pos) { found = true; range = oDocument.createRange(); range.setStart(node, pos - offset); sel.removeAllRanges(); sel.addRange(range); break; } else { _results.push(offset += node.length); } } else { _results.push(fn(pos, node)); } } return _results; })(pos, this.domInputor); } return this.domInputor; }; EditableCaret.prototype.getIEPosition = function() { return this.getPosition(); }; EditableCaret.prototype.getPosition = function() { var inputor_offset, offset; offset = this.getOffset(); inputor_offset = this.$inputor.offset(); offset.left -= inputor_offset.left; offset.top -= inputor_offset.top; return offset; }; EditableCaret.prototype.getOldIEPos = function() { var preCaretTextRange, textRange; textRange = oDocument.selection.createRange(); preCaretTextRange = oDocument.body.createTextRange(); preCaretTextRange.moveToElementText(this.domInputor); preCaretTextRange.setEndPoint("EndToEnd", textRange); return preCaretTextRange.text.length; }; EditableCaret.prototype.getPos = function() { var clonedRange, pos, range; if (range = this.range()) { clonedRange = range.cloneRange(); clonedRange.selectNodeContents(this.domInputor); clonedRange.setEnd(range.endContainer, range.endOffset); pos = clonedRange.toString().length; clonedRange.detach(); return pos; } else if (oDocument.selection) { return this.getOldIEPos(); } }; EditableCaret.prototype.getOldIEOffset = function() { var range, rect; range = oDocument.selection.createRange().duplicate(); range.moveStart("character", -1); rect = range.getBoundingClientRect(); return { height: rect.bottom - rect.top, left: rect.left, top: rect.top }; }; EditableCaret.prototype.getOffset = function(pos) { var clonedRange, offset, range, rect, shadowCaret; if (oWindow.getSelection && (range = this.range())) { if (range.endOffset - 1 > 0 && range.endContainer !== this.domInputor) { clonedRange = range.cloneRange(); clonedRange.setStart(range.endContainer, range.endOffset - 1); clonedRange.setEnd(range.endContainer, range.endOffset); rect = clonedRange.getBoundingClientRect(); offset = { height: rect.height, left: rect.left + rect.width, top: rect.top }; clonedRange.detach(); } if (!offset || (offset != null ? offset.height : void 0) === 0) { clonedRange = range.cloneRange(); shadowCaret = $(oDocument.createTextNode("|")); clonedRange.insertNode(shadowCaret[0]); clonedRange.selectNode(shadowCaret[0]); rect = clonedRange.getBoundingClientRect(); offset = { height: rect.height, left: rect.left, top: rect.top }; shadowCaret.remove(); clonedRange.detach(); } } else if (oDocument.selection) { offset = this.getOldIEOffset(); } if (offset) { offset.top += $(oWindow).scrollTop(); offset.left += $(oWindow).scrollLeft(); } return offset; }; EditableCaret.prototype.range = function() { var sel; if (!oWindow.getSelection) { return; } sel = oWindow.getSelection(); if (sel.rangeCount > 0) { return sel.getRangeAt(0); } else { return null; } }; return EditableCaret; })(); InputCaret = (function() { function InputCaret($inputor) { this.$inputor = $inputor; this.domInputor = this.$inputor[0]; } InputCaret.prototype.getIEPos = function() { var endRange, inputor, len, normalizedValue, pos, range, textInputRange; inputor = this.domInputor; range = oDocument.selection.createRange(); pos = 0; if (range && range.parentElement() === inputor) { normalizedValue = inputor.value.replace(/\r\n/g, "\n"); len = normalizedValue.length; textInputRange = inputor.createTextRange(); textInputRange.moveToBookmark(range.getBookmark()); endRange = inputor.createTextRange(); endRange.collapse(false); if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { pos = len; } else { pos = -textInputRange.moveStart("character", -len); } } return pos; }; InputCaret.prototype.getPos = function() { if (oDocument.selection) { return this.getIEPos(); } else { return this.domInputor.selectionStart; } }; InputCaret.prototype.setPos = function(pos) { var inputor, range; inputor = this.domInputor; if (oDocument.selection) { range = inputor.createTextRange(); range.move("character", pos); range.select(); } else if (inputor.setSelectionRange) { inputor.setSelectionRange(pos, pos); } return inputor; }; InputCaret.prototype.getIEOffset = function(pos) { var h, textRange, x, y; textRange = this.domInputor.createTextRange(); pos || (pos = this.getPos()); textRange.move('character', pos); x = textRange.boundingLeft; y = textRange.boundingTop; h = textRange.boundingHeight; return { left: x, top: y, height: h }; }; InputCaret.prototype.getOffset = function(pos) { var $inputor, offset, position; $inputor = this.$inputor; if (oDocument.selection) { offset = this.getIEOffset(pos); offset.top += $(oWindow).scrollTop() + $inputor.scrollTop(); offset.left += $(oWindow).scrollLeft() + $inputor.scrollLeft(); return offset; } else { offset = $inputor.offset(); position = this.getPosition(pos); return offset = { left: offset.left + position.left - $inputor.scrollLeft(), top: offset.top + position.top - $inputor.scrollTop(), height: position.height }; } }; InputCaret.prototype.getPosition = function(pos) { var $inputor, at_rect, end_range, format, html, mirror, start_range; $inputor = this.$inputor; format = function(value) { value = value.replace(/<|>|`|"|&/g, '?').replace(/\r\n|\r|\n/g, "
"); if (/firefox/i.test(navigator.userAgent)) { value = value.replace(/\s/g, ' '); } return value; }; if (pos === void 0) { pos = this.getPos(); } start_range = $inputor.val().slice(0, pos); end_range = $inputor.val().slice(pos); html = "" + format(start_range) + ""; html += "|"; html += "" + format(end_range) + ""; mirror = new Mirror($inputor); return at_rect = mirror.create(html).rect(); }; InputCaret.prototype.getIEPosition = function(pos) { var h, inputorOffset, offset, x, y; offset = this.getIEOffset(pos); inputorOffset = this.$inputor.offset(); x = offset.left - inputorOffset.left; y = offset.top - inputorOffset.top; h = offset.height; return { left: x, top: y, height: h }; }; return InputCaret; })(); Mirror = (function() { Mirror.prototype.css_attr = ["borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle", "borderTopWidth", "boxSizing", "fontFamily", "fontSize", "fontWeight", "height", "letterSpacing", "lineHeight", "marginBottom", "marginLeft", "marginRight", "marginTop", "outlineWidth", "overflow", "overflowX", "overflowY", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "textAlign", "textOverflow", "textTransform", "whiteSpace", "wordBreak", "wordWrap"]; function Mirror($inputor) { this.$inputor = $inputor; } Mirror.prototype.mirrorCss = function() { var css, _this = this; css = { position: 'absolute', left: -9999, top: 0, zIndex: -20000 }; if (this.$inputor.prop('tagName') === 'TEXTAREA') { this.css_attr.push('width'); } $.each(this.css_attr, function(i, p) { return css[p] = _this.$inputor.css(p); }); return css; }; Mirror.prototype.create = function(html) { this.$mirror = $('
'); this.$mirror.css(this.mirrorCss()); this.$mirror.html(html); this.$inputor.after(this.$mirror); return this; }; Mirror.prototype.rect = function() { var $flag, pos, rect; $flag = this.$mirror.find("#caret"); pos = $flag.position(); rect = { left: pos.left, top: pos.top, height: $flag.height() }; this.$mirror.remove(); return rect; }; return Mirror; })(); Utils = { contentEditable: function($inputor) { return !!($inputor[0].contentEditable && $inputor[0].contentEditable === 'true'); } }; methods = { pos: function(pos) { if (pos || pos === 0) { return this.setPos(pos); } else { return this.getPos(); } }, position: function(pos) { if (oDocument.selection) { return this.getIEPosition(pos); } else { return this.getPosition(pos); } }, offset: function(pos) { var offset; offset = this.getOffset(pos); return offset; } }; oDocument = null; oWindow = null; oFrame = null; setContextBy = function(settings) { var iframe; if (iframe = settings != null ? settings.iframe : void 0) { oFrame = iframe; oWindow = iframe.contentWindow; return oDocument = iframe.contentDocument || oWindow.document; } else { oFrame = void 0; oWindow = window; return oDocument = document; } }; discoveryIframeOf = function($dom) { var error; oDocument = $dom[0].ownerDocument; oWindow = oDocument.defaultView || oDocument.parentWindow; try { return oFrame = oWindow.frameElement; } catch (_error) { error = _error; } }; $.fn.caret = function(method, value, settings) { var caret; if (methods[method]) { if ($.isPlainObject(value)) { setContextBy(value); value = void 0; } else { setContextBy(settings); } caret = Utils.contentEditable(this) ? new EditableCaret(this) : new InputCaret(this); return methods[method].apply(caret, [value]); } else { return $.error("Method " + method + " does not exist on jQuery.caret"); } }; $.fn.caret.EditableCaret = EditableCaret; $.fn.caret.InputCaret = InputCaret; $.fn.caret.Utils = Utils; $.fn.caret.apis = methods; }));