jquery-atwho-rails 0.2.3 → 0.2.4
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.
- data/README.md +2 -2
- data/changelog.md +11 -0
- data/lib/assets/javascripts/jquery.atwho.js +271 -224
- data/lib/jquery-atwho-rails/version.rb +1 -1
- metadata +15 -13
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
### Notice
|
2
2
|
updated to `v0.2.0`.
|
3
3
|
The stable and old one would live in branch `stable-v0.1.x` branch taged `v0.1.7`
|
4
|
-
More details in [At.js](https://github.com/ichord/At.js) project.
|
4
|
+
**More details** in [At.js](https://github.com/ichord/At.js) project.
|
5
5
|
|
6
6
|
### Usage
|
7
7
|
---
|
@@ -9,7 +9,7 @@ bind your textarea
|
|
9
9
|
|
10
10
|
```javascript
|
11
11
|
data = ['tom','john'];
|
12
|
-
$('textarea').
|
12
|
+
$('textarea').atwho("@",{'data':data});
|
13
13
|
```
|
14
14
|
|
15
15
|
that's it, check it out!
|
data/changelog.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
|
2
|
+
#### 2013.4.15 - v0.2.4
|
3
|
+
|
4
|
+
* `data` setting will be used to load data either local or remote. If it's String as URL it will preload data from remote by launch a ajax request (every times At.js call `reg` to update settings)
|
5
|
+
|
6
|
+
* remove default `remote_filter` from callbacks list.
|
7
|
+
* add `get_data` and `save_data` function to contoller. They are used to get and save whole data for At.js
|
8
|
+
* `save_data` will invoke `data_refactor` everytime
|
9
|
+
|
10
|
+
* will filter local data which is set in `settings` first and if it get nothing then call `remote_filter` if it's exists in callbacks list that is set by user.
|
11
|
+
|
1
12
|
* 2013.3.12 - v0.2.3 fix some bugs
|
2
13
|
* 2013.3.1 - v0.2.2 fix some bugs.
|
3
14
|
* 2013.1.24 updated to v0.2.0.
|
@@ -17,55 +17,7 @@
|
|
17
17
|
return factory(window.jQuery);
|
18
18
|
}
|
19
19
|
})(function($) {
|
20
|
-
var Controller, DEFAULT_CALLBACKS, DEFAULT_TPL, KEY_CODE,
|
21
|
-
Mirror = (function() {
|
22
|
-
|
23
|
-
Mirror.prototype.css_attr = ["overflowY", "height", "width", "paddingTop", "paddingLeft", "paddingRight", "paddingBottom", "marginTop", "marginLeft", "marginRight", "marginBottom", "fontFamily", "borderStyle", "borderWidth", "wordWrap", "fontSize", "lineHeight", "overflowX", "text-align"];
|
24
|
-
|
25
|
-
function Mirror($inputor) {
|
26
|
-
this.$inputor = $inputor;
|
27
|
-
}
|
28
|
-
|
29
|
-
Mirror.prototype.copy_inputor_css = function() {
|
30
|
-
var css,
|
31
|
-
_this = this;
|
32
|
-
css = {
|
33
|
-
position: 'absolute',
|
34
|
-
left: -9999,
|
35
|
-
top: 0,
|
36
|
-
zIndex: -20000,
|
37
|
-
'white-space': 'pre-wrap'
|
38
|
-
};
|
39
|
-
$.each(this.css_attr, function(i, p) {
|
40
|
-
return css[p] = _this.$inputor.css(p);
|
41
|
-
});
|
42
|
-
return css;
|
43
|
-
};
|
44
|
-
|
45
|
-
Mirror.prototype.create = function(html) {
|
46
|
-
this.$mirror = $('<div></div>');
|
47
|
-
this.$mirror.css(this.copy_inputor_css());
|
48
|
-
this.$mirror.html(html);
|
49
|
-
this.$inputor.after(this.$mirror);
|
50
|
-
return this;
|
51
|
-
};
|
52
|
-
|
53
|
-
Mirror.prototype.get_flag_rect = function() {
|
54
|
-
var $flag, pos, rect;
|
55
|
-
$flag = this.$mirror.find("span#flag");
|
56
|
-
pos = $flag.position();
|
57
|
-
rect = {
|
58
|
-
left: pos.left,
|
59
|
-
top: pos.top,
|
60
|
-
bottom: $flag.height() + pos.top
|
61
|
-
};
|
62
|
-
this.$mirror.remove();
|
63
|
-
return rect;
|
64
|
-
};
|
65
|
-
|
66
|
-
return Mirror;
|
67
|
-
|
68
|
-
})();
|
20
|
+
var Controller, DEFAULT_CALLBACKS, DEFAULT_TPL, KEY_CODE, View;
|
69
21
|
KEY_CODE = {
|
70
22
|
DOWN: 40,
|
71
23
|
UP: 38,
|
@@ -107,14 +59,7 @@
|
|
107
59
|
}
|
108
60
|
});
|
109
61
|
},
|
110
|
-
remote_filter:
|
111
|
-
return $.ajax(url, {
|
112
|
-
data: params,
|
113
|
-
success: function(data) {
|
114
|
-
return render_view(data);
|
115
|
-
}
|
116
|
-
});
|
117
|
-
},
|
62
|
+
remote_filter: null,
|
118
63
|
sorter: function(query, items, search_key) {
|
119
64
|
var item, results, text, _i, _len;
|
120
65
|
if (!query) {
|
@@ -130,12 +75,22 @@
|
|
130
75
|
for (_i = 0, _len = items.length; _i < _len; _i++) {
|
131
76
|
item = items[_i];
|
132
77
|
text = item[search_key];
|
133
|
-
item.
|
78
|
+
item.atwho_order = text.toLowerCase().indexOf(query);
|
134
79
|
results.push(item);
|
135
80
|
}
|
136
|
-
|
137
|
-
return a.
|
81
|
+
results.sort(function(a, b) {
|
82
|
+
return a.atwho_order - b.atwho_order;
|
138
83
|
});
|
84
|
+
return results = (function() {
|
85
|
+
var _j, _len1, _results;
|
86
|
+
_results = [];
|
87
|
+
for (_j = 0, _len1 = results.length; _j < _len1; _j++) {
|
88
|
+
item = results[_j];
|
89
|
+
delete item["atwho_order"];
|
90
|
+
_results.push(item);
|
91
|
+
}
|
92
|
+
return _results;
|
93
|
+
})();
|
139
94
|
},
|
140
95
|
tpl_eval: function(tpl, map) {
|
141
96
|
var el;
|
@@ -165,14 +120,12 @@
|
|
165
120
|
|
166
121
|
function Controller(inputor) {
|
167
122
|
this.settings = {};
|
168
|
-
this.common_settings = {};
|
169
123
|
this.pos = 0;
|
170
124
|
this.flags = null;
|
171
125
|
this.current_flag = null;
|
172
126
|
this.query = null;
|
127
|
+
this._data_sets = {};
|
173
128
|
this.$inputor = $(inputor);
|
174
|
-
this.mirror = new Mirror(this.$inputor);
|
175
|
-
this.common_settings = $.extend({}, $.fn.atwho["default"]);
|
176
129
|
this.view = new View(this, this.$el);
|
177
130
|
this.listen();
|
178
131
|
}
|
@@ -192,10 +145,14 @@
|
|
192
145
|
|
193
146
|
Controller.prototype.reg = function(flag, settings) {
|
194
147
|
var current_settings, data;
|
195
|
-
|
196
|
-
current_settings =
|
197
|
-
data = current_settings
|
198
|
-
|
148
|
+
this.current_flag = flag;
|
149
|
+
current_settings = this.settings[flag] ? this.settings[flag] = $.extend({}, this.settings[flag], settings) : this.settings[flag] = $.extend({}, $.fn.atwho["default"], settings);
|
150
|
+
data = current_settings.data;
|
151
|
+
if (typeof data === "string") {
|
152
|
+
this.load_remote_data(data);
|
153
|
+
} else {
|
154
|
+
this.save_data(data);
|
155
|
+
}
|
199
156
|
return this;
|
200
157
|
};
|
201
158
|
|
@@ -205,78 +162,44 @@
|
|
205
162
|
return this.$inputor.trigger("" + name + ".atwho", data);
|
206
163
|
};
|
207
164
|
|
208
|
-
Controller.prototype.
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
165
|
+
Controller.prototype.get_data = function(key) {
|
166
|
+
return this._data_sets[key || (key = this.current_flag)];
|
167
|
+
};
|
168
|
+
|
169
|
+
Controller.prototype.save_data = function(data, key) {
|
170
|
+
return this._data_sets[key || (key = this.current_flag)] = this.callbacks("data_refactor").call(this, data);
|
214
171
|
};
|
215
172
|
|
216
173
|
Controller.prototype.callbacks = function(func_name) {
|
217
174
|
var func;
|
218
|
-
|
219
|
-
|
175
|
+
func = this.get_opt("callbacks")[func_name];
|
176
|
+
if (!func) {
|
177
|
+
func = DEFAULT_CALLBACKS[func_name];
|
220
178
|
}
|
221
179
|
return func;
|
222
180
|
};
|
223
181
|
|
224
182
|
Controller.prototype.get_opt = function(key, default_value) {
|
225
|
-
var value;
|
226
183
|
try {
|
227
|
-
|
228
|
-
value = this.settings[this.current_flag][key];
|
229
|
-
}
|
230
|
-
if (value === void 0) {
|
231
|
-
value = this.common_settings[key];
|
232
|
-
}
|
233
|
-
return value = value === void 0 ? default_value : value;
|
184
|
+
return this.settings[this.current_flag][key];
|
234
185
|
} catch (e) {
|
235
|
-
return
|
186
|
+
return null;
|
236
187
|
}
|
237
188
|
};
|
238
189
|
|
239
190
|
Controller.prototype.rect = function() {
|
240
|
-
var
|
241
|
-
|
191
|
+
var c, scale, scale_bottom;
|
192
|
+
c = this.$inputor.caret('offset', this.pos - 1);
|
242
193
|
if (document.selection) {
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
return {
|
248
|
-
top: y - 2,
|
249
|
-
left: x - 2,
|
250
|
-
bottom: bottom - 2
|
251
|
-
};
|
194
|
+
scale_bottom = scale = -2;
|
195
|
+
} else {
|
196
|
+
scale = 0;
|
197
|
+
scale_bottom = 2;
|
252
198
|
}
|
253
|
-
format = function(value) {
|
254
|
-
return value.replace(/</g, '<').replace(/>/g, '>').replace(/`/g, '`').replace(/"/g, '"').replace(/\r\n|\r|\n/g, "<br />");
|
255
|
-
};
|
256
|
-
/* 克隆完inputor后将原来的文本内容根据
|
257
|
-
@的位置进行分块,以获取@块在inputor(输入框)里的position
|
258
|
-
*/
|
259
|
-
|
260
|
-
start_range = $inputor.val().slice(0, this.pos - 1);
|
261
|
-
html = "<span>" + format(start_range) + "</span>";
|
262
|
-
html += "<span id='flag'>?</span>";
|
263
|
-
/*
|
264
|
-
将inputor的 offset(相对于document)
|
265
|
-
和@在inputor里的position相加
|
266
|
-
就得到了@相对于document的offset.
|
267
|
-
当然,还要加上行高和滚动条的偏移量.
|
268
|
-
*/
|
269
|
-
|
270
|
-
offset = $inputor.offset();
|
271
|
-
at_rect = this.mirror.create(html).get_flag_rect();
|
272
|
-
x = offset.left + at_rect.left - $inputor.scrollLeft();
|
273
|
-
y = offset.top - $inputor.scrollTop();
|
274
|
-
bottom = y + at_rect.bottom;
|
275
|
-
y += at_rect.top;
|
276
199
|
return {
|
277
|
-
|
278
|
-
|
279
|
-
bottom:
|
200
|
+
left: c.left + scale,
|
201
|
+
top: c.top + scale,
|
202
|
+
bottom: c.top + c.height + scale_bottom
|
280
203
|
};
|
281
204
|
};
|
282
205
|
|
@@ -284,11 +207,7 @@
|
|
284
207
|
var caret_pos, content, end, query, start, subtext,
|
285
208
|
_this = this;
|
286
209
|
content = this.$inputor.val();
|
287
|
-
caret_pos = this.$inputor.
|
288
|
-
/* 向在插入符前的的文本进行正则匹配
|
289
|
-
* 考虑会有多个 @ 的存在, 匹配离插入符最近的一个
|
290
|
-
*/
|
291
|
-
|
210
|
+
caret_pos = this.$inputor.caret('pos');
|
292
211
|
subtext = content.slice(0, caret_pos);
|
293
212
|
query = null;
|
294
213
|
$.each(this.settings, function(flag, settings) {
|
@@ -317,12 +236,13 @@
|
|
317
236
|
Controller.prototype.replace_str = function(str) {
|
318
237
|
var $inputor, flag_len, source, start_str, text;
|
319
238
|
$inputor = this.$inputor;
|
239
|
+
str = '' + str;
|
320
240
|
source = $inputor.val();
|
321
241
|
flag_len = this.get_opt("display_flag") ? 0 : this.current_flag.length;
|
322
242
|
start_str = source.slice(0, (this.query['head_pos'] || 0) - flag_len);
|
323
243
|
text = "" + start_str + str + " " + (source.slice(this.query['end_pos'] || 0));
|
324
244
|
$inputor.val(text);
|
325
|
-
$inputor.
|
245
|
+
$inputor.caret('pos', start_str.length + str.length + 1);
|
326
246
|
return $inputor.change();
|
327
247
|
};
|
328
248
|
|
@@ -377,22 +297,24 @@
|
|
377
297
|
var search_key;
|
378
298
|
search_key = this.get_opt("search_key");
|
379
299
|
data = this.callbacks("sorter").call(this, this.query.text, data, search_key);
|
380
|
-
data = data.
|
381
|
-
this.data(data);
|
300
|
+
data = data.slice(0, this.get_opt('limit'));
|
382
301
|
return this.view.render(data);
|
383
302
|
};
|
384
303
|
|
385
|
-
Controller.prototype.remote_call = function(
|
386
|
-
var
|
387
|
-
params = {
|
388
|
-
q: query.text,
|
389
|
-
limit: this.get_opt("limit")
|
390
|
-
};
|
304
|
+
Controller.prototype.remote_call = function(query) {
|
305
|
+
var _callback;
|
391
306
|
_callback = function(data) {
|
392
307
|
return this.render_view(data);
|
393
308
|
};
|
394
309
|
_callback = $.proxy(_callback, this);
|
395
|
-
return this.callbacks('remote_filter').call(this,
|
310
|
+
return this.callbacks('remote_filter').call(this, query.text, _callback);
|
311
|
+
};
|
312
|
+
|
313
|
+
Controller.prototype.load_remote_data = function(url) {
|
314
|
+
var _this = this;
|
315
|
+
return $.get(url).done(function(data) {
|
316
|
+
return _this.save_data(data);
|
317
|
+
});
|
396
318
|
};
|
397
319
|
|
398
320
|
Controller.prototype.look_up = function() {
|
@@ -401,12 +323,13 @@
|
|
401
323
|
if (!query) {
|
402
324
|
return false;
|
403
325
|
}
|
404
|
-
data = this.
|
326
|
+
data = this.get_data();
|
405
327
|
search_key = this.get_opt("search_key");
|
406
|
-
|
407
|
-
|
408
|
-
} else if ((data = this.callbacks('filter').call(this, query.text, data, search_key))) {
|
328
|
+
data = this.callbacks('filter').call(this, query.text, data || [], search_key);
|
329
|
+
if (data && data.length > 0) {
|
409
330
|
this.render_view(data);
|
331
|
+
} else if (this.callbacks('remote_filter')) {
|
332
|
+
this.remote_call(query);
|
410
333
|
} else {
|
411
334
|
this.view.hide();
|
412
335
|
}
|
@@ -420,7 +343,7 @@
|
|
420
343
|
|
421
344
|
function View(controller) {
|
422
345
|
this.controller = controller;
|
423
|
-
this.id = this.controller.get_opt("view_id"
|
346
|
+
this.id = this.controller.get_opt("view_id") || "at-view";
|
424
347
|
this.timeout_id = null;
|
425
348
|
this.$el = $("#" + this.id);
|
426
349
|
this.create_view();
|
@@ -565,7 +488,6 @@
|
|
565
488
|
};
|
566
489
|
$.fn.atwho.Controller = Controller;
|
567
490
|
$.fn.atwho.View = View;
|
568
|
-
$.fn.atwho.Mirror = Mirror;
|
569
491
|
return $.fn.atwho["default"] = {
|
570
492
|
data: null,
|
571
493
|
search_key: "name",
|
@@ -599,109 +521,234 @@
|
|
599
521
|
(function() {
|
600
522
|
|
601
523
|
(function(factory) {
|
602
|
-
if (typeof
|
603
|
-
return
|
604
|
-
} else if (typeof define === 'function' && define.amd) {
|
605
|
-
return define(['jquery']);
|
524
|
+
if (typeof define === 'function' && define.amd) {
|
525
|
+
return define(['jquery'], factory);
|
606
526
|
} else {
|
607
527
|
return factory(window.jQuery);
|
608
528
|
}
|
609
529
|
})(function($) {
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
#assume we select "HATE" in the inputor such as textarea -> { }.
|
616
|
-
* start end-point.
|
617
|
-
* /
|
618
|
-
* < I really [HATE] IE > between the brackets is the selection range.
|
619
|
-
* \
|
620
|
-
* end end-point.
|
621
|
-
*/
|
622
|
-
|
623
|
-
range = document.selection.createRange();
|
624
|
-
pos = 0;
|
625
|
-
if (range && range.parentElement() === inputor) {
|
626
|
-
normalizedValue = inputor.value.replace(/\r\n/g, "\n");
|
627
|
-
/* SOMETIME !!!
|
628
|
-
"/r/n" is counted as two char.
|
629
|
-
one line is two, two will be four. balalala.
|
630
|
-
so we have to using the normalized one's length.;
|
631
|
-
*/
|
530
|
+
"use strict";
|
531
|
+
|
532
|
+
var Caret, Mirror, methods, pluginName;
|
533
|
+
pluginName = 'caret';
|
534
|
+
Caret = (function() {
|
632
535
|
|
633
|
-
|
536
|
+
function Caret($inputor) {
|
537
|
+
this.$inputor = $inputor;
|
538
|
+
this.domInputor = this.$inputor[0];
|
539
|
+
}
|
540
|
+
|
541
|
+
Caret.prototype.getPos = function() {
|
542
|
+
var end, endRange, inputor, len, normalizedValue, pos, range, start, textInputRange;
|
543
|
+
inputor = this.domInputor;
|
544
|
+
inputor.focus();
|
545
|
+
if (document.selection) {
|
634
546
|
/*
|
635
|
-
|
636
|
-
|
547
|
+
#assume we select "HATE" in the inputor such as textarea -> { }.
|
548
|
+
* start end-point.
|
549
|
+
* /
|
550
|
+
* < I really [HATE] IE > between the brackets is the selection range.
|
551
|
+
* \
|
552
|
+
* end end-point.
|
637
553
|
*/
|
638
554
|
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
555
|
+
range = document.selection.createRange();
|
556
|
+
pos = 0;
|
557
|
+
if (range && range.parentElement() === inputor) {
|
558
|
+
normalizedValue = inputor.value.replace(/\r\n/g, "\n");
|
559
|
+
/* SOMETIME !!!
|
560
|
+
"/r/n" is counted as two char.
|
561
|
+
one line is two, two will be four. balalala.
|
562
|
+
so we have to using the normalized one's length.;
|
563
|
+
*/
|
647
564
|
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
565
|
+
len = normalizedValue.length;
|
566
|
+
/*
|
567
|
+
<[ I really HATE IE ]>:
|
568
|
+
the whole content in the inputor will be the textInputRange.
|
569
|
+
*/
|
653
570
|
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
571
|
+
textInputRange = inputor.createTextRange();
|
572
|
+
/* _here must be the position of bookmark.
|
573
|
+
/
|
574
|
+
<[ I really [HATE] IE ]>
|
575
|
+
[---------->[ ] : this is what moveToBookmark do.
|
576
|
+
< I really [[HATE] IE ]> : here is result.
|
577
|
+
\ two brackets in should be in line.
|
578
|
+
*/
|
579
|
+
|
580
|
+
textInputRange.moveToBookmark(range.getBookmark());
|
581
|
+
endRange = inputor.createTextRange();
|
582
|
+
/* [--------------------->[] : if set false all end-point goto end.
|
583
|
+
< I really [[HATE] IE []]>
|
584
|
+
*/
|
664
585
|
|
665
|
-
|
666
|
-
start = end = len;
|
667
|
-
} else {
|
586
|
+
endRange.collapse(false);
|
668
587
|
/*
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
I reall[y [HATE] IE ]>
|
588
|
+
___VS____
|
589
|
+
/ \
|
590
|
+
< I really [[HATE] IE []]>
|
591
|
+
\_endRange end-point.
|
674
592
|
|
675
|
-
|
593
|
+
" > -1" mean the start end-point will be the same or right to the end end-point
|
594
|
+
* simplelly, all in the end.
|
676
595
|
*/
|
677
596
|
|
678
|
-
|
679
|
-
|
597
|
+
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
598
|
+
start = end = len;
|
599
|
+
} else {
|
600
|
+
/*
|
601
|
+
I really |HATE] IE ]>
|
602
|
+
<-|
|
603
|
+
I really[ [HATE] IE ]>
|
604
|
+
<-[
|
605
|
+
I reall[y [HATE] IE ]>
|
606
|
+
|
607
|
+
will return how many unit have moved.
|
608
|
+
*/
|
609
|
+
|
610
|
+
start = -textInputRange.moveStart("character", -len);
|
611
|
+
end = -textInputRange.moveEnd("character", -len);
|
612
|
+
}
|
680
613
|
}
|
614
|
+
} else {
|
615
|
+
start = inputor.selectionStart;
|
681
616
|
}
|
682
|
-
|
683
|
-
|
617
|
+
return start;
|
618
|
+
};
|
619
|
+
|
620
|
+
Caret.prototype.setPos = function(pos) {
|
621
|
+
var inputor, range;
|
622
|
+
inputor = this.domInputor;
|
623
|
+
if (document.selection) {
|
624
|
+
range = inputor.createTextRange();
|
625
|
+
range.move("character", pos);
|
626
|
+
return range.select();
|
627
|
+
} else {
|
628
|
+
return inputor.setSelectionRange(pos, pos);
|
629
|
+
}
|
630
|
+
};
|
631
|
+
|
632
|
+
Caret.prototype.getPosition = function(pos) {
|
633
|
+
var $inputor, at_rect, format, h, html, mirror, start_range, x, y;
|
634
|
+
$inputor = this.$inputor;
|
635
|
+
format = function(value) {
|
636
|
+
return value.replace(/</g, '<').replace(/>/g, '>').replace(/`/g, '`').replace(/"/g, '"').replace(/\r\n|\r|\n/g, "<br />");
|
637
|
+
};
|
638
|
+
pos = pos || this.getPos();
|
639
|
+
start_range = $inputor.val().slice(0, pos);
|
640
|
+
html = "<span>" + format(start_range) + "</span>";
|
641
|
+
html += "<span id='caret'>|</span>";
|
642
|
+
mirror = new Mirror($inputor);
|
643
|
+
at_rect = mirror.create(html).rect();
|
644
|
+
x = at_rect.left - $inputor.scrollLeft();
|
645
|
+
y = at_rect.top - $inputor.scrollTop();
|
646
|
+
h = at_rect.height;
|
647
|
+
return {
|
648
|
+
left: x,
|
649
|
+
top: y,
|
650
|
+
height: h
|
651
|
+
};
|
652
|
+
};
|
653
|
+
|
654
|
+
Caret.prototype.getOffset = function(pos) {
|
655
|
+
var $inputor, h, offset, position, range, x, y;
|
656
|
+
$inputor = this.$inputor;
|
657
|
+
if (document.selection) {
|
658
|
+
range = this.domInputor.createRange();
|
659
|
+
if (pos) {
|
660
|
+
range.move('character', pos);
|
661
|
+
}
|
662
|
+
x = range.boundingLeft + $inputor.scrollLeft();
|
663
|
+
y = range.boundingTop + $(window).scrollTop() + $inputor.scrollTop();
|
664
|
+
h = range.boundingHeight;
|
665
|
+
} else {
|
666
|
+
offset = $inputor.offset();
|
667
|
+
position = this.getPosition(pos);
|
668
|
+
x = offset.left + position.left;
|
669
|
+
y = offset.top + position.top;
|
670
|
+
h = position.height;
|
671
|
+
}
|
672
|
+
return {
|
673
|
+
left: x,
|
674
|
+
top: y,
|
675
|
+
height: h
|
676
|
+
};
|
677
|
+
};
|
678
|
+
|
679
|
+
return Caret;
|
680
|
+
|
681
|
+
})();
|
682
|
+
Mirror = (function() {
|
683
|
+
|
684
|
+
Mirror.prototype.css_attr = ["overflowY", "height", "width", "paddingTop", "paddingLeft", "paddingRight", "paddingBottom", "marginTop", "marginLeft", "marginRight", "marginBottom", "fontFamily", "borderStyle", "borderWidth", "wordWrap", "fontSize", "lineHeight", "overflowX", "text-align"];
|
685
|
+
|
686
|
+
function Mirror($inputor) {
|
687
|
+
this.$inputor = $inputor;
|
684
688
|
}
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
689
|
+
|
690
|
+
Mirror.prototype.mirrorCss = function() {
|
691
|
+
var css,
|
692
|
+
_this = this;
|
693
|
+
css = {
|
694
|
+
position: 'absolute',
|
695
|
+
left: -9999,
|
696
|
+
top: 0,
|
697
|
+
zIndex: -20000,
|
698
|
+
'white-space': 'pre-wrap'
|
699
|
+
};
|
700
|
+
$.each(this.css_attr, function(i, p) {
|
701
|
+
return css[p] = _this.$inputor.css(p);
|
702
|
+
});
|
703
|
+
return css;
|
704
|
+
};
|
705
|
+
|
706
|
+
Mirror.prototype.create = function(html) {
|
707
|
+
this.$mirror = $('<div></div>');
|
708
|
+
this.$mirror.css(this.mirrorCss());
|
709
|
+
this.$mirror.html(html);
|
710
|
+
this.$inputor.after(this.$mirror);
|
711
|
+
return this;
|
712
|
+
};
|
713
|
+
|
714
|
+
Mirror.prototype.rect = function() {
|
715
|
+
var $flag, pos, rect;
|
716
|
+
$flag = this.$mirror.find("#caret");
|
717
|
+
pos = $flag.position();
|
718
|
+
rect = {
|
719
|
+
left: pos.left,
|
720
|
+
top: pos.top,
|
721
|
+
height: $flag.height()
|
722
|
+
};
|
723
|
+
this.$mirror.remove();
|
724
|
+
return rect;
|
725
|
+
};
|
726
|
+
|
727
|
+
return Mirror;
|
728
|
+
|
729
|
+
})();
|
730
|
+
methods = {
|
731
|
+
pos: function(pos) {
|
732
|
+
if (pos) {
|
733
|
+
return this.setPos(pos);
|
734
|
+
} else {
|
735
|
+
return this.getPos();
|
736
|
+
}
|
737
|
+
},
|
738
|
+
position: function(pos) {
|
739
|
+
return this.getPosition(pos);
|
740
|
+
},
|
741
|
+
offset: function(pos) {
|
742
|
+
return this.getOffset(pos);
|
695
743
|
}
|
696
744
|
};
|
697
|
-
return $.fn.
|
698
|
-
var
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
return setCaretPos(inputor, pos);
|
745
|
+
return $.fn.caret = function(method) {
|
746
|
+
var caret;
|
747
|
+
caret = new Caret(this);
|
748
|
+
if (methods[method]) {
|
749
|
+
return methods[method].apply(caret, Array.prototype.slice.call(arguments, 1));
|
703
750
|
} else {
|
704
|
-
return
|
751
|
+
return $.error("Method " + method + " does not exist on jQuery.caret");
|
705
752
|
}
|
706
753
|
};
|
707
754
|
});
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jquery-atwho-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,14 +9,14 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '0'
|
38
38
|
type: :development
|
@@ -40,10 +40,12 @@ dependencies:
|
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
-
description:
|
46
|
+
description: |-
|
47
|
+
This is a jQuery plugin
|
48
|
+
that implement Github-like mentions.
|
47
49
|
email:
|
48
50
|
- chord.luo@gmail.com
|
49
51
|
executables: []
|
@@ -72,27 +74,27 @@ require_paths:
|
|
72
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
73
75
|
none: false
|
74
76
|
requirements:
|
75
|
-
- -
|
77
|
+
- - '>='
|
76
78
|
- !ruby/object:Gem::Version
|
77
79
|
version: '0'
|
78
80
|
segments:
|
79
81
|
- 0
|
80
|
-
hash:
|
82
|
+
hash: -3109051973216094172
|
81
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
84
|
none: false
|
83
85
|
requirements:
|
84
|
-
- -
|
86
|
+
- - '>='
|
85
87
|
- !ruby/object:Gem::Version
|
86
88
|
version: '0'
|
87
89
|
segments:
|
88
90
|
- 0
|
89
|
-
hash:
|
91
|
+
hash: -3109051973216094172
|
90
92
|
requirements: []
|
91
93
|
rubyforge_project: jquery-atwho-rails
|
92
|
-
rubygems_version: 1.8.
|
94
|
+
rubygems_version: 1.8.25
|
93
95
|
signing_key:
|
94
96
|
specification_version: 3
|
95
|
-
summary:
|
97
|
+
summary: 'jquery plugin: @mentions'
|
96
98
|
test_files:
|
97
99
|
- spec/generators/install_generator_spec.rb
|
98
100
|
- spec/spec_helper.rb
|