Skip to content

Commit 2053342

Browse files
committed
update to v0.5.0
1 parent 606b097 commit 2053342

File tree

4 files changed

+138
-126
lines changed

4 files changed

+138
-126
lines changed

lib/assets/javascripts/jquery.atwho/jquery.atwho.js

+97-91
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! jquery.atwho - v0.4.11 - 2014-04-27
1+
/*! jquery.atwho - v0.5.0 - 2014-07-14
22
* Copyright (c) 2014 chord.luo <chord.luo@gmail.com>;
33
* homepage: http://ichord.github.com/At.js
44
* Licensed MIT
@@ -13,7 +13,7 @@
1313
}
1414
})(function($) {
1515

16-
var $CONTAINER, Api, App, Atwho, Controller, DEFAULT_CALLBACKS, KEY_CODE, Model, View,
16+
var $CONTAINER, Api, App, Controller, DEFAULT_CALLBACKS, KEY_CODE, Model, View,
1717
__slice = [].slice;
1818

1919
App = (function() {
@@ -28,25 +28,36 @@ App = (function() {
2828
}
2929

3030
App.prototype.setIframe = function(iframe) {
31-
var error;
3231
if (iframe) {
3332
this.window = iframe.contentWindow;
3433
this.document = iframe.contentDocument || this.window.document;
35-
this.iframe = iframe;
36-
return this;
34+
return this.iframe = iframe;
3735
} else {
38-
this.document = this.$inputor[0].ownerDocument;
39-
this.window = this.document.defaultView || this.document.parentWindow;
40-
try {
41-
return this.iframe = this.window.frameElement;
42-
} catch (_error) {
43-
error = _error;
44-
}
36+
this.document = document;
37+
this.window = window;
38+
return this.iframe = null;
4539
}
4640
};
4741

4842
App.prototype.controller = function(at) {
49-
return this.controllers[this.alias_maps[at] || at || this.current_flag];
43+
var c, current, current_flag, _ref;
44+
if (this.alias_maps[at]) {
45+
current = this.controllers[this.alias_maps[at]];
46+
} else {
47+
_ref = this.controllers;
48+
for (current_flag in _ref) {
49+
c = _ref[current_flag];
50+
if (current_flag === at) {
51+
current = c;
52+
break;
53+
}
54+
}
55+
}
56+
if (current) {
57+
return current;
58+
} else {
59+
return this.controllers[this.current_flag];
60+
}
5061
};
5162

5263
App.prototype.set_context_for = function(at) {
@@ -76,15 +87,20 @@ App = (function() {
7687
})(this)).on('scroll.atwhoInner', (function(_this) {
7788
return function(e) {
7889
var _ref;
79-
return (_ref = _this.controller()) != null ? _ref.view.hide() : void 0;
90+
return (_ref = _this.controller()) != null ? _ref.view.hide(e) : void 0;
8091
};
8192
})(this)).on('blur.atwhoInner', (function(_this) {
8293
return function(e) {
8394
var c;
8495
if (c = _this.controller()) {
85-
return c.view.hide(c.get_opt("display_timeout"));
96+
return c.view.hide(e, c.get_opt("display_timeout"));
8697
}
8798
};
99+
})(this)).on('click.atwhoInner', (function(_this) {
100+
return function(e) {
101+
var _ref;
102+
return (_ref = _this.controller()) != null ? _ref.view.hide(e) : void 0;
103+
};
88104
})(this));
89105
};
90106

@@ -153,7 +169,7 @@ App = (function() {
153169
switch (e.keyCode) {
154170
case KEY_CODE.ESC:
155171
e.preventDefault();
156-
view.hide();
172+
view.hide(e);
157173
break;
158174
case KEY_CODE.UP:
159175
e.preventDefault();
@@ -183,7 +199,7 @@ App = (function() {
183199
return;
184200
}
185201
e.preventDefault();
186-
view.choose();
202+
view.choose(e);
187203
break;
188204
default:
189205
$.noop();
@@ -274,7 +290,9 @@ Controller = (function() {
274290
Controller.prototype.catch_query = function() {
275291
var caret_pos, content, end, query, start, subtext;
276292
content = this.content();
277-
caret_pos = this.$inputor.caret('pos');
293+
caret_pos = this.$inputor.caret('pos', {
294+
iframe: this.app.iframe
295+
});
278296
subtext = content.slice(0, caret_pos);
279297
query = this.callbacks("matcher").call(this, this.at, subtext, this.get_opt('start_with_space'));
280298
if (typeof query === "string" && query.length <= this.get_opt('max_len', 20)) {
@@ -296,9 +314,9 @@ Controller = (function() {
296314

297315
Controller.prototype.rect = function() {
298316
var c, scale_bottom;
299-
if (!(c = this.$inputor.caret({
317+
if (!(c = this.$inputor.caret('offset', this.pos - 1, {
300318
iframe: this.app.iframe
301-
}).caret('offset', this.pos - 1))) {
319+
}))) {
302320
return;
303321
}
304322
if (this.$inputor.attr('contentEditable') === 'true') {
@@ -344,37 +362,32 @@ Controller = (function() {
344362
};
345363

346364
Controller.prototype.insert = function(content, $li) {
347-
var $inputor, $insert_node, class_name, content_node, insert_node, pos, range, sel, source, start_str, text;
365+
var $inputor, content_node, pos, range, sel, source, start_str, text, wrapped_content;
348366
$inputor = this.$inputor;
349-
if ($inputor.attr('contentEditable') === 'true') {
350-
class_name = "atwho-view-flag atwho-view-flag-" + (this.get_opt('alias') || this.at);
351-
content_node = "" + content + "<span contenteditable='false'>&nbsp;<span>";
352-
insert_node = "<span contenteditable='false' class='" + class_name + "'>" + content_node + "</span>";
353-
$insert_node = $(insert_node, this.app.document).data('atwho-data-item', $li.data('item-data'));
354-
if (this.app.document.selection) {
355-
$insert_node = $("<span contenteditable='true'></span>", this.app.document).html($insert_node);
356-
}
357-
}
367+
wrapped_content = this.callbacks('inserting_wrapper').call(this, $inputor, content, this.get_opt("suffix"));
358368
if ($inputor.is('textarea, input')) {
359-
content = '' + content;
360369
source = $inputor.val();
361370
start_str = source.slice(0, Math.max(this.query.head_pos - this.at.length, 0));
362-
text = "" + start_str + content + " " + (source.slice(this.query['end_pos'] || 0));
371+
text = "" + start_str + wrapped_content + (source.slice(this.query['end_pos'] || 0));
363372
$inputor.val(text);
364-
$inputor.caret('pos', start_str.length + content.length + 1);
373+
$inputor.caret('pos', start_str.length + wrapped_content.length, {
374+
iframe: this.app.iframe
375+
});
365376
} else if (range = this.range) {
366377
pos = range.startOffset - (this.query.end_pos - this.query.head_pos) - this.at.length;
367378
range.setStart(range.endContainer, Math.max(pos, 0));
368379
range.setEnd(range.endContainer, range.endOffset);
369380
range.deleteContents();
370-
range.insertNode($insert_node[0]);
381+
content_node = $(wrapped_content, this.app.document)[0];
382+
range.insertNode(content_node);
383+
range.setEndAfter(content_node);
371384
range.collapse(false);
372385
sel = this.app.window.getSelection();
373386
sel.removeAllRanges();
374387
sel.addRange(range);
375388
} else if (range = this.ie8_range) {
376389
range.moveStart('character', this.query.end_pos - this.query.head_pos - this.at.length);
377-
range.pasteHTML(content_node);
390+
range.pasteHTML(wrapped_content);
378391
range.collapse(false);
379392
range.select();
380393
}
@@ -504,7 +517,7 @@ View = (function() {
504517
return $(e.currentTarget).addClass('cur');
505518
}).on('click', (function(_this) {
506519
return function(e) {
507-
_this.choose();
520+
_this.choose(e);
508521
return e.preventDefault();
509522
};
510523
})(this));
@@ -514,13 +527,16 @@ View = (function() {
514527
return this.$el.is(":visible");
515528
};
516529

517-
View.prototype.choose = function() {
530+
View.prototype.choose = function(e) {
518531
var $li, content;
519532
if (($li = this.$el.find(".cur")).length) {
520533
content = this.context.insert_content_for($li);
521534
this.context.insert(this.context.callbacks("before_insert").call(this.context, content, $li), $li);
522-
this.context.trigger("inserted", [$li]);
523-
return this.hide();
535+
this.context.trigger("inserted", [$li, e]);
536+
this.hide(e);
537+
}
538+
if (this.context.get_opt("hide_without_suffix")) {
539+
return this.stop_showing = true;
524540
}
525541
};
526542

@@ -562,6 +578,10 @@ View = (function() {
562578

563579
View.prototype.show = function() {
564580
var rect;
581+
if (this.stop_showing) {
582+
this.stop_showing = false;
583+
return;
584+
}
565585
this.context.mark_range();
566586
if (!this.visible()) {
567587
this.$el.show();
@@ -572,12 +592,15 @@ View = (function() {
572592
}
573593
};
574594

575-
View.prototype.hide = function(time) {
595+
View.prototype.hide = function(e, time) {
576596
var callback;
577-
if (isNaN(time && this.visible())) {
597+
if (!this.visible()) {
598+
return;
599+
}
600+
if (isNaN(time)) {
578601
this.context.reset_rect();
579602
this.$el.hide();
580-
return this.context.trigger('hidden');
603+
return this.context.trigger('hidden', [e]);
581604
} else {
582605
callback = (function(_this) {
583606
return function() {
@@ -707,13 +730,32 @@ DEFAULT_CALLBACKS = {
707730
if (!query) {
708731
return li;
709732
}
710-
regexp = new RegExp(">\\s*(\\w*)(" + query.replace("+", "\\+") + ")(\\w*)\\s*<", 'ig');
733+
regexp = new RegExp(">\\s*(\\w*?)(" + query.replace("+", "\\+") + ")(\\w*)\\s*<", 'ig');
711734
return li.replace(regexp, function(str, $1, $2, $3) {
712735
return '> ' + $1 + '<strong>' + $2 + '</strong>' + $3 + ' <';
713736
});
714737
},
715738
before_insert: function(value, $li) {
716739
return value;
740+
},
741+
inserting_wrapper: function($inputor, content, suffix) {
742+
var new_suffix, wrapped_content;
743+
new_suffix = suffix === "" ? suffix : suffix || " ";
744+
if ($inputor.is('textarea, input')) {
745+
return '' + content + new_suffix;
746+
} else if ($inputor.attr('contentEditable') === 'true') {
747+
new_suffix = suffix === "" ? suffix : suffix || "&nbsp;";
748+
if (/firefox/i.test(navigator.userAgent)) {
749+
wrapped_content = "<span>" + content + new_suffix + "</span>";
750+
} else {
751+
suffix = "<span contenteditable='false'>" + new_suffix + "<span>";
752+
wrapped_content = "<span contenteditable='false'>" + content + suffix + "</span>";
753+
}
754+
if (this.app.document.selection) {
755+
wrapped_content = "<span contenteditable='true'>" + content + "</span>";
756+
}
757+
return wrapped_content;
758+
}
717759
}
718760
};
719761

@@ -724,36 +766,9 @@ Api = {
724766
return c.model.load(data);
725767
}
726768
},
727-
getInsertedItemsWithIDs: function(at) {
728-
var c, ids, items;
729-
if (!(c = this.controller(at))) {
730-
return [null, null];
731-
}
732-
if (at) {
733-
at = "-" + (c.get_opt('alias') || c.at);
734-
}
735-
ids = [];
736-
items = $.map(this.$inputor.find("span.atwho-view-flag" + (at || "")), function(item) {
737-
var data;
738-
data = $(item).data('atwho-data-item');
739-
if (ids.indexOf(data.id) > -1) {
740-
return;
741-
}
742-
if (data.id) {
743-
ids.push = data.id;
744-
}
745-
return data;
746-
});
747-
return [ids, items];
748-
},
749-
getInsertedItems: function(at) {
750-
return Api.getInsertedItemsWithIDs.apply(this, [at])[1];
751-
},
752-
getInsertedIDs: function(at) {
753-
return Api.getInsertedItemsWithIDs.apply(this, [at])[0];
754-
},
755769
setIframe: function(iframe) {
756-
return this.setIframe(iframe);
770+
this.setIframe(iframe);
771+
return null;
757772
},
758773
run: function() {
759774
return this.dispatch();
@@ -764,18 +779,6 @@ Api = {
764779
}
765780
};
766781

767-
Atwho = {
768-
init: function(options) {
769-
var $this, app;
770-
app = ($this = $(this)).data("atwho");
771-
if (!app) {
772-
$this.data('atwho', (app = new App(this)));
773-
}
774-
app.reg(options.at, options);
775-
return this;
776-
}
777-
};
778-
779782
$CONTAINER = $("<div id='atwho-container'></div>");
780783

781784
$.fn.atwho = function(method) {
@@ -784,13 +787,14 @@ $.fn.atwho = function(method) {
784787
$('body').append($CONTAINER);
785788
result = null;
786789
this.filter('textarea, input, [contenteditable=true]').each(function() {
787-
var app;
790+
var $this, app;
791+
if (!(app = ($this = $(this)).data("atwho"))) {
792+
$this.data('atwho', (app = new App(this)));
793+
}
788794
if (typeof method === 'object' || !method) {
789-
return Atwho.init.apply(this, _args);
790-
} else if (Api[method]) {
791-
if (app = $(this).data('atwho')) {
792-
return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1));
793-
}
795+
return app.reg(method.at, method);
796+
} else if (Api[method] && app) {
797+
return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1));
794798
} else {
795799
return $.error("Method " + method + " does not exist on jQuery.caret");
796800
}
@@ -803,9 +807,11 @@ $.fn.atwho["default"] = {
803807
alias: void 0,
804808
data: null,
805809
tpl: "<li data-value='${atwho-at}${name}'>${name}</li>",
806-
insert_tpl: "<span>${atwho-data-value}</span>",
810+
insert_tpl: "<span id='${id}'>${atwho-data-value}</span>",
807811
callbacks: DEFAULT_CALLBACKS,
808812
search_key: "name",
813+
suffix: void 0,
814+
hide_without_suffix: false,
809815
start_with_space: true,
810816
highlight_first: true,
811817
limit: 5,

0 commit comments

Comments
 (0)