jquery-atwho-rails 0.4.5 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2dd59a48f6a65bb4ecd8be26f8375c12aae7c0b
4
- data.tar.gz: 7663cd82b31f3989bfa58fbc785cceaebff87e81
3
+ metadata.gz: f4711b0cee4422713ce5672944e44588dcc560e8
4
+ data.tar.gz: a96d6fc2ee15c7d549f55e83aa855793f801b73b
5
5
  SHA512:
6
- metadata.gz: c4ba905d140575cf2c20de6d3bbf625fee4defdc2c0d97b4d9ebb05466f0fffba8bcbd62730daa98f79c57a556facc79d25bb2f7b07f23d9f08a3720839e3edd
7
- data.tar.gz: 3116c072145617a20e6ee19797dc1a07cb9e9ab02749543d5f8a7d2ab1df809c8f2c32a6b1774dd5e73d0c47685525f020ff5e4942f147f2bcb0484ddd16bf37
6
+ metadata.gz: da25e5bd13ae5af69b9037d6851c498ce3febed96b2074dbf2d6ab98132c74ae7b8118f9a2a15aab50fe48a06f107bc80e04162b32b8a2521021a8167afe46b4
7
+ data.tar.gz: 8c71f0f82b185ead06af5a8c3311b1e59192fe451e8dcede7be675ae41668b158c082489b48ebbe6ac9c2f402475e3bc35d29ff99ceb4f93882884b685d62726
data/Rakefile CHANGED
@@ -1,9 +1,11 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
+ at_dir = "tmp/At.js"
4
+ bower_dir = "#{at_dir}/bower_components/"
5
+
3
6
  desc "sync from At.js"
4
7
  task :sync do
5
8
  puts " * syncing..."
6
- at_dir = "tmp/At.js"
7
9
  FileUtils.mkdir_p("tmp") unless Dir.exist? "tmp"
8
10
  unless Dir.exist? at_dir
9
11
  system "git clone git://github.com/ichord/At.js.git #{at_dir}"
@@ -12,12 +14,23 @@ task :sync do
12
14
  end
13
15
  end
14
16
 
17
+ desc "load dependences"
18
+ task :bower_install => :sync do
19
+ unless Dir.exist? bower_dir
20
+ Dir.chdir(at_dir) { puts %x{bower install} }
21
+ end
22
+ end
23
+
15
24
  desc "copy assets"
16
- task :fresh => :sync do
25
+ task :fresh => [:bower_install, :sync] do
17
26
  puts "", " * Copying..."
18
27
  source_dir = "tmp/At.js/dist"
19
28
  dist_dir = "lib/assets"
20
- FileUtils.copy "#{source_dir}/js/jquery.atwho.js", "#{dist_dir}/javascripts/"
29
+
30
+ js_dist_dir = "#{dist_dir}/javascripts/jquery.atwho/"
31
+ FileUtils.copy "#{bower_dir}/Caret.js/src/jquery.caret.js", js_dist_dir
32
+ FileUtils.copy "#{source_dir}/js/jquery.atwho.js", js_dist_dir
33
+
21
34
  FileUtils.copy "#{source_dir}/css/jquery.atwho.css", "#{dist_dir}/stylesheets/"
22
35
  puts `ls -R #{dist_dir}`
23
36
  end
@@ -0,0 +1,2 @@
1
+ //= require ./jquery.caret
2
+ //= require ./jquery.atwho
@@ -0,0 +1,752 @@
1
+ /*! jquery.atwho - v0.4.7 - 2014-02-22
2
+ * Copyright (c) 2014 chord.luo <chord.luo@gmail.com>;
3
+ * homepage: http://ichord.github.com/At.js
4
+ * Licensed MIT
5
+ */
6
+
7
+ (function() {
8
+ (function(factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ return define(['jquery'], factory);
11
+ } else {
12
+ return factory(window.jQuery);
13
+ }
14
+ })(function($) {
15
+
16
+ var $CONTAINER, Api, App, Atwho, Controller, DEFAULT_CALLBACKS, KEY_CODE, Model, View,
17
+ __slice = [].slice;
18
+
19
+ App = (function() {
20
+ function App(inputor) {
21
+ this.current_flag = null;
22
+ this.controllers = {};
23
+ this.alias_maps = {};
24
+ this.$inputor = $(inputor);
25
+ this.listen();
26
+ }
27
+
28
+ App.prototype.controller = function(at) {
29
+ return this.controllers[this.alias_maps[at] || at || this.current_flag];
30
+ };
31
+
32
+ App.prototype.set_context_for = function(at) {
33
+ this.current_flag = at;
34
+ return this;
35
+ };
36
+
37
+ App.prototype.reg = function(flag, setting) {
38
+ var controller, _base;
39
+ controller = (_base = this.controllers)[flag] || (_base[flag] = new Controller(this, flag));
40
+ if (setting.alias) {
41
+ this.alias_maps[setting.alias] = flag;
42
+ }
43
+ controller.init(setting);
44
+ return this;
45
+ };
46
+
47
+ App.prototype.listen = function() {
48
+ return this.$inputor.on('keyup.atwhoInner', (function(_this) {
49
+ return function(e) {
50
+ return _this.on_keyup(e);
51
+ };
52
+ })(this)).on('keydown.atwhoInner', (function(_this) {
53
+ return function(e) {
54
+ return _this.on_keydown(e);
55
+ };
56
+ })(this)).on('scroll.atwhoInner', (function(_this) {
57
+ return function(e) {
58
+ var _ref;
59
+ return (_ref = _this.controller()) != null ? _ref.view.hide() : void 0;
60
+ };
61
+ })(this)).on('blur.atwhoInner', (function(_this) {
62
+ return function(e) {
63
+ var c;
64
+ if (c = _this.controller()) {
65
+ return c.view.hide(c.get_opt("display_timeout"));
66
+ }
67
+ };
68
+ })(this));
69
+ };
70
+
71
+ App.prototype.shutdown = function() {
72
+ var c, _, _ref;
73
+ _ref = this.controllers;
74
+ for (_ in _ref) {
75
+ c = _ref[_];
76
+ c.destroy();
77
+ }
78
+ return this.$inputor.off('.atwhoInner');
79
+ };
80
+
81
+ App.prototype.dispatch = function() {
82
+ return $.map(this.controllers, (function(_this) {
83
+ return function(c) {
84
+ if (c.look_up()) {
85
+ return _this.set_context_for(c.at);
86
+ }
87
+ };
88
+ })(this));
89
+ };
90
+
91
+ App.prototype.on_keyup = function(e) {
92
+ var _ref;
93
+ switch (e.keyCode) {
94
+ case KEY_CODE.ESC:
95
+ e.preventDefault();
96
+ if ((_ref = this.controller()) != null) {
97
+ _ref.view.hide();
98
+ }
99
+ break;
100
+ case KEY_CODE.DOWN:
101
+ case KEY_CODE.UP:
102
+ $.noop();
103
+ break;
104
+ default:
105
+ this.dispatch();
106
+ }
107
+ };
108
+
109
+ App.prototype.on_keydown = function(e) {
110
+ var view, _ref;
111
+ view = (_ref = this.controller()) != null ? _ref.view : void 0;
112
+ if (!(view && view.visible())) {
113
+ return;
114
+ }
115
+ switch (e.keyCode) {
116
+ case KEY_CODE.ESC:
117
+ e.preventDefault();
118
+ view.hide();
119
+ break;
120
+ case KEY_CODE.UP:
121
+ e.preventDefault();
122
+ view.prev();
123
+ break;
124
+ case KEY_CODE.DOWN:
125
+ e.preventDefault();
126
+ view.next();
127
+ break;
128
+ case KEY_CODE.TAB:
129
+ case KEY_CODE.ENTER:
130
+ if (!view.visible()) {
131
+ return;
132
+ }
133
+ e.preventDefault();
134
+ view.choose();
135
+ break;
136
+ default:
137
+ $.noop();
138
+ }
139
+ };
140
+
141
+ return App;
142
+
143
+ })();
144
+
145
+ Controller = (function() {
146
+ var uuid, _uuid;
147
+
148
+ _uuid = 0;
149
+
150
+ uuid = function() {
151
+ return _uuid += 1;
152
+ };
153
+
154
+ function Controller(app, at) {
155
+ this.app = app;
156
+ this.at = at;
157
+ this.$inputor = this.app.$inputor;
158
+ this.oDocument = this.$inputor[0].ownerDocument;
159
+ this.oWindow = this.oDocument.defaultView || this.oDocument.parentWindow;
160
+ this.id = this.$inputor[0].id || uuid();
161
+ this.setting = null;
162
+ this.query = null;
163
+ this.pos = 0;
164
+ this.cur_rect = null;
165
+ this.range = null;
166
+ $CONTAINER.append(this.$el = $("<div id='atwho-ground-" + this.id + "'></div>"));
167
+ this.model = new Model(this);
168
+ this.view = new View(this);
169
+ }
170
+
171
+ Controller.prototype.init = function(setting) {
172
+ this.setting = $.extend({}, this.setting || $.fn.atwho["default"], setting);
173
+ this.view.init();
174
+ return this.model.reload(this.setting.data);
175
+ };
176
+
177
+ Controller.prototype.destroy = function() {
178
+ this.trigger('beforeDestroy');
179
+ this.model.destroy();
180
+ return this.view.destroy();
181
+ };
182
+
183
+ Controller.prototype.call_default = function() {
184
+ var args, error, func_name;
185
+ func_name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
186
+ try {
187
+ return DEFAULT_CALLBACKS[func_name].apply(this, args);
188
+ } catch (_error) {
189
+ error = _error;
190
+ return $.error("" + error + " Or maybe At.js doesn't have function " + func_name);
191
+ }
192
+ };
193
+
194
+ Controller.prototype.trigger = function(name, data) {
195
+ var alias, event_name;
196
+ if (data == null) {
197
+ data = [];
198
+ }
199
+ data.push(this);
200
+ alias = this.get_opt('alias');
201
+ event_name = alias ? "" + name + "-" + alias + ".atwho" : "" + name + ".atwho";
202
+ return this.$inputor.trigger(event_name, data);
203
+ };
204
+
205
+ Controller.prototype.callbacks = function(func_name) {
206
+ return this.get_opt("callbacks")[func_name] || DEFAULT_CALLBACKS[func_name];
207
+ };
208
+
209
+ Controller.prototype.get_opt = function(at, default_value) {
210
+ var e;
211
+ try {
212
+ return this.setting[at];
213
+ } catch (_error) {
214
+ e = _error;
215
+ return null;
216
+ }
217
+ };
218
+
219
+ Controller.prototype.content = function() {
220
+ if (this.$inputor.is('textarea, input')) {
221
+ return this.$inputor.val();
222
+ } else {
223
+ return this.$inputor.text();
224
+ }
225
+ };
226
+
227
+ Controller.prototype.catch_query = function() {
228
+ var caret_pos, content, end, query, start, subtext;
229
+ content = this.content();
230
+ caret_pos = this.$inputor.caret('pos');
231
+ subtext = content.slice(0, caret_pos);
232
+ query = this.callbacks("matcher").call(this, this.at, subtext, this.get_opt('start_with_space'));
233
+ if (typeof query === "string" && query.length <= this.get_opt('max_len', 20)) {
234
+ start = caret_pos - query.length;
235
+ end = start + query.length;
236
+ this.pos = start;
237
+ query = {
238
+ 'text': query.toLowerCase(),
239
+ 'head_pos': start,
240
+ 'end_pos': end
241
+ };
242
+ this.trigger("matched", [this.at, query.text]);
243
+ } else {
244
+ this.view.hide();
245
+ }
246
+ return this.query = query;
247
+ };
248
+
249
+ Controller.prototype.rect = function() {
250
+ var c, scale_bottom;
251
+ if (!(c = this.$inputor.caret('offset', this.pos - 1))) {
252
+ return;
253
+ }
254
+ if (this.$inputor.attr('contentEditable') === 'true') {
255
+ c = (this.cur_rect || (this.cur_rect = c)) || c;
256
+ }
257
+ scale_bottom = document.selection ? 0 : 2;
258
+ return {
259
+ left: c.left,
260
+ top: c.top,
261
+ bottom: c.top + c.height + scale_bottom
262
+ };
263
+ };
264
+
265
+ Controller.prototype.reset_rect = function() {
266
+ if (this.$inputor.attr('contentEditable') === 'true') {
267
+ return this.cur_rect = null;
268
+ }
269
+ };
270
+
271
+ Controller.prototype.mark_range = function() {
272
+ if (this.$inputor.attr('contentEditable') === 'true') {
273
+ if (this.oWindow.getSelection) {
274
+ this.range = this.oWindow.getSelection().getRangeAt(0);
275
+ }
276
+ if (this.oDocument.selection) {
277
+ return this.ie8_range = this.oDocument.selection.createRange();
278
+ }
279
+ }
280
+ };
281
+
282
+ Controller.prototype.insert_content_for = function($li) {
283
+ var data, data_value, tpl;
284
+ data_value = $li.data('value');
285
+ tpl = this.get_opt('insert_tpl');
286
+ if (this.$inputor.is('textarea, input') || !tpl) {
287
+ return data_value;
288
+ }
289
+ data = $.extend({}, $li.data('item-data'), {
290
+ 'atwho-data-value': data_value,
291
+ 'atwho-at': this.at
292
+ });
293
+ return this.callbacks("tpl_eval").call(this, tpl, data);
294
+ };
295
+
296
+ Controller.prototype.insert = function(content, $li) {
297
+ var $inputor, $insert_node, class_name, content_node, insert_node, pos, range, sel, source, start_str, text;
298
+ $inputor = this.$inputor;
299
+ if ($inputor.attr('contentEditable') === 'true') {
300
+ class_name = "atwho-view-flag atwho-view-flag-" + (this.get_opt('alias') || this.at);
301
+ content_node = "" + content + "<span contenteditable='false'>&nbsp;<span>";
302
+ insert_node = "<span contenteditable='false' class='" + class_name + "'>" + content_node + "</span>";
303
+ $insert_node = $(insert_node, this.oDocument).data('atwho-data-item', $li.data('item-data'));
304
+ if (this.oDocument.selection) {
305
+ $insert_node = $("<span contenteditable='true'></span>", this.oDocument).html($insert_node);
306
+ }
307
+ }
308
+ if ($inputor.is('textarea, input')) {
309
+ content = '' + content;
310
+ source = $inputor.val();
311
+ start_str = source.slice(0, Math.max(this.query.head_pos - this.at.length, 0));
312
+ text = "" + start_str + content + " " + (source.slice(this.query['end_pos'] || 0));
313
+ $inputor.val(text);
314
+ $inputor.caret('pos', start_str.length + content.length + 1);
315
+ } else if (range = this.range) {
316
+ pos = range.startOffset - (this.query.end_pos - this.query.head_pos) - this.at.length;
317
+ range.setStart(range.endContainer, Math.max(pos, 0));
318
+ range.setEnd(range.endContainer, range.endOffset);
319
+ range.deleteContents();
320
+ range.insertNode($insert_node[0]);
321
+ range.collapse(false);
322
+ sel = this.oWindow.getSelection();
323
+ sel.removeAllRanges();
324
+ sel.addRange(range);
325
+ } else if (range = this.ie8_range) {
326
+ range.moveStart('character', this.query.end_pos - this.query.head_pos - this.at.length);
327
+ range.pasteHTML(content_node);
328
+ range.collapse(false);
329
+ range.select();
330
+ }
331
+ if (!$inputor.is(':focus')) {
332
+ $inputor.focus();
333
+ }
334
+ return $inputor.change();
335
+ };
336
+
337
+ Controller.prototype.render_view = function(data) {
338
+ var search_key;
339
+ search_key = this.get_opt("search_key");
340
+ data = this.callbacks("sorter").call(this, this.query.text, data.slice(0, 1001), search_key);
341
+ return this.view.render(data.slice(0, this.get_opt('limit')));
342
+ };
343
+
344
+ Controller.prototype.look_up = function() {
345
+ var query, _callback;
346
+ if (!(query = this.catch_query())) {
347
+ return;
348
+ }
349
+ _callback = function(data) {
350
+ if (data && data.length > 0) {
351
+ return this.render_view(data);
352
+ } else {
353
+ return this.view.hide();
354
+ }
355
+ };
356
+ this.model.query(query.text, $.proxy(_callback, this));
357
+ return query;
358
+ };
359
+
360
+ return Controller;
361
+
362
+ })();
363
+
364
+ Model = (function() {
365
+ function Model(context) {
366
+ this.context = context;
367
+ this.at = this.context.at;
368
+ this.storage = this.context.$inputor;
369
+ }
370
+
371
+ Model.prototype.destroy = function() {
372
+ return this.storage.data(this.at, null);
373
+ };
374
+
375
+ Model.prototype.saved = function() {
376
+ return this.fetch() > 0;
377
+ };
378
+
379
+ Model.prototype.query = function(query, callback) {
380
+ var data, search_key, _remote_filter;
381
+ data = this.fetch();
382
+ search_key = this.context.get_opt("search_key");
383
+ data = this.context.callbacks('filter').call(this.context, query, data, search_key) || [];
384
+ _remote_filter = this.context.callbacks('remote_filter');
385
+ if (data.length > 0 || (!_remote_filter && data.length === 0)) {
386
+ return callback(data);
387
+ } else {
388
+ return _remote_filter.call(this.context, query, callback);
389
+ }
390
+ };
391
+
392
+ Model.prototype.fetch = function() {
393
+ return this.storage.data(this.at) || [];
394
+ };
395
+
396
+ Model.prototype.save = function(data) {
397
+ return this.storage.data(this.at, this.context.callbacks("before_save").call(this.context, data || []));
398
+ };
399
+
400
+ Model.prototype.load = function(data) {
401
+ if (!(this.saved() || !data)) {
402
+ return this._load(data);
403
+ }
404
+ };
405
+
406
+ Model.prototype.reload = function(data) {
407
+ return this._load(data);
408
+ };
409
+
410
+ Model.prototype._load = function(data) {
411
+ if (typeof data === "string") {
412
+ return $.ajax(data, {
413
+ dataType: "json"
414
+ }).done((function(_this) {
415
+ return function(data) {
416
+ return _this.save(data);
417
+ };
418
+ })(this));
419
+ } else {
420
+ return this.save(data);
421
+ }
422
+ };
423
+
424
+ return Model;
425
+
426
+ })();
427
+
428
+ View = (function() {
429
+ function View(context) {
430
+ this.context = context;
431
+ this.$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>");
432
+ this.timeout_id = null;
433
+ this.context.$el.append(this.$el);
434
+ this.bind_event();
435
+ }
436
+
437
+ View.prototype.init = function() {
438
+ var id;
439
+ id = this.context.get_opt("alias") || this.context.at.charCodeAt(0);
440
+ return this.$el.attr({
441
+ 'id': "at-view-" + id
442
+ });
443
+ };
444
+
445
+ View.prototype.destroy = function() {
446
+ return this.$el.remove();
447
+ };
448
+
449
+ View.prototype.bind_event = function() {
450
+ var $menu;
451
+ $menu = this.$el.find('ul');
452
+ return $menu.on('mouseenter.atwho-view', 'li', function(e) {
453
+ $menu.find('.cur').removeClass('cur');
454
+ return $(e.currentTarget).addClass('cur');
455
+ }).on('click', (function(_this) {
456
+ return function(e) {
457
+ _this.choose();
458
+ return e.preventDefault();
459
+ };
460
+ })(this));
461
+ };
462
+
463
+ View.prototype.visible = function() {
464
+ return this.$el.is(":visible");
465
+ };
466
+
467
+ View.prototype.choose = function() {
468
+ var $li, content;
469
+ $li = this.$el.find(".cur");
470
+ content = this.context.insert_content_for($li);
471
+ this.context.insert(this.context.callbacks("before_insert").call(this.context, content, $li), $li);
472
+ this.context.trigger("inserted", [$li]);
473
+ return this.hide();
474
+ };
475
+
476
+ View.prototype.reposition = function(rect) {
477
+ var offset;
478
+ if (rect.bottom + this.$el.height() - $(window).scrollTop() > $(window).height()) {
479
+ rect.bottom = rect.top - this.$el.height();
480
+ }
481
+ offset = {
482
+ left: rect.left,
483
+ top: rect.bottom
484
+ };
485
+ this.$el.offset(offset);
486
+ return this.context.trigger("reposition", [offset]);
487
+ };
488
+
489
+ View.prototype.next = function() {
490
+ var cur, next;
491
+ cur = this.$el.find('.cur').removeClass('cur');
492
+ next = cur.next();
493
+ if (!next.length) {
494
+ next = this.$el.find('li:first');
495
+ }
496
+ return next.addClass('cur');
497
+ };
498
+
499
+ View.prototype.prev = function() {
500
+ var cur, prev;
501
+ cur = this.$el.find('.cur').removeClass('cur');
502
+ prev = cur.prev();
503
+ if (!prev.length) {
504
+ prev = this.$el.find('li:last');
505
+ }
506
+ return prev.addClass('cur');
507
+ };
508
+
509
+ View.prototype.show = function() {
510
+ var rect;
511
+ this.context.mark_range();
512
+ if (!this.visible()) {
513
+ this.$el.show();
514
+ }
515
+ if (rect = this.context.rect()) {
516
+ return this.reposition(rect);
517
+ }
518
+ };
519
+
520
+ View.prototype.hide = function(time) {
521
+ var callback;
522
+ if (isNaN(time && this.visible())) {
523
+ this.context.reset_rect();
524
+ return this.$el.hide();
525
+ } else {
526
+ callback = (function(_this) {
527
+ return function() {
528
+ return _this.hide();
529
+ };
530
+ })(this);
531
+ clearTimeout(this.timeout_id);
532
+ return this.timeout_id = setTimeout(callback, time);
533
+ }
534
+ };
535
+
536
+ View.prototype.render = function(list) {
537
+ var $li, $ul, item, li, tpl, _i, _len;
538
+ if (!($.isArray(list) && list.length > 0)) {
539
+ this.hide();
540
+ return;
541
+ }
542
+ this.$el.find('ul').empty();
543
+ $ul = this.$el.find('ul');
544
+ tpl = this.context.get_opt('tpl');
545
+ for (_i = 0, _len = list.length; _i < _len; _i++) {
546
+ item = list[_i];
547
+ item = $.extend({}, item, {
548
+ 'atwho-at': this.context.at
549
+ });
550
+ li = this.context.callbacks("tpl_eval").call(this.context, tpl, item);
551
+ $li = $(this.context.callbacks("highlighter").call(this.context, li, this.context.query.text));
552
+ $li.data("item-data", item);
553
+ $ul.append($li);
554
+ }
555
+ this.show();
556
+ return $ul.find("li:first").addClass("cur");
557
+ };
558
+
559
+ return View;
560
+
561
+ })();
562
+
563
+ KEY_CODE = {
564
+ DOWN: 40,
565
+ UP: 38,
566
+ ESC: 27,
567
+ TAB: 9,
568
+ ENTER: 13
569
+ };
570
+
571
+ DEFAULT_CALLBACKS = {
572
+ before_save: function(data) {
573
+ var item, _i, _len, _results;
574
+ if (!$.isArray(data)) {
575
+ return data;
576
+ }
577
+ _results = [];
578
+ for (_i = 0, _len = data.length; _i < _len; _i++) {
579
+ item = data[_i];
580
+ if ($.isPlainObject(item)) {
581
+ _results.push(item);
582
+ } else {
583
+ _results.push({
584
+ name: item
585
+ });
586
+ }
587
+ }
588
+ return _results;
589
+ },
590
+ matcher: function(flag, subtext, should_start_with_space) {
591
+ var match, regexp;
592
+ flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
593
+ if (should_start_with_space) {
594
+ flag = '(?:^|\\s)' + flag;
595
+ }
596
+ regexp = new RegExp(flag + '([A-Za-z0-9_\+\-]*)$|' + flag + '([^\\x00-\\xff]*)$', 'gi');
597
+ match = regexp.exec(subtext);
598
+ if (match) {
599
+ return match[2] || match[1];
600
+ } else {
601
+ return null;
602
+ }
603
+ },
604
+ filter: function(query, data, search_key) {
605
+ var item, _i, _len, _results;
606
+ _results = [];
607
+ for (_i = 0, _len = data.length; _i < _len; _i++) {
608
+ item = data[_i];
609
+ if (~item[search_key].toLowerCase().indexOf(query)) {
610
+ _results.push(item);
611
+ }
612
+ }
613
+ return _results;
614
+ },
615
+ remote_filter: null,
616
+ sorter: function(query, items, search_key) {
617
+ var item, _i, _len, _results;
618
+ if (!query) {
619
+ return items;
620
+ }
621
+ _results = [];
622
+ for (_i = 0, _len = items.length; _i < _len; _i++) {
623
+ item = items[_i];
624
+ item.atwho_order = item[search_key].toLowerCase().indexOf(query);
625
+ if (item.atwho_order > -1) {
626
+ _results.push(item);
627
+ }
628
+ }
629
+ return _results.sort(function(a, b) {
630
+ return a.atwho_order - b.atwho_order;
631
+ });
632
+ },
633
+ tpl_eval: function(tpl, map) {
634
+ var error;
635
+ try {
636
+ return tpl.replace(/\$\{([^\}]*)\}/g, function(tag, key, pos) {
637
+ return map[key];
638
+ });
639
+ } catch (_error) {
640
+ error = _error;
641
+ return "";
642
+ }
643
+ },
644
+ highlighter: function(li, query) {
645
+ var regexp;
646
+ if (!query) {
647
+ return li;
648
+ }
649
+ regexp = new RegExp(">\\s*(\\w*)(" + query.replace("+", "\\+") + ")(\\w*)\\s*<", 'ig');
650
+ return li.replace(regexp, function(str, $1, $2, $3) {
651
+ return '> ' + $1 + '<strong>' + $2 + '</strong>' + $3 + ' <';
652
+ });
653
+ },
654
+ before_insert: function(value, $li) {
655
+ return value;
656
+ }
657
+ };
658
+
659
+ Api = {
660
+ load: function(at, data) {
661
+ var c;
662
+ if (c = this.controller(at)) {
663
+ return c.model.load(data);
664
+ }
665
+ },
666
+ getInsertedItemsWithIDs: function(at) {
667
+ var c, ids, items;
668
+ if (!(c = this.controller(at))) {
669
+ return [null, null];
670
+ }
671
+ if (at) {
672
+ at = "-" + (c.get_opt('alias') || c.at);
673
+ }
674
+ ids = [];
675
+ items = $.map(this.$inputor.find("span.atwho-view-flag" + (at || "")), function(item) {
676
+ var data;
677
+ data = $(item).data('atwho-data-item');
678
+ if (ids.indexOf(data.id) > -1) {
679
+ return;
680
+ }
681
+ if (data.id) {
682
+ ids.push = data.id;
683
+ }
684
+ return data;
685
+ });
686
+ return [ids, items];
687
+ },
688
+ getInsertedItems: function(at) {
689
+ return Api.getInsertedItemsWithIDs.apply(this, [at])[1];
690
+ },
691
+ getInsertedIDs: function(at) {
692
+ return Api.getInsertedItemsWithIDs.apply(this, [at])[0];
693
+ },
694
+ run: function() {
695
+ return this.dispatch();
696
+ },
697
+ destroy: function() {
698
+ this.shutdown();
699
+ return this.$inputor.data('atwho', null);
700
+ }
701
+ };
702
+
703
+ Atwho = {
704
+ init: function(options) {
705
+ var $this, app;
706
+ app = ($this = $(this)).data("atwho");
707
+ if (!app) {
708
+ $this.data('atwho', (app = new App(this)));
709
+ }
710
+ app.reg(options.at, options);
711
+ return this;
712
+ }
713
+ };
714
+
715
+ $CONTAINER = $("<div id='atwho-container'></div>");
716
+
717
+ $.fn.atwho = function(method) {
718
+ var result, _args;
719
+ _args = arguments;
720
+ $('body').append($CONTAINER);
721
+ result = null;
722
+ this.filter('textarea, input, [contenteditable=true]').each(function() {
723
+ var app;
724
+ if (typeof method === 'object' || !method) {
725
+ return Atwho.init.apply(this, _args);
726
+ } else if (Api[method]) {
727
+ if (app = $(this).data('atwho')) {
728
+ return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1));
729
+ }
730
+ } else {
731
+ return $.error("Method " + method + " does not exist on jQuery.caret");
732
+ }
733
+ });
734
+ return result || this;
735
+ };
736
+
737
+ $.fn.atwho["default"] = {
738
+ at: void 0,
739
+ alias: void 0,
740
+ data: null,
741
+ tpl: "<li data-value='${atwho-at}${name}'>${name}</li>",
742
+ insert_tpl: "<span>${atwho-data-value}</span>",
743
+ callbacks: DEFAULT_CALLBACKS,
744
+ search_key: "name",
745
+ start_with_space: true,
746
+ limit: 5,
747
+ max_len: 20,
748
+ display_timeout: 300
749
+ };
750
+
751
+ });
752
+ }).call(this);