Commit db9ed1cf authored by Clement Ho's avatar Clement Ho

Merge branch '58876-mg-remove-jquery-atwho-gem' into 'master'

Resolve "Remove jquery-atwho-rails gem"

Closes #58876

See merge request gitlab-org/gitlab-ce!26058
parents 3c40c573 7f3719f3
......@@ -265,7 +265,6 @@ gem 'addressable', '~> 2.5.2'
gem 'font-awesome-rails', '~> 4.7'
gem 'gemojione', '~> 3.3'
gem 'gon', '~> 6.2'
gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'request_store', '~> 1.3'
gem 'virtus', '~> 1.0.1'
gem 'base32', '~> 0.3.0'
......
......@@ -398,7 +398,6 @@ GEM
activesupport
multipart-post
oauth (~> 0.5, >= 0.5.0)
jquery-atwho-rails (1.3.2)
js_regex (3.1.1)
character_set (~> 1.1)
regexp_parser (~> 1.1)
......@@ -1046,7 +1045,6 @@ DEPENDENCIES
influxdb (~> 0.2)
jaeger-client (~> 0.10.0)
jira-ruby (~> 1.4)
jquery-atwho-rails (~> 1.3.2)
js_regex (~> 3.1)
json-schema (~> 2.8.0)
jwt (~> 2.1.0)
......
......@@ -3,7 +3,7 @@ import 'jquery';
// common jQuery plugins
import 'jquery-ujs';
import 'vendor/jquery.endless-scroll';
import 'vendor/jquery.caret';
import 'vendor/jquery.atwho';
import 'jquery.caret'; // must be imported before at.js
import 'at.js';
import 'vendor/jquery.scrollTo';
import 'jquery.waitforimages';
......@@ -11,8 +11,8 @@ import $ from 'jquery';
import _ from 'underscore';
import Cookies from 'js-cookie';
import Autosize from 'autosize';
import 'vendor/jquery.caret'; // required by jquery.atwho
import 'vendor/jquery.atwho';
import 'jquery.caret'; // required by at.js
import 'at.js';
import AjaxCache from '~/lib/utils/ajax_cache';
import Vue from 'vue';
import syntaxHighlight from '~/syntax_highlight';
......
......@@ -2,7 +2,6 @@
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require jquery.atwho
*= require_self
*= require cropper.css
*/
......@@ -15,6 +14,7 @@
* directory.
*/
@import "../../../node_modules/at.js/dist/css/jquery.atwho";
@import "../../../node_modules/pikaday/scss/pikaday";
@import "../../../node_modules/dropzone/dist/basic";
@import "../../../node_modules/select2/select2";
......
......@@ -3,8 +3,8 @@
import $ from 'jquery';
import GfmAutoComplete from '~/gfm_auto_complete';
import 'vendor/jquery.caret';
import 'vendor/jquery.atwho';
import 'jquery.caret';
import 'at.js';
describe('GfmAutoComplete', () => {
const gfmAutoCompleteCallbacks = GfmAutoComplete.prototype.getDefaultCallbacks.call({
......
/**
* at.js - 1.5.1
* Copyright (c) 2016 chord.luo <chord.luo@gmail.com>;
* Homepage: http://ichord.github.com/At.js
* License: MIT
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module unless amdModuleId is set
define(["jquery"], function (a0) {
return (factory(a0));
});
} 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 ($) {
var DEFAULT_CALLBACKS, KEY_CODE;
KEY_CODE = {
DOWN: 40,
UP: 38,
ESC: 27,
TAB: 9,
ENTER: 13,
CTRL: 17,
A: 65,
P: 80,
N: 78,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
BACKSPACE: 8,
SPACE: 32
};
DEFAULT_CALLBACKS = {
beforeSave: function(data) {
return Controller.arrayToDefaultHash(data);
},
matcher: function(flag, subtext, should_startWithSpace, acceptSpaceBar) {
var _a, _y, match, regexp, space;
flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
if (should_startWithSpace) {
flag = '(?:^|\\s)' + flag;
}
_a = decodeURI("%C3%80");
_y = decodeURI("%C3%BF");
space = acceptSpaceBar ? "\ " : "";
regexp = new RegExp(flag + "([A-Za-z" + _a + "-" + _y + "0-9_" + space + "\'\.\+\-]*)$|" + flag + "([^\\x00-\\xff]*)$", 'gi');
match = regexp.exec(subtext);
if (match) {
return match[2] || match[1];
} else {
return null;
}
},
filter: function(query, data, searchKey) {
var _results, i, item, len;
_results = [];
for (i = 0, len = data.length; i < len; i++) {
item = data[i];
if (~new String(item[searchKey]).toLowerCase().indexOf(query.toLowerCase())) {
_results.push(item);
}
}
return _results;
},
remoteFilter: null,
sorter: function(query, items, searchKey) {
var _results, i, item, len;
if (!query) {
return items;
}
_results = [];
for (i = 0, len = items.length; i < len; i++) {
item = items[i];
item.atwho_order = new String(item[searchKey]).toLowerCase().indexOf(query.toLowerCase());
if (item.atwho_order > -1) {
_results.push(item);
}
}
return _results.sort(function(a, b) {
return a.atwho_order - b.atwho_order;
});
},
tplEval: function(tpl, map) {
var error, error1, template;
template = tpl;
try {
if (typeof tpl !== 'string') {
template = tpl(map);
}
return template.replace(/\$\{([^\}]*)\}/g, function(tag, key, pos) {
return map[key];
});
} catch (error1) {
error = error1;
return "";
}
},
highlighter: function(li, query) {
var regexp;
if (!query) {
return li;
}
regexp = new RegExp(">\\s*(\\w*?)(" + query.replace("+", "\\+") + ")(\\w*)\\s*<", 'ig');
return li.replace(regexp, function(str, $1, $2, $3) {
return '> ' + $1 + '<strong>' + $2 + '</strong>' + $3 + ' <';
});
},
beforeInsert: function(value, $li, e) {
return value;
},
beforeReposition: function(offset) {
return offset;
},
afterMatchFailed: function(at, el) {}
};
var App;
App = (function() {
function App(inputor) {
this.currentFlag = null;
this.controllers = {};
this.aliasMaps = {};
this.$inputor = $(inputor);
this.setupRootElement();
this.listen();
}
App.prototype.createContainer = function(doc) {
var ref;
if ((ref = this.$el) != null) {
ref.remove();
}
return $(doc.body).append(this.$el = $("<div class='atwho-container'></div>"));
};
App.prototype.setupRootElement = function(iframe, asRoot) {
var error, error1;
if (asRoot == null) {
asRoot = false;
}
if (iframe) {
this.window = iframe.contentWindow;
this.document = iframe.contentDocument || this.window.document;
this.iframe = iframe;
} else {
this.document = this.$inputor[0].ownerDocument;
this.window = this.document.defaultView || this.document.parentWindow;
try {
this.iframe = this.window.frameElement;
} catch (error1) {
error = error1;
this.iframe = null;
if ($.fn.atwho.debug) {
throw new Error("iframe auto-discovery is failed.\nPlease use `setIframe` to set the target iframe manually.\n" + error);
}
}
}
return this.createContainer((this.iframeAsRoot = asRoot) ? this.document : document);
};
App.prototype.controller = function(at) {
var c, current, currentFlag, ref;
if (this.aliasMaps[at]) {
current = this.controllers[this.aliasMaps[at]];
} else {
ref = this.controllers;
for (currentFlag in ref) {
c = ref[currentFlag];
if (currentFlag === at) {
current = c;
break;
}
}
}
if (current) {
return current;
} else {
return this.controllers[this.currentFlag];
}
};
App.prototype.setContextFor = function(at) {
this.currentFlag = at;
return this;
};
App.prototype.reg = function(flag, setting) {
var base, controller;
controller = (base = this.controllers)[flag] || (base[flag] = this.$inputor.is('[contentEditable]') ? new EditableController(this, flag) : new TextareaController(this, flag));
if (setting.alias) {
this.aliasMaps[setting.alias] = flag;
}
controller.init(setting);
return this;
};
App.prototype.listen = function() {
return this.$inputor.on('compositionstart', (function(_this) {
return function(e) {
var ref;
if ((ref = _this.controller()) != null) {
ref.view.hide();
}
_this.isComposing = true;
return null;
};
})(this)).on('compositionend', (function(_this) {
return function(e) {
_this.isComposing = false;
setTimeout(function(e) {
return _this.dispatch(e);
});
return null;
};
})(this)).on('keyup.atwhoInner', (function(_this) {
return function(e) {
return _this.onKeyup(e);
};
})(this)).on('keydown.atwhoInner', (function(_this) {
return function(e) {
return _this.onKeydown(e);
};
})(this)).on('blur.atwhoInner', (function(_this) {
return function(e) {
var c;
if (c = _this.controller()) {
c.expectedQueryCBId = null;
return c.view.hide(e, c.getOpt("displayTimeout"));
}
};
})(this)).on('click.atwhoInner', (function(_this) {
return function(e) {
return _this.dispatch(e);
};
})(this)).on('scroll.atwhoInner', (function(_this) {
return function() {
var lastScrollTop;
lastScrollTop = _this.$inputor.scrollTop();
return function(e) {
var currentScrollTop, ref;
currentScrollTop = e.target.scrollTop;
if (lastScrollTop !== currentScrollTop) {
if ((ref = _this.controller()) != null) {
ref.view.hide(e);
}
}
lastScrollTop = currentScrollTop;
return true;
};
};
})(this)());
};
App.prototype.shutdown = function() {
var _, c, ref;
ref = this.controllers;
for (_ in ref) {
c = ref[_];
c.destroy();
delete this.controllers[_];
}
this.$inputor.off('.atwhoInner');
return this.$el.remove();
};
App.prototype.dispatch = function(e) {
var _, c, ref, results;
ref = this.controllers;
results = [];
for (_ in ref) {
c = ref[_];
results.push(c.lookUp(e));
}
return results;
};
App.prototype.onKeyup = function(e) {
var ref;
switch (e.keyCode) {
case KEY_CODE.ESC:
e.preventDefault();
if ((ref = this.controller()) != null) {
ref.view.hide();
}
break;
case KEY_CODE.DOWN:
case KEY_CODE.UP:
case KEY_CODE.CTRL:
case KEY_CODE.ENTER:
$.noop();
break;
case KEY_CODE.P:
case KEY_CODE.N:
if (!e.ctrlKey) {
this.dispatch(e);
}
break;
default:
this.dispatch(e);
}
};
App.prototype.onKeydown = function(e) {
var ref, view;
view = (ref = this.controller()) != null ? ref.view : void 0;
if (!(view && view.visible())) {
return;
}
switch (e.keyCode) {
case KEY_CODE.ESC:
e.preventDefault();
view.hide(e);
break;
case KEY_CODE.UP:
e.preventDefault();
view.prev();
break;
case KEY_CODE.DOWN:
e.preventDefault();
view.next();
break;
case KEY_CODE.P:
if (!e.ctrlKey) {
return;
}
e.preventDefault();
view.prev();
break;
case KEY_CODE.N:
if (!e.ctrlKey) {
return;
}
e.preventDefault();
view.next();
break;
case KEY_CODE.TAB:
case KEY_CODE.ENTER:
case KEY_CODE.SPACE:
if (!view.visible()) {
return;
}
if (!this.controller().getOpt('spaceSelectsMatch') && e.keyCode === KEY_CODE.SPACE) {
return;
}
if (!this.controller().getOpt('tabSelectsMatch') && e.keyCode === KEY_CODE.TAB) {
return;
}
if (view.highlighted()) {
e.preventDefault();
view.choose(e);
} else {
view.hide(e);
}
break;
default:
$.noop();
}
};
return App;
})();
var Controller,
slice = [].slice;
Controller = (function() {
Controller.prototype.uid = function() {
return (Math.random().toString(16) + "000000000").substr(2, 8) + (new Date().getTime());
};
function Controller(app, at1) {
this.app = app;
this.at = at1;
this.$inputor = this.app.$inputor;
this.id = this.$inputor[0].id || this.uid();
this.expectedQueryCBId = null;
this.setting = null;
this.query = null;
this.pos = 0;
this.range = null;
if ((this.$el = $("#atwho-ground-" + this.id, this.app.$el)).length === 0) {
this.app.$el.append(this.$el = $("<div id='atwho-ground-" + this.id + "'></div>"));
}
this.model = new Model(this);
this.view = new View(this);
}
Controller.prototype.init = function(setting) {
this.setting = $.extend({}, this.setting || $.fn.atwho["default"], setting);
this.view.init();
return this.model.reload(this.setting.data);
};
Controller.prototype.destroy = function() {
this.trigger('beforeDestroy');
this.model.destroy();
this.view.destroy();
return this.$el.remove();
};
Controller.prototype.callDefault = function() {
var args, error, error1, funcName;
funcName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
try {
return DEFAULT_CALLBACKS[funcName].apply(this, args);
} catch (error1) {
error = error1;
return $.error(error + " Or maybe At.js doesn't have function " + funcName);
}
};
Controller.prototype.trigger = function(name, data) {
var alias, eventName;
if (data == null) {
data = [];
}
data.push(this);
alias = this.getOpt('alias');
eventName = alias ? name + "-" + alias + ".atwho" : name + ".atwho";
return this.$inputor.trigger(eventName, data);
};
Controller.prototype.callbacks = function(funcName) {
return this.getOpt("callbacks")[funcName] || DEFAULT_CALLBACKS[funcName];
};
Controller.prototype.getOpt = function(at, default_value) {
var e, error1;
try {
return this.setting[at];
} catch (error1) {
e = error1;
return null;
}
};
Controller.prototype.insertContentFor = function($li) {
var data, tpl;
tpl = this.getOpt('insertTpl');
data = $.extend({}, $li.data('itemData'), {
'atwho-at': this.at
});
return this.callbacks("tplEval").call(this, tpl, data, "onInsert");
};
Controller.prototype.renderView = function(data) {
var searchKey;
searchKey = this.getOpt("searchKey");
data = this.callbacks("sorter").call(this, this.query.text, data.slice(0, 1001), searchKey);
return this.view.render(data.slice(0, this.getOpt('limit')));
};
Controller.arrayToDefaultHash = function(data) {
var i, item, len, results;
if (!$.isArray(data)) {
return data;
}
results = [];
for (i = 0, len = data.length; i < len; i++) {
item = data[i];
if ($.isPlainObject(item)) {
results.push(item);
} else {
results.push({
name: item
});
}
}
return results;
};
Controller.prototype.lookUp = function(e) {
var query, wait;
if (e && e.type === 'click' && !this.getOpt('lookUpOnClick')) {
return;
}
if (this.getOpt('suspendOnComposing') && this.app.isComposing) {
return;
}
query = this.catchQuery(e);
if (!query) {
this.expectedQueryCBId = null;
return query;
}
this.app.setContextFor(this.at);
if (wait = this.getOpt('delay')) {
this._delayLookUp(query, wait);
} else {
this._lookUp(query);
}
return query;
};
Controller.prototype._delayLookUp = function(query, wait) {
var now, remaining;
now = Date.now ? Date.now() : new Date().getTime();
this.previousCallTime || (this.previousCallTime = now);
remaining = wait - (now - this.previousCallTime);
if ((0 < remaining && remaining < wait)) {
this.previousCallTime = now;
this._stopDelayedCall();
return this.delayedCallTimeout = setTimeout((function(_this) {
return function() {
_this.previousCallTime = 0;
_this.delayedCallTimeout = null;
return _this._lookUp(query);
};
})(this), wait);
} else {
this._stopDelayedCall();
if (this.previousCallTime !== now) {
this.previousCallTime = 0;
}
return this._lookUp(query);
}
};
Controller.prototype._stopDelayedCall = function() {
if (this.delayedCallTimeout) {
clearTimeout(this.delayedCallTimeout);
return this.delayedCallTimeout = null;
}
};
Controller.prototype._generateQueryCBId = function() {
return {};
};
Controller.prototype._lookUp = function(query) {
var _callback;
_callback = function(queryCBId, data) {
if (queryCBId !== this.expectedQueryCBId) {
return;
}
if (data && data.length > 0) {
return this.renderView(this.constructor.arrayToDefaultHash(data));
} else {
return this.view.hide();
}
};
this.expectedQueryCBId = this._generateQueryCBId();
return this.model.query(query.text, $.proxy(_callback, this, this.expectedQueryCBId));
};
return Controller;
})();
var TextareaController,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
TextareaController = (function(superClass) {
extend(TextareaController, superClass);
function TextareaController() {
return TextareaController.__super__.constructor.apply(this, arguments);
}
TextareaController.prototype.catchQuery = function() {
var caretPos, content, end, isString, query, start, subtext;
content = this.$inputor.val();
caretPos = this.$inputor.caret('pos', {
iframe: this.app.iframe
});
subtext = content.slice(0, caretPos);
query = this.callbacks("matcher").call(this, this.at, subtext, this.getOpt('startWithSpace'), this.getOpt("acceptSpaceBar"));
isString = typeof query === 'string';
if (isString && query.length < this.getOpt('minLen', 0)) {
return;
}
if (isString && query.length <= this.getOpt('maxLen', 20)) {
start = caretPos - query.length;
end = start + query.length;
this.pos = start;
query = {
'text': query,
'headPos': start,
'endPos': end
};
this.trigger("matched", [this.at, query.text]);
} else {
query = null;
this.view.hide();
}
return this.query = query;
};
TextareaController.prototype.rect = function() {
var c, iframeOffset, scaleBottom;
if (!(c = this.$inputor.caret('offset', this.pos - 1, {
iframe: this.app.iframe
}))) {
return;
}
if (this.app.iframe && !this.app.iframeAsRoot) {
iframeOffset = $(this.app.iframe).offset();
c.left += iframeOffset.left;
c.top += iframeOffset.top;
}
scaleBottom = this.app.document.selection ? 0 : 2;
return {
left: c.left,
top: c.top,
bottom: c.top + c.height + scaleBottom
};
};
TextareaController.prototype.insert = function(content, $li) {
var $inputor, source, startStr, suffix, text;
$inputor = this.$inputor;
source = $inputor.val();
startStr = source.slice(0, Math.max(this.query.headPos - this.at.length, 0));
suffix = (suffix = this.getOpt('suffix')) === "" ? suffix : suffix || " ";
content += suffix;
text = "" + startStr + content + (source.slice(this.query['endPos'] || 0));
$inputor.val(text);
$inputor.caret('pos', startStr.length + content.length, {
iframe: this.app.iframe
});
if (!$inputor.is(':focus')) {
$inputor.focus();
}
return $inputor.change();
};
return TextareaController;
})(Controller);
var EditableController,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
EditableController = (function(superClass) {
extend(EditableController, superClass);
function EditableController() {
return EditableController.__super__.constructor.apply(this, arguments);
}
EditableController.prototype._getRange = function() {
var sel;
sel = this.app.window.getSelection();
if (sel.rangeCount > 0) {
return sel.getRangeAt(0);
}
};
EditableController.prototype._setRange = function(position, node, range) {
if (range == null) {
range = this._getRange();
}
if (!range) {
return;
}
node = $(node)[0];
if (position === 'after') {
range.setEndAfter(node);
range.setStartAfter(node);
} else {
range.setEndBefore(node);
range.setStartBefore(node);
}
range.collapse(false);
return this._clearRange(range);
};
EditableController.prototype._clearRange = function(range) {
var sel;
if (range == null) {
range = this._getRange();
}
sel = this.app.window.getSelection();
if (this.ctrl_a_pressed == null) {
sel.removeAllRanges();
return sel.addRange(range);
}
};
EditableController.prototype._movingEvent = function(e) {
var ref;
return e.type === 'click' || ((ref = e.which) === KEY_CODE.RIGHT || ref === KEY_CODE.LEFT || ref === KEY_CODE.UP || ref === KEY_CODE.DOWN);
};
EditableController.prototype._unwrap = function(node) {
var next;
node = $(node).unwrap().get(0);
if ((next = node.nextSibling) && next.nodeValue) {
node.nodeValue += next.nodeValue;
$(next).remove();
}
return node;
};
EditableController.prototype.catchQuery = function(e) {
var $inserted, $query, _range, index, inserted, isString, lastNode, matched, offset, query, query_content, range;
if (!(range = this._getRange())) {
return;
}
if (!range.collapsed) {
return;
}
if (e.which === KEY_CODE.ENTER) {
($query = $(range.startContainer).closest('.atwho-query')).contents().unwrap();
if ($query.is(':empty')) {
$query.remove();
}
($query = $(".atwho-query", this.app.document)).text($query.text()).contents().last().unwrap();
this._clearRange();
return;
}
if (/firefox/i.test(navigator.userAgent)) {
if ($(range.startContainer).is(this.$inputor)) {
this._clearRange();
return;
}
if (e.which === KEY_CODE.BACKSPACE && range.startContainer.nodeType === document.ELEMENT_NODE && (offset = range.startOffset - 1) >= 0) {
_range = range.cloneRange();
_range.setStart(range.startContainer, offset);
if ($(_range.cloneContents()).contents().last().is('.atwho-inserted')) {
inserted = $(range.startContainer).contents().get(offset);
this._setRange('after', $(inserted).contents().last());
}
} else if (e.which === KEY_CODE.LEFT && range.startContainer.nodeType === document.TEXT_NODE) {
$inserted = $(range.startContainer.previousSibling);
if ($inserted.is('.atwho-inserted') && range.startOffset === 0) {
this._setRange('after', $inserted.contents().last());
}
}
}
$(range.startContainer).closest('.atwho-inserted').addClass('atwho-query').siblings().removeClass('atwho-query');
if (($query = $(".atwho-query", this.app.document)).length > 0 && $query.is(':empty') && $query.text().length === 0) {
$query.remove();
}
if (!this._movingEvent(e)) {
$query.removeClass('atwho-inserted');
}
if ($query.length > 0) {
switch (e.which) {
case KEY_CODE.LEFT:
this._setRange('before', $query.get(0), range);
$query.removeClass('atwho-query');
return;
case KEY_CODE.RIGHT:
this._setRange('after', $query.get(0).nextSibling, range);
$query.removeClass('atwho-query');
return;
}
}
if ($query.length > 0 && (query_content = $query.attr('data-atwho-at-query'))) {
$query.empty().html(query_content).attr('data-atwho-at-query', null);
this._setRange('after', $query.get(0), range);
}
_range = range.cloneRange();
_range.setStart(range.startContainer, 0);
matched = this.callbacks("matcher").call(this, this.at, _range.toString(), this.getOpt('startWithSpace'), this.getOpt("acceptSpaceBar"));
isString = typeof matched === 'string';
if ($query.length === 0 && isString && (index = range.startOffset - this.at.length - matched.length) >= 0) {
range.setStart(range.startContainer, index);
$query = $('<span/>', this.app.document).attr(this.getOpt("editableAtwhoQueryAttrs")).addClass('atwho-query');
range.surroundContents($query.get(0));
lastNode = $query.contents().last().get(0);
if (/firefox/i.test(navigator.userAgent)) {
range.setStart(lastNode, lastNode.length);
range.setEnd(lastNode, lastNode.length);
this._clearRange(range);
} else {
this._setRange('after', lastNode, range);
}
}
if (isString && matched.length < this.getOpt('minLen', 0)) {
return;
}
if (isString && matched.length <= this.getOpt('maxLen', 20)) {
query = {
text: matched,
el: $query
};
this.trigger("matched", [this.at, query.text]);
return this.query = query;
} else {
this.view.hide();
this.query = {
el: $query
};
if ($query.text().indexOf(this.at) >= 0) {
if (this._movingEvent(e) && $query.hasClass('atwho-inserted')) {
$query.removeClass('atwho-query');
} else if (false !== this.callbacks('afterMatchFailed').call(this, this.at, $query)) {
this._setRange("after", this._unwrap($query.text($query.text()).contents().first()));
}
}
return null;
}
};
EditableController.prototype.rect = function() {
var $iframe, iframeOffset, rect;
rect = this.query.el.offset();
if (this.app.iframe && !this.app.iframeAsRoot) {
iframeOffset = ($iframe = $(this.app.iframe)).offset();
rect.left += iframeOffset.left - this.$inputor.scrollLeft();
rect.top += iframeOffset.top - this.$inputor.scrollTop();
}
rect.bottom = rect.top + this.query.el.height();
return rect;
};
EditableController.prototype.insert = function(content, $li) {
var data, range, suffix, suffixNode;
if (!this.$inputor.is(':focus')) {
this.$inputor.focus();
}
suffix = (suffix = this.getOpt('suffix')) === "" ? suffix : suffix || "\u00A0";
data = $li.data('itemData');
this.query.el.removeClass('atwho-query').addClass('atwho-inserted').html(content).attr('data-atwho-at-query', "" + data['atwho-at'] + this.query.text);
if (range = this._getRange()) {
range.setEndAfter(this.query.el[0]);
range.collapse(false);
range.insertNode(suffixNode = this.app.document.createTextNode("\u200D" + suffix));
this._setRange('after', suffixNode, range);
}
if (!this.$inputor.is(':focus')) {
this.$inputor.focus();
}
return this.$inputor.change();
};
return EditableController;
})(Controller);
var Model;
Model = (function() {
function Model(context) {
this.context = context;
this.at = this.context.at;
this.storage = this.context.$inputor;
}
Model.prototype.destroy = function() {
return this.storage.data(this.at, null);
};
Model.prototype.saved = function() {
return this.fetch() > 0;
};
Model.prototype.query = function(query, callback) {
var _remoteFilter, data, searchKey;
data = this.fetch();
searchKey = this.context.getOpt("searchKey");
data = this.context.callbacks('filter').call(this.context, query, data, searchKey) || [];
_remoteFilter = this.context.callbacks('remoteFilter');
if (data.length > 0 || (!_remoteFilter && data.length === 0)) {
return callback(data);
} else {
return _remoteFilter.call(this.context, query, callback);
}
};
Model.prototype.fetch = function() {
return this.storage.data(this.at) || [];
};
Model.prototype.save = function(data) {
return this.storage.data(this.at, this.context.callbacks("beforeSave").call(this.context, data || []));
};
Model.prototype.load = function(data) {
if (!(this.saved() || !data)) {
return this._load(data);
}
};
Model.prototype.reload = function(data) {
return this._load(data);
};
Model.prototype._load = function(data) {
if (typeof data === "string") {
return $.ajax(data, {
dataType: "json"
}).done((function(_this) {
return function(data) {
return _this.save(data);
};
})(this));
} else {
return this.save(data);
}
};
return Model;
})();
var View;
View = (function() {
function View(context) {
this.context = context;
this.$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>");
this.$elUl = this.$el.children();
this.timeoutID = null;
this.context.$el.append(this.$el);
this.bindEvent();
}
View.prototype.init = function() {
var header_tpl, id;
id = this.context.getOpt("alias") || this.context.at.charCodeAt(0);
header_tpl = this.context.getOpt("headerTpl");
if (header_tpl && this.$el.children().length === 1) {
this.$el.prepend(header_tpl);
}
return this.$el.attr({
'id': "at-view-" + id
});
};
View.prototype.destroy = function() {
return this.$el.remove();
};
View.prototype.bindEvent = function() {
var $menu, lastCoordX, lastCoordY;
$menu = this.$el.find('ul');
lastCoordX = 0;
lastCoordY = 0;
return $menu.on('mousemove.atwho-view', 'li', (function(_this) {
return function(e) {
var $cur;
if (lastCoordX === e.clientX && lastCoordY === e.clientY) {
return;
}
lastCoordX = e.clientX;
lastCoordY = e.clientY;
$cur = $(e.currentTarget);
if ($cur.hasClass('cur')) {
return;
}
$menu.find('.cur').removeClass('cur');
return $cur.addClass('cur');
};
})(this)).on('click.atwho-view', 'li', (function(_this) {
return function(e) {
$menu.find('.cur').removeClass('cur');
$(e.currentTarget).addClass('cur');
_this.choose(e);
return e.preventDefault();
};
})(this));
};
View.prototype.visible = function() {
return this.$el.is(":visible");
};
View.prototype.highlighted = function() {
return this.$el.find(".cur").length > 0;
};
View.prototype.choose = function(e) {
var $li, content;
if (($li = this.$el.find(".cur")).length) {
content = this.context.insertContentFor($li);
this.context._stopDelayedCall();
this.context.insert(this.context.callbacks("beforeInsert").call(this.context, content, $li, e), $li);
this.context.trigger("inserted", [$li, e]);
this.hide(e);
}
if (this.context.getOpt("hideWithoutSuffix")) {
return this.stopShowing = true;
}
};
View.prototype.reposition = function(rect) {
var _window, offset, overflowOffset, ref;
_window = this.context.app.iframeAsRoot ? this.context.app.window : window;
if (rect.bottom + this.$el.height() - $(_window).scrollTop() > $(_window).height()) {
rect.bottom = rect.top - this.$el.height();
}
if (rect.left > (overflowOffset = $(_window).width() - this.$el.width() - 5)) {
rect.left = overflowOffset;
}
offset = {
left: rect.left,
top: rect.bottom
};
if ((ref = this.context.callbacks("beforeReposition")) != null) {
ref.call(this.context, offset);
}
this.$el.offset(offset);
return this.context.trigger("reposition", [offset]);
};
View.prototype.next = function() {
var cur, next, nextEl, offset;
cur = this.$el.find('.cur').removeClass('cur');
next = cur.next();
if (!next.length) {
next = this.$el.find('li:first');
}
next.addClass('cur');
nextEl = next[0];
offset = nextEl.offsetTop + nextEl.offsetHeight + (nextEl.nextSibling ? nextEl.nextSibling.offsetHeight : 0);
return this.scrollTop(Math.max(0, offset - this.$el.height()));
};
View.prototype.prev = function() {
var cur, offset, prev, prevEl;
cur = this.$el.find('.cur').removeClass('cur');
prev = cur.prev();
if (!prev.length) {
prev = this.$el.find('li:last');
}
prev.addClass('cur');
prevEl = prev[0];
offset = prevEl.offsetTop + prevEl.offsetHeight + (prevEl.nextSibling ? prevEl.nextSibling.offsetHeight : 0);
return this.scrollTop(Math.max(0, offset - this.$el.height()));
};
View.prototype.scrollTop = function(scrollTop) {
var scrollDuration;
scrollDuration = this.context.getOpt('scrollDuration');
if (scrollDuration) {
return this.$elUl.animate({
scrollTop: scrollTop
}, scrollDuration);
} else {
return this.$elUl.scrollTop(scrollTop);
}
};
View.prototype.show = function() {
var rect;
if (this.stopShowing) {
this.stopShowing = false;
return;
}
if (!this.visible()) {
this.$el.show();
this.$el.scrollTop(0);
this.context.trigger('shown');
}
if (rect = this.context.rect()) {
return this.reposition(rect);
}
};
View.prototype.hide = function(e, time) {
var callback;
if (!this.visible()) {
return;
}
if (isNaN(time)) {
this.$el.hide();
return this.context.trigger('hidden', [e]);
} else {
callback = (function(_this) {
return function() {
return _this.hide();
};
})(this);
clearTimeout(this.timeoutID);
return this.timeoutID = setTimeout(callback, time);
}
};
View.prototype.render = function(list) {
var $li, $ul, i, item, len, li, tpl;
if (!($.isArray(list) && list.length > 0)) {
this.hide();
return;
}
this.$el.find('ul').empty();
$ul = this.$el.find('ul');
tpl = this.context.getOpt('displayTpl');
for (i = 0, len = list.length; i < len; i++) {
item = list[i];
item = $.extend({}, item, {
'atwho-at': this.context.at
});
li = this.context.callbacks("tplEval").call(this.context, tpl, item, "onDisplay");
$li = $(this.context.callbacks("highlighter").call(this.context, li, this.context.query.text));
$li.data("item-data", item);
$ul.append($li);
}
this.show();
if (this.context.getOpt('highlightFirst')) {
return $ul.find("li:first").addClass("cur");
}
};
return View;
})();
var Api;
Api = {
load: function(at, data) {
var c;
if (c = this.controller(at)) {
return c.model.load(data);
}
},
isSelecting: function() {
var ref;
return !!((ref = this.controller()) != null ? ref.view.visible() : void 0);
},
hide: function() {
var ref;
return (ref = this.controller()) != null ? ref.view.hide() : void 0;
},
reposition: function() {
var c;
if (c = this.controller()) {
return c.view.reposition(c.rect());
}
},
setIframe: function(iframe, asRoot) {
this.setupRootElement(iframe, asRoot);
return null;
},
run: function() {
return this.dispatch();
},
destroy: function() {
this.shutdown();
return this.$inputor.data('atwho', null);
}
};
$.fn.atwho = function(method) {
var _args, result;
_args = arguments;
result = null;
this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each(function() {
var $this, app;
if (!(app = ($this = $(this)).data("atwho"))) {
$this.data('atwho', (app = new App(this)));
}
if (typeof method === 'object' || !method) {
return app.reg(method.at, method);
} else if (Api[method] && app) {
return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1));
} else {
return $.error("Method " + method + " does not exist on jQuery.atwho");
}
});
if (result != null) {
return result;
} else {
return this;
}
};
$.fn.atwho["default"] = {
at: void 0,
alias: void 0,
data: null,
displayTpl: "<li>${name}</li>",
insertTpl: "${atwho-at}${name}",
headerTpl: null,
callbacks: DEFAULT_CALLBACKS,
searchKey: "name",
suffix: void 0,
hideWithoutSuffix: false,
startWithSpace: true,
acceptSpaceBar: false,
highlightFirst: true,
limit: 5,
maxLen: 20,
minLen: 0,
displayTimeout: 300,
delay: null,
spaceSelectsMatch: false,
tabSelectsMatch: true,
editableAtwhoQueryAttrs: {},
scrollDuration: 150,
suspendOnComposing: true,
lookUpOnClick: true
};
$.fn.atwho.debug = false;
}));
(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) {
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, "<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;
}));
......@@ -606,7 +606,6 @@ iterall,1.2.2,MIT
jed,1.1.1,MIT
jira-ruby,1.4.1,MIT
jquery,3.3.1,MIT
jquery-atwho-rails,1.3.2,MIT
jquery-ujs,1.2.2,MIT
jquery.waitforimages,2.2.0,MIT
js-beautify,1.8.8,MIT
......
......@@ -1378,6 +1378,11 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
at.js@^1.5.4:
version "1.5.4"
resolved "https://registry.yarnpkg.com/at.js/-/at.js-1.5.4.tgz#8fc60cc80eadbe4874449b166a818e7ae1d784c1"
integrity sha512-G8mgUb/PqShPoH8AyjuxsTGvIr1o716BtQUKDM44C8qN2W615y7KGJ68MlTGamd0J0D/m28emUkzagaHTdrGZw==
atob@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
......@@ -6070,6 +6075,11 @@ jquery-ujs@1.2.2:
dependencies:
jquery ">=1.8.0"
jquery.caret@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/jquery.caret/-/jquery.caret-0.3.1.tgz#9c093318faf327eff322e826ca9f3241368bc7b8"
integrity sha1-nAkzGPrzJ+/zIugmyp8yQTaLx7g=
jquery.waitforimages@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/jquery.waitforimages/-/jquery.waitforimages-2.2.0.tgz#63f23131055a1b060dc913e6d874bcc9b9e6b16b"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment