jquery-atwho-rails 0.3.3 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|