jquery-atwho-rails 0.3.3 → 0.4.1
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 +4 -4
- data/lib/assets/javascripts/jquery.atwho.js +374 -189
- data/lib/jquery-atwho-rails/version.rb +1 -1
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee0d4a6e119e2f77127b810901f3572f95cf1d62
|
4
|
+
data.tar.gz: 02c7cea94f2a89ff6eff5ffdeb74eb57b3dc1c64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37fb91bd4a88c5dae9c152eda4cedf20be7270b3a567581e51e510f791b4c44cae23c53a42c502a1342f8f89ff13b67a3a035780689b3e28caf20a4a56e2e64e
|
7
|
+
data.tar.gz: b65c453e756f540f774b5cc32e6d9ef9b9c402852fbb3528432c1f2ada50a89ef154e648552a36d0bb2204144cd5855ecd8b42519f75f89f573d4880c75c8f89
|
@@ -24,110 +24,196 @@
|
|
24
24
|
}
|
25
25
|
})(function($) {
|
26
26
|
"use strict";
|
27
|
-
var
|
27
|
+
var EditableCaret, InputCaret, Mirror, Utils, methods, pluginName;
|
28
28
|
|
29
29
|
pluginName = 'caret';
|
30
|
-
|
31
|
-
function
|
30
|
+
EditableCaret = (function() {
|
31
|
+
function EditableCaret($inputor) {
|
32
32
|
this.$inputor = $inputor;
|
33
33
|
this.domInputor = this.$inputor[0];
|
34
34
|
}
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
EditableCaret.prototype.setPos = function(pos) {
|
37
|
+
return this.domInputor;
|
38
|
+
};
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
/*
|
43
|
-
#assume we select "HATE" in the inputor such as textarea -> { }.
|
44
|
-
* start end-point.
|
45
|
-
* /
|
46
|
-
* < I really [HATE] IE > between the brackets is the selection range.
|
47
|
-
* \
|
48
|
-
* end end-point.
|
49
|
-
*/
|
40
|
+
EditableCaret.prototype.getIEPosition = function() {
|
41
|
+
return $.noop();
|
42
|
+
};
|
50
43
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
44
|
+
EditableCaret.prototype.getPosition = function() {
|
45
|
+
return $.noop();
|
46
|
+
};
|
47
|
+
|
48
|
+
EditableCaret.prototype.getOldIEPos = function() {
|
49
|
+
var preCaretTextRange, textRange;
|
50
|
+
|
51
|
+
textRange = document.selection.createRange();
|
52
|
+
preCaretTextRange = document.body.createTextRange();
|
53
|
+
preCaretTextRange.moveToElementText(this.domInputor);
|
54
|
+
preCaretTextRange.setEndPoint("EndToEnd", textRange);
|
55
|
+
return preCaretTextRange.text.length;
|
56
|
+
};
|
57
|
+
|
58
|
+
EditableCaret.prototype.getPos = function() {
|
59
|
+
var clonedRange, pos, range;
|
60
|
+
|
61
|
+
if (range = this.range()) {
|
62
|
+
clonedRange = range.cloneRange();
|
63
|
+
clonedRange.selectNodeContents(this.domInputor);
|
64
|
+
clonedRange.setEnd(range.endContainer, range.endOffset);
|
65
|
+
pos = clonedRange.toString().length;
|
66
|
+
clonedRange.detach();
|
67
|
+
return pos;
|
68
|
+
} else if (document.selection) {
|
69
|
+
return this.getOldIEPos();
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
EditableCaret.prototype.getOldIEOffset = function() {
|
74
|
+
var range, rect;
|
75
|
+
|
76
|
+
range = document.selection.createRange().duplicate();
|
77
|
+
range.moveStart("character", -1);
|
78
|
+
rect = range.getBoundingClientRect();
|
79
|
+
return {
|
80
|
+
height: rect.bottom - rect.top,
|
81
|
+
left: rect.left,
|
82
|
+
top: rect.top
|
83
|
+
};
|
84
|
+
};
|
85
|
+
|
86
|
+
EditableCaret.prototype.getOffset = function(pos) {
|
87
|
+
var clonedRange, offset, range, rect;
|
88
|
+
|
89
|
+
offset = null;
|
90
|
+
if (window.getSelection && (range = this.range())) {
|
91
|
+
if (range.endOffset - 1 < 0) {
|
92
|
+
return null;
|
93
|
+
}
|
94
|
+
clonedRange = range.cloneRange();
|
95
|
+
clonedRange.setStart(range.endContainer, range.endOffset - 1);
|
96
|
+
clonedRange.setEnd(range.endContainer, range.endOffset);
|
97
|
+
rect = clonedRange.getBoundingClientRect();
|
98
|
+
offset = {
|
99
|
+
height: rect.height,
|
100
|
+
left: rect.left + rect.width,
|
101
|
+
top: rect.top
|
102
|
+
};
|
103
|
+
clonedRange.detach();
|
104
|
+
offset;
|
105
|
+
} else if (document.selection) {
|
106
|
+
this.getOldIEOffset();
|
107
|
+
}
|
108
|
+
return Utils.adjustOffset(offset, this.$inputor);
|
109
|
+
};
|
110
|
+
|
111
|
+
EditableCaret.prototype.range = function() {
|
112
|
+
var sel;
|
113
|
+
|
114
|
+
if (!window.getSelection) {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
sel = window.getSelection();
|
118
|
+
if (sel.rangeCount > 0) {
|
119
|
+
return sel.getRangeAt(0);
|
120
|
+
} else {
|
121
|
+
return null;
|
122
|
+
}
|
123
|
+
};
|
124
|
+
|
125
|
+
return EditableCaret;
|
126
|
+
|
127
|
+
})();
|
128
|
+
InputCaret = (function() {
|
129
|
+
function InputCaret($inputor) {
|
130
|
+
this.$inputor = $inputor;
|
131
|
+
this.domInputor = this.$inputor[0];
|
132
|
+
}
|
133
|
+
|
134
|
+
InputCaret.prototype.getIEPos = function() {
|
135
|
+
var endRange, inputor, len, normalizedValue, pos, range, textInputRange;
|
136
|
+
|
137
|
+
inputor = this.domInputor;
|
138
|
+
range = document.selection.createRange();
|
139
|
+
pos = 0;
|
140
|
+
if (range && range.parentElement() === inputor) {
|
141
|
+
normalizedValue = inputor.value.replace(/\r\n/g, "\n");
|
142
|
+
len = normalizedValue.length;
|
143
|
+
textInputRange = inputor.createTextRange();
|
144
|
+
textInputRange.moveToBookmark(range.getBookmark());
|
145
|
+
endRange = inputor.createTextRange();
|
146
|
+
endRange.collapse(false);
|
147
|
+
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
148
|
+
pos = len;
|
149
|
+
} else {
|
150
|
+
pos = -textInputRange.moveStart("character", -len);
|
109
151
|
}
|
152
|
+
}
|
153
|
+
return pos;
|
154
|
+
};
|
155
|
+
|
156
|
+
InputCaret.prototype.getPos = function() {
|
157
|
+
if (document.selection) {
|
158
|
+
return this.getIEPos();
|
110
159
|
} else {
|
111
|
-
|
160
|
+
return this.domInputor.selectionStart;
|
112
161
|
}
|
113
|
-
return start;
|
114
162
|
};
|
115
163
|
|
116
|
-
|
164
|
+
InputCaret.prototype.setPos = function(pos) {
|
117
165
|
var inputor, range;
|
118
166
|
|
119
167
|
inputor = this.domInputor;
|
120
168
|
if (document.selection) {
|
121
169
|
range = inputor.createTextRange();
|
122
170
|
range.move("character", pos);
|
123
|
-
|
171
|
+
range.select();
|
172
|
+
} else if (inputor.setSelectionRange) {
|
173
|
+
inputor.setSelectionRange(pos, pos);
|
174
|
+
}
|
175
|
+
return inputor;
|
176
|
+
};
|
177
|
+
|
178
|
+
InputCaret.prototype.getIEOffset = function(pos) {
|
179
|
+
var h, range, textRange, x, y;
|
180
|
+
|
181
|
+
textRange = this.domInputor.createTextRange();
|
182
|
+
if (pos) {
|
183
|
+
textRange.move('character', pos);
|
184
|
+
} else {
|
185
|
+
range = document.selection.createRange();
|
186
|
+
textRange.moveToBookmark(range.getBookmark());
|
187
|
+
}
|
188
|
+
x = textRange.boundingLeft;
|
189
|
+
y = textRange.boundingTop;
|
190
|
+
h = textRange.boundingHeight;
|
191
|
+
return {
|
192
|
+
left: x,
|
193
|
+
top: y,
|
194
|
+
height: h
|
195
|
+
};
|
196
|
+
};
|
197
|
+
|
198
|
+
InputCaret.prototype.getOffset = function(pos) {
|
199
|
+
var $inputor, offset, position;
|
200
|
+
|
201
|
+
$inputor = this.$inputor;
|
202
|
+
if (document.selection) {
|
203
|
+
return Utils.adjustOffset(this.getIEOffset(pos), $inputor);
|
124
204
|
} else {
|
125
|
-
|
205
|
+
offset = $inputor.offset();
|
206
|
+
position = this.getPosition(pos);
|
207
|
+
return offset = {
|
208
|
+
left: offset.left + position.left,
|
209
|
+
top: offset.top + position.top,
|
210
|
+
height: position.height
|
211
|
+
};
|
126
212
|
}
|
127
213
|
};
|
128
214
|
|
129
|
-
|
130
|
-
var $inputor, at_rect, format,
|
215
|
+
InputCaret.prototype.getPosition = function(pos) {
|
216
|
+
var $inputor, at_rect, format, html, mirror, start_range;
|
131
217
|
|
132
218
|
$inputor = this.$inputor;
|
133
219
|
format = function(value) {
|
@@ -140,34 +226,10 @@
|
|
140
226
|
html = "<span>" + format(start_range) + "</span>";
|
141
227
|
html += "<span id='caret'>|</span>";
|
142
228
|
mirror = new Mirror($inputor);
|
143
|
-
at_rect = mirror.create(html).rect();
|
144
|
-
x = at_rect.left - $inputor.scrollLeft();
|
145
|
-
y = at_rect.top - $inputor.scrollTop();
|
146
|
-
h = at_rect.height;
|
147
|
-
return {
|
148
|
-
left: x,
|
149
|
-
top: y,
|
150
|
-
height: h
|
151
|
-
};
|
152
|
-
};
|
153
|
-
|
154
|
-
Caret.prototype.getOffset = function(pos) {
|
155
|
-
var $inputor, h, offset, position, x, y;
|
156
|
-
|
157
|
-
$inputor = this.$inputor;
|
158
|
-
offset = $inputor.offset();
|
159
|
-
position = this.getPosition(pos);
|
160
|
-
x = offset.left + position.left;
|
161
|
-
y = offset.top + position.top;
|
162
|
-
h = position.height;
|
163
|
-
return {
|
164
|
-
left: x,
|
165
|
-
top: y,
|
166
|
-
height: h
|
167
|
-
};
|
229
|
+
return at_rect = mirror.create(html).rect();
|
168
230
|
};
|
169
231
|
|
170
|
-
|
232
|
+
InputCaret.prototype.getIEPosition = function(pos) {
|
171
233
|
var h, inputorOffset, offset, x, y;
|
172
234
|
|
173
235
|
offset = this.getIEOffset(pos);
|
@@ -182,27 +244,7 @@
|
|
182
244
|
};
|
183
245
|
};
|
184
246
|
|
185
|
-
|
186
|
-
var h, range, textRange, x, y;
|
187
|
-
|
188
|
-
textRange = this.domInputor.createTextRange();
|
189
|
-
if (pos) {
|
190
|
-
textRange.move('character', pos);
|
191
|
-
} else {
|
192
|
-
range = document.selection.createRange();
|
193
|
-
textRange.moveToBookmark(range.getBookmark());
|
194
|
-
}
|
195
|
-
x = textRange.boundingLeft + this.$inputor.scrollLeft();
|
196
|
-
y = textRange.boundingTop + $(window).scrollTop() + this.$inputor.scrollTop();
|
197
|
-
h = textRange.boundingHeight;
|
198
|
-
return {
|
199
|
-
left: x,
|
200
|
-
top: y,
|
201
|
-
height: h
|
202
|
-
};
|
203
|
-
};
|
204
|
-
|
205
|
-
return Caret;
|
247
|
+
return InputCaret;
|
206
248
|
|
207
249
|
})();
|
208
250
|
Mirror = (function() {
|
@@ -254,6 +296,19 @@
|
|
254
296
|
return Mirror;
|
255
297
|
|
256
298
|
})();
|
299
|
+
Utils = {
|
300
|
+
adjustOffset: function(offset, $inputor) {
|
301
|
+
if (!offset) {
|
302
|
+
return;
|
303
|
+
}
|
304
|
+
offset.top += $(window).scrollTop() + $inputor.scrollTop();
|
305
|
+
offset.left += +$(window).scrollLeft() + $inputor.scrollLeft();
|
306
|
+
return offset;
|
307
|
+
},
|
308
|
+
contentEditable: function($inputor) {
|
309
|
+
return !!($inputor[0].contentEditable && $inputor[0].contentEditable === 'true');
|
310
|
+
}
|
311
|
+
};
|
257
312
|
methods = {
|
258
313
|
pos: function(pos) {
|
259
314
|
if (pos) {
|
@@ -270,23 +325,23 @@
|
|
270
325
|
}
|
271
326
|
},
|
272
327
|
offset: function(pos) {
|
273
|
-
|
274
|
-
return this.getIEOffset(pos);
|
275
|
-
} else {
|
276
|
-
return this.getOffset(pos);
|
277
|
-
}
|
328
|
+
return this.getOffset(pos);
|
278
329
|
}
|
279
330
|
};
|
280
|
-
|
331
|
+
$.fn.caret = function(method) {
|
281
332
|
var caret;
|
282
333
|
|
283
|
-
caret = new
|
334
|
+
caret = Utils.contentEditable(this) ? new EditableCaret(this) : new InputCaret(this);
|
284
335
|
if (methods[method]) {
|
285
336
|
return methods[method].apply(caret, Array.prototype.slice.call(arguments, 1));
|
286
337
|
} else {
|
287
338
|
return $.error("Method " + method + " does not exist on jQuery.caret");
|
288
339
|
}
|
289
340
|
};
|
341
|
+
$.fn.caret.EditableCaret = EditableCaret;
|
342
|
+
$.fn.caret.InputCaret = InputCaret;
|
343
|
+
$.fn.caret.Utils = Utils;
|
344
|
+
return $.fn.caret.apis = methods;
|
290
345
|
});
|
291
346
|
|
292
347
|
}).call(this);
|
@@ -311,7 +366,7 @@
|
|
311
366
|
return factory(window.jQuery);
|
312
367
|
}
|
313
368
|
})(function($) {
|
314
|
-
var $CONTAINER, Api, App, Controller, DEFAULT_CALLBACKS,
|
369
|
+
var $CONTAINER, Api, App, Atwho, Controller, DEFAULT_CALLBACKS, KEY_CODE, Model, View;
|
315
370
|
App = (function() {
|
316
371
|
|
317
372
|
function App(inputor) {
|
@@ -321,12 +376,12 @@
|
|
321
376
|
this.listen();
|
322
377
|
}
|
323
378
|
|
324
|
-
App.prototype.controller = function(
|
325
|
-
return this.controllers[
|
379
|
+
App.prototype.controller = function(at) {
|
380
|
+
return this.controllers[at || this.current_flag];
|
326
381
|
};
|
327
382
|
|
328
|
-
App.prototype.set_context_for = function(
|
329
|
-
this.current_flag =
|
383
|
+
App.prototype.set_context_for = function(at) {
|
384
|
+
this.current_flag = at;
|
330
385
|
return this;
|
331
386
|
};
|
332
387
|
|
@@ -361,7 +416,7 @@
|
|
361
416
|
var _this = this;
|
362
417
|
return $.map(this.controllers, function(c) {
|
363
418
|
if (c.look_up()) {
|
364
|
-
return _this.set_context_for(c.
|
419
|
+
return _this.set_context_for(c.at);
|
365
420
|
}
|
366
421
|
});
|
367
422
|
};
|
@@ -428,14 +483,16 @@
|
|
428
483
|
return _uuid += 1;
|
429
484
|
};
|
430
485
|
|
431
|
-
function Controller(app,
|
486
|
+
function Controller(app, at) {
|
432
487
|
this.app = app;
|
433
|
-
this.
|
488
|
+
this.at = at;
|
434
489
|
this.$inputor = this.app.$inputor;
|
435
490
|
this.id = this.$inputor[0].id || uuid();
|
436
491
|
this.setting = null;
|
437
492
|
this.query = null;
|
438
493
|
this.pos = 0;
|
494
|
+
this.cur_rect = null;
|
495
|
+
this.range = null;
|
439
496
|
$CONTAINER.append(this.$el = $("<div id='atwho-ground-" + this.id + "'></div>"));
|
440
497
|
this.model = new Model(this);
|
441
498
|
this.view = new View(this);
|
@@ -443,6 +500,7 @@
|
|
443
500
|
|
444
501
|
Controller.prototype.init = function(setting) {
|
445
502
|
this.setting = $.extend({}, this.setting || $.fn.atwho["default"], setting);
|
503
|
+
this.view.init();
|
446
504
|
return this.model.reload(this.setting.data);
|
447
505
|
};
|
448
506
|
|
@@ -468,20 +526,28 @@
|
|
468
526
|
return this.get_opt("callbacks")[func_name] || DEFAULT_CALLBACKS[func_name];
|
469
527
|
};
|
470
528
|
|
471
|
-
Controller.prototype.get_opt = function(
|
529
|
+
Controller.prototype.get_opt = function(at, default_value) {
|
472
530
|
try {
|
473
|
-
return this.setting[
|
531
|
+
return this.setting[at];
|
474
532
|
} catch (e) {
|
475
533
|
return null;
|
476
534
|
}
|
477
535
|
};
|
478
536
|
|
537
|
+
Controller.prototype.content = function() {
|
538
|
+
if (this.$inputor.is('textarea, input')) {
|
539
|
+
return this.$inputor.val();
|
540
|
+
} else {
|
541
|
+
return this.$inputor.text();
|
542
|
+
}
|
543
|
+
};
|
544
|
+
|
479
545
|
Controller.prototype.catch_query = function() {
|
480
546
|
var caret_pos, content, end, query, start, subtext;
|
481
|
-
content = this
|
547
|
+
content = this.content();
|
482
548
|
caret_pos = this.$inputor.caret('pos');
|
483
549
|
subtext = content.slice(0, caret_pos);
|
484
|
-
query = this.callbacks("matcher").call(this, this.
|
550
|
+
query = this.callbacks("matcher").call(this, this.at, subtext, this.get_opt('start_with_space'));
|
485
551
|
if (typeof query === "string" && query.length <= this.get_opt('max_len', 20)) {
|
486
552
|
start = caret_pos - query.length;
|
487
553
|
end = start + query.length;
|
@@ -491,7 +557,7 @@
|
|
491
557
|
'head_pos': start,
|
492
558
|
'end_pos': end
|
493
559
|
};
|
494
|
-
this.trigger("matched", [this.
|
560
|
+
this.trigger("matched", [this.at, query.text]);
|
495
561
|
} else {
|
496
562
|
this.view.hide();
|
497
563
|
}
|
@@ -500,7 +566,12 @@
|
|
500
566
|
|
501
567
|
Controller.prototype.rect = function() {
|
502
568
|
var c, scale_bottom;
|
503
|
-
c = this.$inputor.caret('offset', this.pos - 1)
|
569
|
+
if (!(c = this.$inputor.caret('offset', this.pos - 1))) {
|
570
|
+
return;
|
571
|
+
}
|
572
|
+
if (this.$inputor.attr('contentEditable') === 'true') {
|
573
|
+
c = (this.cur_rect || (this.cur_rect = c)) || c;
|
574
|
+
}
|
504
575
|
scale_bottom = document.selection ? 0 : 2;
|
505
576
|
return {
|
506
577
|
left: c.left,
|
@@ -509,15 +580,78 @@
|
|
509
580
|
};
|
510
581
|
};
|
511
582
|
|
512
|
-
Controller.prototype.
|
513
|
-
|
583
|
+
Controller.prototype.reset_rect = function() {
|
584
|
+
if (this.$inputor.attr('contentEditable') === 'true') {
|
585
|
+
return this.cur_rect = null;
|
586
|
+
}
|
587
|
+
};
|
588
|
+
|
589
|
+
Controller.prototype.mark_range = function() {
|
590
|
+
return this.range = this.get_range() || this.get_ie_range();
|
591
|
+
};
|
592
|
+
|
593
|
+
Controller.prototype.clear_range = function() {
|
594
|
+
return this.range = null;
|
595
|
+
};
|
596
|
+
|
597
|
+
Controller.prototype.get_range = function() {
|
598
|
+
return this.range || (window.getSelection ? window.getSelection().getRangeAt(0) : void 0);
|
599
|
+
};
|
600
|
+
|
601
|
+
Controller.prototype.get_ie_range = function() {
|
602
|
+
return this.range || (document.selection ? document.selection.createRange() : void 0);
|
603
|
+
};
|
604
|
+
|
605
|
+
Controller.prototype.insert_content_for = function($li) {
|
606
|
+
var data, data_value, tpl;
|
607
|
+
data_value = $li.data('value');
|
608
|
+
tpl = this.get_opt('insert_tpl');
|
609
|
+
if (this.$inputor.is('textarea, input') || !tpl) {
|
610
|
+
return data_value;
|
611
|
+
}
|
612
|
+
data = $.extend({}, $li.data('item-data'), {
|
613
|
+
'atwho-data-value': data_value,
|
614
|
+
'atwho-at': this.at
|
615
|
+
});
|
616
|
+
return this.callbacks("tpl_eval").call(this, tpl, data);
|
617
|
+
};
|
618
|
+
|
619
|
+
Controller.prototype.insert = function(content, $li) {
|
620
|
+
var $inputor, $insert_node, class_name, content_node, insert_node, pos, range, sel, source, start_str, text;
|
514
621
|
$inputor = this.$inputor;
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
622
|
+
if ($inputor.attr('contentEditable') === 'true') {
|
623
|
+
class_name = "atwho-view-flag atwho-view-flag-" + (this.get_opt('alias') || this.at);
|
624
|
+
content_node = "" + content + "<span contenteditable='false'> <span>";
|
625
|
+
insert_node = "<span contenteditable='false' class='" + class_name + "'>" + content_node + "</span>";
|
626
|
+
$insert_node = $(insert_node).data('atwho-data-item', $li.data('item-data'));
|
627
|
+
if (document.selection) {
|
628
|
+
$insert_node = $("<span contenteditable='true'></span>").html($insert_node);
|
629
|
+
}
|
630
|
+
}
|
631
|
+
if ($inputor.is('textarea, input')) {
|
632
|
+
content = '' + content;
|
633
|
+
source = $inputor.val();
|
634
|
+
start_str = source.slice(0, Math.max(this.query.head_pos - this.at.length, 0));
|
635
|
+
text = "" + start_str + content + " " + (source.slice(this.query['end_pos'] || 0));
|
636
|
+
$inputor.val(text);
|
637
|
+
$inputor.caret('pos', start_str.length + content.length + 1);
|
638
|
+
} else if (range = this.get_range()) {
|
639
|
+
pos = range.startOffset - (this.query.end_pos - this.query.head_pos) - this.at.length;
|
640
|
+
range.setStart(range.endContainer, Math.max(pos, 0));
|
641
|
+
range.setEnd(range.endContainer, range.endOffset);
|
642
|
+
range.deleteContents();
|
643
|
+
range.insertNode($insert_node[0]);
|
644
|
+
range.collapse(false);
|
645
|
+
sel = window.getSelection();
|
646
|
+
sel.removeAllRanges();
|
647
|
+
sel.addRange(range);
|
648
|
+
} else if (range = this.get_ie_range()) {
|
649
|
+
range.moveStart('character', this.query.end_pos - this.query.head_pos - this.at.length);
|
650
|
+
range.pasteHTML($insert_node[0]);
|
651
|
+
range.collapse(false);
|
652
|
+
range.select();
|
653
|
+
}
|
654
|
+
$inputor.focus();
|
521
655
|
return $inputor.change();
|
522
656
|
};
|
523
657
|
|
@@ -554,7 +688,7 @@
|
|
554
688
|
|
555
689
|
function Model(context) {
|
556
690
|
this.context = context;
|
557
|
-
this.
|
691
|
+
this.at = this.context.at;
|
558
692
|
}
|
559
693
|
|
560
694
|
Model.prototype.saved = function() {
|
@@ -572,11 +706,11 @@
|
|
572
706
|
};
|
573
707
|
|
574
708
|
Model.prototype.fetch = function() {
|
575
|
-
return _storage[this.
|
709
|
+
return _storage[this.at] || [];
|
576
710
|
};
|
577
711
|
|
578
712
|
Model.prototype.save = function(data) {
|
579
|
-
return _storage[this.
|
713
|
+
return _storage[this.at] = this.context.callbacks("before_save").call(this.context, data || []);
|
580
714
|
};
|
581
715
|
|
582
716
|
Model.prototype.load = function(data) {
|
@@ -609,25 +743,36 @@
|
|
609
743
|
|
610
744
|
function View(context) {
|
611
745
|
this.context = context;
|
612
|
-
this
|
613
|
-
this.id = this.context.get_opt("alias") || ("at-view-" + (this.key.charCodeAt(0)));
|
614
|
-
this.$el = $("<div id='" + this.id + "' class='atwho-view'><ul id='" + this.id + "-ul' class='atwho-view-url'></ul></div>");
|
746
|
+
this.$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>");
|
615
747
|
this.timeout_id = null;
|
616
748
|
this.context.$el.append(this.$el);
|
617
749
|
this.bind_event();
|
618
750
|
}
|
619
751
|
|
752
|
+
View.prototype.init = function() {
|
753
|
+
var id;
|
754
|
+
id = this.context.get_opt("alias") || this.context.at.charCodeAt(0);
|
755
|
+
return this.$el.attr({
|
756
|
+
'id': "at-view-" + id
|
757
|
+
});
|
758
|
+
};
|
759
|
+
|
620
760
|
View.prototype.bind_event = function() {
|
621
761
|
var $menu,
|
622
762
|
_this = this;
|
623
763
|
$menu = this.$el.find('ul');
|
624
|
-
|
764
|
+
$menu.on('mouseenter.atwho-view', 'li', function(e) {
|
625
765
|
$menu.find('.cur').removeClass('cur');
|
626
766
|
return $(e.currentTarget).addClass('cur');
|
627
767
|
}).on('click', function(e) {
|
628
768
|
_this.choose();
|
629
769
|
return e.preventDefault();
|
630
770
|
});
|
771
|
+
return this.$el.on('mouseenter.atwho-view', 'ul', function(e) {
|
772
|
+
return _this.context.mark_range();
|
773
|
+
}).on('mouseleave.atwho-view', 'ul', function(e) {
|
774
|
+
return _this.context.clear_range();
|
775
|
+
});
|
631
776
|
};
|
632
777
|
|
633
778
|
View.prototype.visible = function() {
|
@@ -635,16 +780,16 @@
|
|
635
780
|
};
|
636
781
|
|
637
782
|
View.prototype.choose = function() {
|
638
|
-
var $li;
|
783
|
+
var $li, content;
|
639
784
|
$li = this.$el.find(".cur");
|
640
|
-
this.context.
|
785
|
+
content = this.context.insert_content_for($li);
|
786
|
+
this.context.insert(this.context.callbacks("before_insert").call(this.context, content, $li), $li);
|
641
787
|
this.context.trigger("inserted", [$li]);
|
642
788
|
return this.hide();
|
643
789
|
};
|
644
790
|
|
645
|
-
View.prototype.reposition = function() {
|
646
|
-
var offset
|
647
|
-
rect = this.context.rect();
|
791
|
+
View.prototype.reposition = function(rect) {
|
792
|
+
var offset;
|
648
793
|
if (rect.bottom + this.$el.height() - $(window).scrollTop() > $(window).height()) {
|
649
794
|
rect.bottom = rect.top - this.$el.height();
|
650
795
|
}
|
@@ -677,16 +822,20 @@
|
|
677
822
|
};
|
678
823
|
|
679
824
|
View.prototype.show = function() {
|
825
|
+
var rect;
|
680
826
|
if (!this.visible()) {
|
681
827
|
this.$el.show();
|
682
828
|
}
|
683
|
-
|
829
|
+
if (rect = this.context.rect()) {
|
830
|
+
return this.reposition(rect);
|
831
|
+
}
|
684
832
|
};
|
685
833
|
|
686
834
|
View.prototype.hide = function(time) {
|
687
835
|
var callback,
|
688
836
|
_this = this;
|
689
837
|
if (isNaN(time && this.visible())) {
|
838
|
+
this.context.reset_rect();
|
690
839
|
return this.$el.hide();
|
691
840
|
} else {
|
692
841
|
callback = function() {
|
@@ -705,12 +854,15 @@
|
|
705
854
|
}
|
706
855
|
this.$el.find('ul').empty();
|
707
856
|
$ul = this.$el.find('ul');
|
708
|
-
tpl = this.context.get_opt('tpl'
|
857
|
+
tpl = this.context.get_opt('tpl');
|
709
858
|
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
710
859
|
item = list[_i];
|
860
|
+
item = $.extend({}, item, {
|
861
|
+
'atwho-at': this.context.at
|
862
|
+
});
|
711
863
|
li = this.context.callbacks("tpl_eval").call(this.context, tpl, item);
|
712
864
|
$li = $(this.context.callbacks("highlighter").call(this.context, li, this.context.query.text));
|
713
|
-
$li.data("
|
865
|
+
$li.data("item-data", item);
|
714
866
|
$ul.append($li);
|
715
867
|
}
|
716
868
|
this.show();
|
@@ -812,54 +964,87 @@
|
|
812
964
|
return value;
|
813
965
|
}
|
814
966
|
};
|
815
|
-
DEFAULT_TPL = "<li data-value='${name}'>${name}</li>";
|
816
967
|
Api = {
|
817
|
-
|
818
|
-
var $this, app;
|
819
|
-
app = ($this = $(this)).data("atwho");
|
820
|
-
if (!app) {
|
821
|
-
$this.data('atwho', (app = new App(this)));
|
822
|
-
}
|
823
|
-
return app.reg(options.at, options);
|
824
|
-
},
|
825
|
-
load: function(key, data) {
|
968
|
+
load: function(at, data) {
|
826
969
|
var c;
|
827
|
-
if (c = this.controller(
|
970
|
+
if (c = this.controller(at)) {
|
828
971
|
return c.model.load(data);
|
829
972
|
}
|
830
973
|
},
|
974
|
+
getInsertedItemsWithIDs: function(at) {
|
975
|
+
var c, ids, items;
|
976
|
+
if (!(c = this.controller(at))) {
|
977
|
+
return [null, null];
|
978
|
+
}
|
979
|
+
if (at) {
|
980
|
+
at = "-" + (c.get_opt('alias') || c.at);
|
981
|
+
}
|
982
|
+
ids = [];
|
983
|
+
items = $.map(this.$inputor.find("span.atwho-view-flag" + (at || "")), function(item) {
|
984
|
+
var data;
|
985
|
+
data = $(item).data('atwho-data-item');
|
986
|
+
if (ids.indexOf(data.id) > -1) {
|
987
|
+
return;
|
988
|
+
}
|
989
|
+
if (data.id) {
|
990
|
+
ids.push = data.id;
|
991
|
+
}
|
992
|
+
return data;
|
993
|
+
});
|
994
|
+
return [ids, items];
|
995
|
+
},
|
996
|
+
getInsertedItems: function(at) {
|
997
|
+
return Api.getInsertedItemsWithIDs.apply(this, [at])[1];
|
998
|
+
},
|
999
|
+
getInsertedIDs: function(at) {
|
1000
|
+
return Api.getInsertedItemsWithIDs.apply(this, [at])[0];
|
1001
|
+
},
|
831
1002
|
run: function() {
|
832
1003
|
return this.dispatch();
|
833
1004
|
}
|
834
1005
|
};
|
1006
|
+
Atwho = {
|
1007
|
+
init: function(options) {
|
1008
|
+
var $this, app;
|
1009
|
+
app = ($this = $(this)).data("atwho");
|
1010
|
+
if (!app) {
|
1011
|
+
$this.data('atwho', (app = new App(this)));
|
1012
|
+
}
|
1013
|
+
app.reg(options.at, options);
|
1014
|
+
return this;
|
1015
|
+
}
|
1016
|
+
};
|
835
1017
|
$CONTAINER = $("<div id='atwho-container'></div>");
|
836
1018
|
$.fn.atwho = function(method) {
|
837
|
-
var _args;
|
1019
|
+
var result, _args;
|
838
1020
|
_args = arguments;
|
839
1021
|
$('body').append($CONTAINER);
|
840
|
-
|
1022
|
+
result = null;
|
1023
|
+
this.filter('textarea, input, [contenteditable=true]').each(function() {
|
841
1024
|
var app;
|
842
1025
|
if (typeof method === 'object' || !method) {
|
843
|
-
return
|
1026
|
+
return Atwho.init.apply(this, _args);
|
844
1027
|
} else if (Api[method]) {
|
845
1028
|
if (app = $(this).data('atwho')) {
|
846
|
-
return Api[method].apply(app, Array.prototype.slice.call(_args, 1));
|
1029
|
+
return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1));
|
847
1030
|
}
|
848
1031
|
} else {
|
849
1032
|
return $.error("Method " + method + " does not exist on jQuery.caret");
|
850
1033
|
}
|
851
1034
|
});
|
1035
|
+
return result || this;
|
852
1036
|
};
|
853
1037
|
return $.fn.atwho["default"] = {
|
854
1038
|
at: void 0,
|
855
1039
|
alias: void 0,
|
856
1040
|
data: null,
|
857
|
-
tpl:
|
1041
|
+
tpl: "<li data-value='${atwho-at}${name}'>${name}</li>",
|
1042
|
+
insert_tpl: "<span>${atwho-data-value}</span>",
|
858
1043
|
callbacks: DEFAULT_CALLBACKS,
|
859
1044
|
search_key: "name",
|
1045
|
+
start_with_space: true,
|
860
1046
|
limit: 5,
|
861
1047
|
max_len: 20,
|
862
|
-
start_with_space: true,
|
863
1048
|
display_timeout: 300
|
864
1049
|
};
|
865
1050
|
});
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jquery-atwho-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ichord
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -87,4 +87,3 @@ summary: 'jquery plugin: @mentions'
|
|
87
87
|
test_files:
|
88
88
|
- spec/generators/install_generator_spec.rb
|
89
89
|
- spec/spec_helper.rb
|
90
|
-
has_rdoc:
|