summaryrefslogtreecommitdiffstats
path: root/apps/comments/js/vendor/Caret.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/comments/js/vendor/Caret.js')
-rw-r--r--apps/comments/js/vendor/Caret.js/.bower.json30
-rw-r--r--apps/comments/js/vendor/Caret.js/CHANGELOG.md52
-rw-r--r--apps/comments/js/vendor/Caret.js/Gruntfile.coffee79
-rw-r--r--apps/comments/js/vendor/Caret.js/LICENSE-MIT22
-rw-r--r--apps/comments/js/vendor/Caret.js/README.md54
-rw-r--r--apps/comments/js/vendor/Caret.js/bower.json20
-rw-r--r--apps/comments/js/vendor/Caret.js/component.json20
-rw-r--r--apps/comments/js/vendor/Caret.js/dist/jquery.caret.js405
-rw-r--r--apps/comments/js/vendor/Caret.js/dist/jquery.caret.min.js2
-rw-r--r--apps/comments/js/vendor/Caret.js/package.json29
-rw-r--r--apps/comments/js/vendor/Caret.js/src/jquery.caret.coffee311
-rw-r--r--apps/comments/js/vendor/Caret.js/src/jquery.caret.js406
12 files changed, 1430 insertions, 0 deletions
diff --git a/apps/comments/js/vendor/Caret.js/.bower.json b/apps/comments/js/vendor/Caret.js/.bower.json
new file mode 100644
index 00000000000..dae9e91f6ad
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/.bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "Caret.js",
+ "version": "0.2.2",
+ "main": "src/jquery.caret.js",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests",
+ "spec",
+ "index.html"
+ ],
+ "dependencies": {
+ "jquery": ">=1.7.0"
+ },
+ "devDependencies": {
+ "jasmine-jquery": "~1.5.8"
+ },
+ "homepage": "https://github.com/ichord/Caret.js",
+ "_release": "0.2.2",
+ "_resolution": {
+ "type": "version",
+ "tag": "v0.2.2",
+ "commit": "b435c7049f1bce1c4db10526d956e24e8b484a52"
+ },
+ "_source": "https://github.com/ichord/Caret.js.git",
+ "_target": "~0.2.2",
+ "_originalSource": "Caret.js"
+} \ No newline at end of file
diff --git a/apps/comments/js/vendor/Caret.js/CHANGELOG.md b/apps/comments/js/vendor/Caret.js/CHANGELOG.md
new file mode 100644
index 00000000000..2b127e44335
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/CHANGELOG.md
@@ -0,0 +1,52 @@
+### v0.2.1
+
+* f66a1eb - can get offset at the benginning of a line
+* 4885ddd - fix wrong position of textarea
+
+### v0.2.0
+
+* 12119d2 - calculating in iframe's coordinate
+* 959436d - implement `position` api for contentEditable
+* d051ffc - fix html escaping while mirroring caret
+
+### v0.1.0
+
+* b1f8f53 - fix Mirror div does not reset its CSS
+* e88e40e - fix Bad positioning in long words
+* 37d4c5e - disable auto decovery iframe
+
+### v0.0.7
+
+* cf94271 - Added suport for .caret(pos, 0) - Nicolas Donna
+* 2de2b0f - Fixed error when checking the pos arg when setting the position - Nicolas Donna
+* 34ac7fa - catch error thrown in cross-domain iframe - jiyinyiyong
+
+* 01f1fa1 - add minified file in dist.
+
+### v0.0.6
+
+* 287b5d8 working in iframe
+
+### v0.0.5
+
+* aef0aa4 fix IE input position error
+* 4a4f7f7 fix contenteditable null value bug
+
+### v0.0.4
+
+* fix scrolling problem
+
+### v0.0.2
+
+* support `contentEditable` mode
+* fix ie bugs, and support IE > 6 to all mode
+
+### 2013-08-07
+
+* fix bug: error position at beginning of textarea
+* Bower
+* jasmine test
+
+### 2013-03-31
+
+* support IE browsers.
diff --git a/apps/comments/js/vendor/Caret.js/Gruntfile.coffee b/apps/comments/js/vendor/Caret.js/Gruntfile.coffee
new file mode 100644
index 00000000000..a645110b59b
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/Gruntfile.coffee
@@ -0,0 +1,79 @@
+module.exports = (grunt) ->
+ grunt.initConfig
+ pkg: grunt.file.readJSON 'package.json'
+ bower_path: 'bower_components'
+
+ jasmine:
+ src: 'src/*.js'
+ options:
+ vendor: [
+ '<%= bower_path %>/jquery/dist/jquery.min.js',
+ '<%= bower_path %>/jasmine-jquery/lib/jasmine-jquery.js'
+ ]
+ specs: 'spec/javascripts/*.js'
+ # keepRunner: true
+
+ uglify:
+ options:
+ banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
+ build:
+ files:
+ 'dist/<%= pkg.name %>.min.js': ['src/<%= pkg.name %>.js']
+
+ coffee:
+ withMaps:
+ options:
+ bare: true
+ sourceMap: true
+ files:
+ 'src/<%= pkg.name %>.js': 'src/<%= pkg.name %>.coffee'
+ withoutMaps:
+ options:
+ bare: true
+ sourceMap: false
+ files:
+ 'dist/<%= pkg.name %>.js': 'src/<%= pkg.name %>.coffee'
+
+ watch:
+ scripts:
+ files: ['src/*.coffee']
+ tasks: ['coffee', 'umd']
+
+ umd:
+ options:
+ template: 'umd'
+ deps:
+ 'default': ['$']
+ amd: ['jquery']
+ cjs: ['jquery']
+ global:
+ items: ['jQuery']
+ prefix: ''
+ src:
+ src: 'src/<%= pkg.name %>.js'
+ dist:
+ src: 'dist/<%= pkg.name %>.js'
+
+
+ 'json-replace':
+ options:
+ space: " ",
+ replace:
+ version: "<%= pkg.version %>"
+ 'update-version':
+ files:[{
+ 'bower.json': 'bower.json',
+ 'component.json': 'component.json'
+ }]
+
+ grunt.loadNpmTasks 'grunt-contrib-coffee'
+ grunt.loadNpmTasks 'grunt-contrib-uglify'
+ grunt.loadNpmTasks 'grunt-contrib-jasmine'
+ grunt.loadNpmTasks 'grunt-json-replace'
+ grunt.loadNpmTasks 'grunt-contrib-watch'
+ grunt.loadNpmTasks 'grunt-umd'
+
+ grunt.registerTask 'update-version', 'json-replace'
+
+ grunt.registerTask 'default', ['coffee', 'umd', 'jasmine','update-version', 'uglify', 'watch']
+ grunt.registerTask 'test', ['coffee', 'umd', 'jasmine']
diff --git a/apps/comments/js/vendor/Caret.js/LICENSE-MIT b/apps/comments/js/vendor/Caret.js/LICENSE-MIT
new file mode 100644
index 00000000000..36cd1c12272
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) 2013 chord.luo@gmail.com
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/apps/comments/js/vendor/Caret.js/README.md b/apps/comments/js/vendor/Caret.js/README.md
new file mode 100644
index 00000000000..ececb2cc2fe
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/README.md
@@ -0,0 +1,54 @@
+Caret.js
+========
+
+Get caret postion or offset from inputor
+
+This is the core function that working in [At.js](http://ichord.github.com/At.js).
+Now, It just become an simple jquery plugin so that everybody can use it.
+And, of course, **At.js** is using this plugin too.
+
+* support iframe context
+
+Live Demo
+=========
+
+http://ichord.github.com/Caret.js/
+
+
+Usage
+=====
+
+```javascript
+
+// Get caret position
+$('#inputor').caret('position'); // => {left: 15, top: 30, height: 20}
+
+// Get caret offset
+$('#inputor').caret('offset'); // => {left: 300, top: 400, height: 20}
+
+var fixPos = 20
+// Get position of the 20th char in the inputor.
+// not working in `contentEditable` mode
+$('#inputor').caret('position', fixPos);
+
+// Get offset of the 20th char.
+// not working in `contentEditable` mode
+$('#inputor').caret('offset', fixPos);
+
+// more
+
+// Get caret position from the first char in the inputor.
+$('#inputor').caret('pos'); // => 15
+
+// Set caret position in the inputor
+// not working in contentEditable mode
+$('#inputor').caret('pos', 15);
+
+// set iframe context
+// NOTE: Related to the iframe's cooridinate.
+// You might want to get the iframe's offset/position on your own
+$('#inputor').caret('offset', {iframe: theIframe});
+$('#inputor').caret('position', {iframe: theIframe});
+$('#inputor').caret('pos', 15, {iframe: theIframe});
+
+```
diff --git a/apps/comments/js/vendor/Caret.js/bower.json b/apps/comments/js/vendor/Caret.js/bower.json
new file mode 100644
index 00000000000..c732905da17
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/bower.json
@@ -0,0 +1,20 @@
+{
+ "name": "Caret.js",
+ "version": "0.2.2",
+ "main": "src/jquery.caret.js",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests",
+ "spec",
+ "index.html"
+ ],
+ "dependencies": {
+ "jquery": ">=1.7.0"
+ },
+ "devDependencies": {
+ "jasmine-jquery": "~1.5.8"
+ }
+} \ No newline at end of file
diff --git a/apps/comments/js/vendor/Caret.js/component.json b/apps/comments/js/vendor/Caret.js/component.json
new file mode 100644
index 00000000000..b81815e5dcd
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/component.json
@@ -0,0 +1,20 @@
+{
+ "name": "Caret.js",
+ "repo": "ichord/Caret.js",
+ "description": "Add Github like mentions autocomplete to your application.",
+ "version": "0.2.2",
+ "keywords": [
+ "At.js",
+ "caret",
+ "ui"
+ ],
+ "dependencies": {
+ "component/jquery": "*"
+ },
+ "demo": "http://ichord.github.com/Caret.js",
+ "main": "src/jquery.caret.js",
+ "scripts": [
+ "src/jquery.caret.js"
+ ],
+ "license": "MIT"
+} \ No newline at end of file
diff --git a/apps/comments/js/vendor/Caret.js/dist/jquery.caret.js b/apps/comments/js/vendor/Caret.js/dist/jquery.caret.js
new file mode 100644
index 00000000000..e0de4bc8245
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/dist/jquery.caret.js
@@ -0,0 +1,405 @@
+(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 enviroments 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) {
+ 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, "<br/>");
+ if (/firefox/i.test(navigator.userAgent)) {
+ value = value.replace(/\s/g, '&nbsp;');
+ }
+ return value;
+ };
+ if (pos === void 0) {
+ pos = this.getPos();
+ }
+ start_range = $inputor.val().slice(0, pos);
+ end_range = $inputor.val().slice(pos);
+ html = "<span style='position: relative; display: inline;'>" + format(start_range) + "</span>";
+ html += "<span id='caret' style='position: relative; display: inline;'>|</span>";
+ html += "<span style='position: relative; display: inline;'>" + format(end_range) + "</span>";
+ 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 = $('<div></div>');
+ 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;
+
+
+}));
diff --git a/apps/comments/js/vendor/Caret.js/dist/jquery.caret.min.js b/apps/comments/js/vendor/Caret.js/dist/jquery.caret.min.js
new file mode 100644
index 00000000000..a4d02eae247
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/dist/jquery.caret.min.js
@@ -0,0 +1,2 @@
+/*! jquery.caret 2015-02-01 */
+!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){"use strict";var b,c,d,e,f,g,h,i,j,k,l;k="caret",b=function(){function b(a){this.$inputor=a,this.domInputor=this.$inputor[0]}return b.prototype.setPos=function(){return this.domInputor},b.prototype.getIEPosition=function(){return this.getPosition()},b.prototype.getPosition=function(){var a,b;return b=this.getOffset(),a=this.$inputor.offset(),b.left-=a.left,b.top-=a.top,b},b.prototype.getOldIEPos=function(){var a,b;return b=h.selection.createRange(),a=h.body.createTextRange(),a.moveToElementText(this.domInputor),a.setEndPoint("EndToEnd",b),a.text.length},b.prototype.getPos=function(){var a,b,c;return(c=this.range())?(a=c.cloneRange(),a.selectNodeContents(this.domInputor),a.setEnd(c.endContainer,c.endOffset),b=a.toString().length,a.detach(),b):h.selection?this.getOldIEPos():void 0},b.prototype.getOldIEOffset=function(){var a,b;return a=h.selection.createRange().duplicate(),a.moveStart("character",-1),b=a.getBoundingClientRect(),{height:b.bottom-b.top,left:b.left,top:b.top}},b.prototype.getOffset=function(){var b,c,d,e,f;return j.getSelection&&(d=this.range())?(d.endOffset-1>0&&d.endContainer===!this.domInputor&&(b=d.cloneRange(),b.setStart(d.endContainer,d.endOffset-1),b.setEnd(d.endContainer,d.endOffset),e=b.getBoundingClientRect(),c={height:e.height,left:e.left+e.width,top:e.top},b.detach()),c&&0!==(null!=c?c.height:void 0)||(b=d.cloneRange(),f=a(h.createTextNode("|")),b.insertNode(f[0]),b.selectNode(f[0]),e=b.getBoundingClientRect(),c={height:e.height,left:e.left,top:e.top},f.remove(),b.detach())):h.selection&&(c=this.getOldIEOffset()),c&&(c.top+=a(j).scrollTop(),c.left+=a(j).scrollLeft()),c},b.prototype.range=function(){var a;if(j.getSelection)return a=j.getSelection(),a.rangeCount>0?a.getRangeAt(0):null},b}(),c=function(){function b(a){this.$inputor=a,this.domInputor=this.$inputor[0]}return b.prototype.getIEPos=function(){var a,b,c,d,e,f,g;return b=this.domInputor,f=h.selection.createRange(),e=0,f&&f.parentElement()===b&&(d=b.value.replace(/\r\n/g,"\n"),c=d.length,g=b.createTextRange(),g.moveToBookmark(f.getBookmark()),a=b.createTextRange(),a.collapse(!1),e=g.compareEndPoints("StartToEnd",a)>-1?c:-g.moveStart("character",-c)),e},b.prototype.getPos=function(){return h.selection?this.getIEPos():this.domInputor.selectionStart},b.prototype.setPos=function(a){var b,c;return b=this.domInputor,h.selection?(c=b.createTextRange(),c.move("character",a),c.select()):b.setSelectionRange&&b.setSelectionRange(a,a),b},b.prototype.getIEOffset=function(a){var b,c,d,e;return c=this.domInputor.createTextRange(),a||(a=this.getPos()),c.move("character",a),d=c.boundingLeft,e=c.boundingTop,b=c.boundingHeight,{left:d,top:e,height:b}},b.prototype.getOffset=function(b){var c,d,e;return c=this.$inputor,h.selection?(d=this.getIEOffset(b),d.top+=a(j).scrollTop()+c.scrollTop(),d.left+=a(j).scrollLeft()+c.scrollLeft(),d):(d=c.offset(),e=this.getPosition(b),d={left:d.left+e.left-c.scrollLeft(),top:d.top+e.top-c.scrollTop(),height:e.height})},b.prototype.getPosition=function(a){var b,c,e,f,g,h,i;return b=this.$inputor,f=function(a){return a=a.replace(/<|>|`|"|&/g,"?").replace(/\r\n|\r|\n/g,"<br/>"),/firefox/i.test(navigator.userAgent)&&(a=a.replace(/\s/g,"&nbsp;")),a},void 0===a&&(a=this.getPos()),i=b.val().slice(0,a),e=b.val().slice(a),g="<span style='position: relative; display: inline;'>"+f(i)+"</span>",g+="<span id='caret' style='position: relative; display: inline;'>|</span>",g+="<span style='position: relative; display: inline;'>"+f(e)+"</span>",h=new d(b),c=h.create(g).rect()},b.prototype.getIEPosition=function(a){var b,c,d,e,f;return d=this.getIEOffset(a),c=this.$inputor.offset(),e=d.left-c.left,f=d.top-c.top,b=d.height,{left:e,top:f,height:b}},b}(),d=function(){function b(a){this.$inputor=a}return b.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"],b.prototype.mirrorCss=function(){var b,c=this;return b={position:"absolute",left:-9999,top:0,zIndex:-2e4},"TEXTAREA"===this.$inputor.prop("tagName")&&this.css_attr.push("width"),a.each(this.css_attr,function(a,d){return b[d]=c.$inputor.css(d)}),b},b.prototype.create=function(b){return this.$mirror=a("<div></div>"),this.$mirror.css(this.mirrorCss()),this.$mirror.html(b),this.$inputor.after(this.$mirror),this},b.prototype.rect=function(){var a,b,c;return a=this.$mirror.find("#caret"),b=a.position(),c={left:b.left,top:b.top,height:a.height()},this.$mirror.remove(),c},b}(),e={contentEditable:function(a){return!(!a[0].contentEditable||"true"!==a[0].contentEditable)}},g={pos:function(a){return a||0===a?this.setPos(a):this.getPos()},position:function(a){return h.selection?this.getIEPosition(a):this.getPosition(a)},offset:function(a){var b;return b=this.getOffset(a)}},h=null,j=null,i=null,l=function(a){var b;return(b=null!=a?a.iframe:void 0)?(i=b,j=b.contentWindow,h=b.contentDocument||j.document):(i=void 0,j=window,h=document)},f=function(a){var b;h=a[0].ownerDocument,j=h.defaultView||h.parentWindow;try{return i=j.frameElement}catch(c){b=c}},a.fn.caret=function(d,f,h){var i;return g[d]?(a.isPlainObject(f)?(l(f),f=void 0):l(h),i=e.contentEditable(this)?new b(this):new c(this),g[d].apply(i,[f])):a.error("Method "+d+" does not exist on jQuery.caret")},a.fn.caret.EditableCaret=b,a.fn.caret.InputCaret=c,a.fn.caret.Utils=e,a.fn.caret.apis=g}); \ No newline at end of file
diff --git a/apps/comments/js/vendor/Caret.js/package.json b/apps/comments/js/vendor/Caret.js/package.json
new file mode 100644
index 00000000000..ee04f5a52b3
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "jquery.caret",
+ "version": "0.2.2",
+ "description": "Get caret position and offset from inputor",
+ "main": "index.js",
+ "dependencies": {
+ "grunt": "~0.4.1"
+ },
+ "devDependencies": {
+ "grunt-contrib-coffee": "~0.6.4",
+ "grunt-contrib-jasmine": "~0.5.1",
+ "grunt-contrib-uglify": "~0.2.0",
+ "grunt-contrib-watch": "^0.6.1",
+ "grunt-json-replace": "~0.1.2",
+ "grunt-umd": "^2.2.1"
+ },
+ "scripts": {
+ "test": "grunt test --verbose"
+ },
+ "repository": "",
+ "keywords": [
+ "jquery",
+ "caret",
+ "offset",
+ "position"
+ ],
+ "author": "Harold.luo <chord.luo@gmail.com>",
+ "license": "MIT"
+}
diff --git a/apps/comments/js/vendor/Caret.js/src/jquery.caret.coffee b/apps/comments/js/vendor/Caret.js/src/jquery.caret.coffee
new file mode 100644
index 00000000000..51f698d1ee2
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/src/jquery.caret.coffee
@@ -0,0 +1,311 @@
+###
+ 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";
+
+pluginName = 'caret'
+
+class EditableCaret
+ constructor: (@$inputor) ->
+ @domInputor = @$inputor[0]
+
+ # NOTE: Duck type
+ setPos: (pos) -> @domInputor
+ getIEPosition: -> this.getPosition()
+ getPosition: ->
+ offset = this.getOffset()
+ inputor_offset = @$inputor.offset()
+ offset.left -= inputor_offset.left
+ offset.top -= inputor_offset.top
+ offset
+
+ getOldIEPos: ->
+ textRange = oDocument.selection.createRange()
+ preCaretTextRange = oDocument.body.createTextRange()
+ preCaretTextRange.moveToElementText(@domInputor)
+ preCaretTextRange.setEndPoint("EndToEnd", textRange)
+ preCaretTextRange.text.length
+
+ getPos: ->
+ if range = this.range() # Major Browser and IE > 10
+ clonedRange = range.cloneRange()
+ clonedRange.selectNodeContents(@domInputor)
+ clonedRange.setEnd(range.endContainer, range.endOffset)
+ pos = clonedRange.toString().length
+ clonedRange.detach()
+ pos
+ else if oDocument.selection #IE < 9
+ this.getOldIEPos()
+
+ getOldIEOffset: ->
+ range = oDocument.selection.createRange().duplicate()
+ range.moveStart "character", -1
+ rect = range.getBoundingClientRect()
+ { height: rect.bottom - rect.top, left: rect.left, top: rect.top }
+
+ getOffset: (pos) ->
+ if oWindow.getSelection and range = this.range()
+ # endContainer would be the inputor in Firefox at the begnning of a line
+ if range.endOffset - 1 > 0 and range.endContainer is not @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()
+ # At the begnning of the inputor, the offset height is 0 in Chrome and Safari
+ # This work fine in all browers but except while the inputor break a line into two (wrapped line).
+ # so we can't use it in all cases.
+ if !offset or offset?.height == 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 # ie < 9
+ offset = this.getOldIEOffset()
+
+ if offset
+ offset.top += $(oWindow).scrollTop()
+ offset.left += $(oWindow).scrollLeft()
+
+ offset
+
+ range: ->
+ return unless oWindow.getSelection
+ sel = oWindow.getSelection()
+ if sel.rangeCount > 0 then sel.getRangeAt(0) else null
+
+
+class InputCaret
+
+ constructor: (@$inputor) ->
+ @domInputor = @$inputor[0]
+
+ getIEPos: ->
+ # https://github.com/ichord/Caret.js/wiki/Get-pos-of-caret-in-IE
+ inputor = @domInputor
+ range = oDocument.selection.createRange()
+ pos = 0
+ # selection should in the inputor.
+ if range and range.parentElement() is 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
+ pos
+
+ getPos: ->
+ if oDocument.selection then this.getIEPos() else @domInputor.selectionStart
+
+ setPos: (pos) ->
+ inputor = @domInputor
+ if oDocument.selection #IE
+ range = inputor.createTextRange()
+ range.move "character", pos
+ range.select()
+ else if inputor.setSelectionRange
+ inputor.setSelectionRange pos, pos
+ inputor
+
+ getIEOffset: (pos) ->
+ textRange = @domInputor.createTextRange()
+ pos ||= this.getPos()
+ textRange.move('character', pos)
+
+ x = textRange.boundingLeft
+ y = textRange.boundingTop
+ h = textRange.boundingHeight
+
+ {left: x, top: y, height: h}
+
+ getOffset: (pos) ->
+ $inputor = @$inputor
+ if oDocument.selection
+ offset = this.getIEOffset(pos)
+ offset.top += $(oWindow).scrollTop() + $inputor.scrollTop()
+ offset.left += $(oWindow).scrollLeft() + $inputor.scrollLeft()
+ offset
+ else
+ offset = $inputor.offset()
+ position = this.getPosition(pos)
+ offset =
+ left: offset.left + position.left - $inputor.scrollLeft()
+ top: offset.top + position.top - $inputor.scrollTop()
+ height: position.height
+
+ getPosition: (pos)->
+ $inputor = @$inputor
+ format = (value) ->
+ value = value.replace(/<|>|`|"|&/g, '?').replace(/\r\n|\r|\n/g,"<br/>")
+ if /firefox/i.test navigator.userAgent
+ value = value.replace(/\s/g, '&nbsp;')
+ value
+ pos = this.getPos() if pos is undefined
+ start_range = $inputor.val().slice(0, pos)
+ end_range = $inputor.val().slice(pos)
+ html = "<span style='position: relative; display: inline;'>"+format(start_range)+"</span>"
+ html += "<span id='caret' style='position: relative; display: inline;'>|</span>"
+ html += "<span style='position: relative; display: inline;'>"+format(end_range)+"</span>"
+
+ mirror = new Mirror($inputor)
+ at_rect = mirror.create(html).rect()
+
+ getIEPosition: (pos) ->
+ offset = this.getIEOffset pos
+ inputorOffset = @$inputor.offset()
+ x = offset.left - inputorOffset.left
+ y = offset.top - inputorOffset.top
+ h = offset.height
+
+ {left: x, top: y, height: h}
+
+# @example
+# mirror = new Mirror($("textarea#inputor"))
+# html = "<p>We will get the rect of <span>@</span>icho</p>"
+# mirror.create(html).rect()
+class Mirror
+ 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",
+ ]
+
+ constructor: (@$inputor) ->
+
+ mirrorCss: ->
+ css =
+ position: 'absolute'
+ left: -9999
+ top: 0
+ zIndex: -20000
+ if @$inputor.prop( 'tagName' ) == 'TEXTAREA'
+ @css_attr.push( 'width' )
+ $.each @css_attr, (i,p) =>
+ css[p] = @$inputor.css p
+ css
+
+ create: (html) ->
+ @$mirror = $('<div></div>')
+ @$mirror.css this.mirrorCss()
+ @$mirror.html(html)
+ @$inputor.after(@$mirror)
+ this
+
+ # 获得标记的位置
+ #
+ # @return [Object] 标记的坐标
+ # {left: 0, top: 0, bottom: 0}
+ rect: ->
+ $flag = @$mirror.find "#caret"
+ pos = $flag.position()
+ rect = {left: pos.left, top: pos.top, height: $flag.height() }
+ @$mirror.remove()
+ rect
+
+Utils =
+ contentEditable: ($inputor)->
+ !!($inputor[0].contentEditable && $inputor[0].contentEditable == 'true')
+
+methods =
+ pos: (pos) ->
+ if pos or pos == 0
+ this.setPos pos
+ else
+ this.getPos()
+
+ position: (pos) ->
+ if oDocument.selection then this.getIEPosition pos else this.getPosition pos
+
+ offset: (pos) ->
+ offset = this.getOffset(pos)
+ offset
+
+oDocument = null
+oWindow = null
+oFrame = null
+setContextBy = (settings) ->
+ if iframe = settings?.iframe
+ oFrame = iframe
+ oWindow = iframe.contentWindow
+ oDocument = iframe.contentDocument || oWindow.document
+ else
+ oFrame = undefined
+ oWindow = window
+ oDocument = document
+discoveryIframeOf = ($dom) ->
+ oDocument = $dom[0].ownerDocument
+ oWindow = oDocument.defaultView || oDocument.parentWindow
+ try
+ oFrame = oWindow.frameElement
+ catch error
+ # throws error in cross-domain iframes
+
+$.fn.caret = (method, value, settings) ->
+ # http://stackoverflow.com/questions/16010204/get-reference-of-window-object-from-a-dom-element
+ if methods[method]
+ if $.isPlainObject(value)
+ setContextBy value
+ value = undefined
+ else
+ setContextBy settings
+ caret = if Utils.contentEditable(this) then new EditableCaret(this) else new InputCaret(this)
+ methods[method].apply caret, [value]
+ else
+ $.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
diff --git a/apps/comments/js/vendor/Caret.js/src/jquery.caret.js b/apps/comments/js/vendor/Caret.js/src/jquery.caret.js
new file mode 100644
index 00000000000..1cdde1d0c95
--- /dev/null
+++ b/apps/comments/js/vendor/Caret.js/src/jquery.caret.js
@@ -0,0 +1,406 @@
+(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 enviroments that support module.exports,
+ // like Node.
+ module.exports = factory(require("jquery"));
+ } else {
+ factory(jQuery);
+ }
+}(this, function ($) {
+
+//@ sourceMappingURL=jquery.caret.map
+/*
+ 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) {
+ 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, "<br/>");
+ if (/firefox/i.test(navigator.userAgent)) {
+ value = value.replace(/\s/g, '&nbsp;');
+ }
+ return value;
+ };
+ if (pos === void 0) {
+ pos = this.getPos();
+ }
+ start_range = $inputor.val().slice(0, pos);
+ end_range = $inputor.val().slice(pos);
+ html = "<span style='position: relative; display: inline;'>" + format(start_range) + "</span>";
+ html += "<span id='caret' style='position: relative; display: inline;'>|</span>";
+ html += "<span style='position: relative; display: inline;'>" + format(end_range) + "</span>";
+ 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 = $('<div></div>');
+ 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;
+
+
+}));