typeahead-rails 0.10.1 → 0.10.5
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/README.md +56 -4
- data/lib/typeahead/rails/version.rb +2 -2
- data/typeahead-rails.gemspec +3 -3
- data/vendor/assets/javascripts/typeahead.js +428 -304
- data/vendor/assets/javascripts/typeahead.min.js +3 -3
- data/vendor/assets/stylesheets/typeahead-rails.css +49 -0
- metadata +15 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fe33c4ed40fca145701a4553f63a2dedb05261b
|
4
|
+
data.tar.gz: eae13ee831d46ab9fc2ff4168bc8084a5572f77c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d49a8259d15787497292011f381f7468cc33fbf2c5b741663fc8f4a8ffbed8e3f32c2c51c10db8f91f84c75030ea802ba6f717bdfced98bacdf18c2426c02ef
|
7
|
+
data.tar.gz: 7a4223a7a0146177e173371c494611cf89baadaf999690138365915265b36fac2acdc38d625e5a934f4223b0f73f144af8bcbf54943293a4bd822b5b917b4a24
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# Twitter typeahead for Rails 3
|
2
2
|
|
3
|
-
Provides an easy-to-use Rails 3.1 asset for [typeahead.js](http://twitter.github.io/typeahead.js/)
|
3
|
+
Provides an easy-to-use Rails 3.1 or higher asset for [typeahead.js](http://twitter.github.io/typeahead.js/)
|
4
|
+
This gem includes the standard and minified versions of the assets.
|
4
5
|
|
5
6
|
## Installation
|
6
7
|
|
@@ -16,11 +17,62 @@ Or install it yourself as:
|
|
16
17
|
|
17
18
|
$ gem install typeahead-rails
|
18
19
|
|
19
|
-
|
20
|
+
|
21
|
+
## Configuration
|
22
|
+
|
23
|
+
### Javascript
|
20
24
|
|
21
25
|
Add the following to your app/assets/javascripts/application.js:
|
22
26
|
|
23
|
-
|
27
|
+
Standard version
|
28
|
+
```js
|
29
|
+
//= require typeahead
|
30
|
+
```
|
31
|
+
|
32
|
+
Minified version :
|
33
|
+
```js
|
34
|
+
//= require typeahead.min
|
35
|
+
```
|
36
|
+
|
37
|
+
### Css
|
38
|
+
|
39
|
+
You can use a css example via the asset pipeline (app/assets/stylesheets/application.css) :
|
40
|
+
```css
|
41
|
+
*= require typeahead-rails
|
42
|
+
```
|
43
|
+
|
44
|
+
## Usage
|
45
|
+
|
46
|
+
```js
|
47
|
+
|
48
|
+
// instantiate the bloodhound suggestion engine
|
49
|
+
var numbers = new Bloodhound({
|
50
|
+
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('num'),
|
51
|
+
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
52
|
+
local: [
|
53
|
+
{ num: 'one' },
|
54
|
+
{ num: 'two' },
|
55
|
+
{ num: 'three' },
|
56
|
+
{ num: 'four' },
|
57
|
+
{ num: 'five' },
|
58
|
+
{ num: 'six' },
|
59
|
+
{ num: 'seven' },
|
60
|
+
{ num: 'eight' },
|
61
|
+
{ num: 'nine' },
|
62
|
+
{ num: 'ten' }
|
63
|
+
]
|
64
|
+
});
|
65
|
+
|
66
|
+
// initialize the bloodhound suggestion engine
|
67
|
+
numbers.initialize();
|
68
|
+
|
69
|
+
// instantiate the typeahead UI
|
70
|
+
$('.example-numbers .typeahead').typeahead(null, {
|
71
|
+
displayKey: 'num',
|
72
|
+
source: numbers.ttAdapter()
|
73
|
+
});
|
74
|
+
```
|
75
|
+
|
24
76
|
|
25
77
|
## Contributing
|
26
78
|
|
data/typeahead-rails.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'typeahead/rails/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'typeahead-rails'
|
8
8
|
spec.version = Typeahead::Rails::VERSION
|
9
|
-
spec.authors = ['Maksim Berjoza']
|
10
|
-
spec.email = ['torbjon@gmail.com']
|
9
|
+
spec.authors = ['Maksim Berjoza', 'Luc Donnet']
|
10
|
+
spec.email = ['torbjon@gmail.com', 'luc.donnet@free.fr']
|
11
11
|
spec.description = 'Twitter Typeahead.js with Rails asset pipeline'
|
12
12
|
spec.homepage = 'https://github.com/torbjon/typeahead-rails'
|
13
13
|
spec.summary = 'Twitter Typeahead.js with Rails asset pipeline'
|
@@ -19,5 +19,5 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = %w(lib vendors)
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
-
spec.add_development_dependency 'rake'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
23
|
end
|
@@ -1,132 +1,171 @@
|
|
1
1
|
/*!
|
2
|
-
* typeahead.js 0.10.
|
2
|
+
* typeahead.js 0.10.5
|
3
3
|
* https://github.com/twitter/typeahead.js
|
4
|
-
* Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT
|
4
|
+
* Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
|
5
5
|
*/
|
6
6
|
|
7
7
|
(function($) {
|
8
|
-
var _ = {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
var result = true;
|
41
|
-
if (!obj) {
|
42
|
-
return result;
|
43
|
-
}
|
44
|
-
$.each(obj, function(key, val) {
|
45
|
-
if (!(result = test.call(null, val, key, obj))) {
|
46
|
-
return false;
|
8
|
+
var _ = function() {
|
9
|
+
"use strict";
|
10
|
+
return {
|
11
|
+
isMsie: function() {
|
12
|
+
return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
|
13
|
+
},
|
14
|
+
isBlankString: function(str) {
|
15
|
+
return !str || /^\s*$/.test(str);
|
16
|
+
},
|
17
|
+
escapeRegExChars: function(str) {
|
18
|
+
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
19
|
+
},
|
20
|
+
isString: function(obj) {
|
21
|
+
return typeof obj === "string";
|
22
|
+
},
|
23
|
+
isNumber: function(obj) {
|
24
|
+
return typeof obj === "number";
|
25
|
+
},
|
26
|
+
isArray: $.isArray,
|
27
|
+
isFunction: $.isFunction,
|
28
|
+
isObject: $.isPlainObject,
|
29
|
+
isUndefined: function(obj) {
|
30
|
+
return typeof obj === "undefined";
|
31
|
+
},
|
32
|
+
toStr: function toStr(s) {
|
33
|
+
return _.isUndefined(s) || s === null ? "" : s + "";
|
34
|
+
},
|
35
|
+
bind: $.proxy,
|
36
|
+
each: function(collection, cb) {
|
37
|
+
$.each(collection, reverseArgs);
|
38
|
+
function reverseArgs(index, value) {
|
39
|
+
return cb(value, index);
|
47
40
|
}
|
48
|
-
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
}
|
56
|
-
$.each(obj, function(key, val) {
|
57
|
-
if (result = test.call(null, val, key, obj)) {
|
58
|
-
return false;
|
41
|
+
},
|
42
|
+
map: $.map,
|
43
|
+
filter: $.grep,
|
44
|
+
every: function(obj, test) {
|
45
|
+
var result = true;
|
46
|
+
if (!obj) {
|
47
|
+
return result;
|
59
48
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
mixin: $.extend,
|
64
|
-
getUniqueId: function() {
|
65
|
-
var counter = 0;
|
66
|
-
return function() {
|
67
|
-
return counter++;
|
68
|
-
};
|
69
|
-
}(),
|
70
|
-
templatify: function templatify(obj) {
|
71
|
-
return $.isFunction(obj) ? obj : template;
|
72
|
-
function template() {
|
73
|
-
return String(obj);
|
74
|
-
}
|
75
|
-
},
|
76
|
-
defer: function(fn) {
|
77
|
-
setTimeout(fn, 0);
|
78
|
-
},
|
79
|
-
debounce: function(func, wait, immediate) {
|
80
|
-
var timeout, result;
|
81
|
-
return function() {
|
82
|
-
var context = this, args = arguments, later, callNow;
|
83
|
-
later = function() {
|
84
|
-
timeout = null;
|
85
|
-
if (!immediate) {
|
86
|
-
result = func.apply(context, args);
|
49
|
+
$.each(obj, function(key, val) {
|
50
|
+
if (!(result = test.call(null, val, key, obj))) {
|
51
|
+
return false;
|
87
52
|
}
|
88
|
-
};
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
53
|
+
});
|
54
|
+
return !!result;
|
55
|
+
},
|
56
|
+
some: function(obj, test) {
|
57
|
+
var result = false;
|
58
|
+
if (!obj) {
|
59
|
+
return result;
|
94
60
|
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
61
|
+
$.each(obj, function(key, val) {
|
62
|
+
if (result = test.call(null, val, key, obj)) {
|
63
|
+
return false;
|
64
|
+
}
|
65
|
+
});
|
66
|
+
return !!result;
|
67
|
+
},
|
68
|
+
mixin: $.extend,
|
69
|
+
getUniqueId: function() {
|
70
|
+
var counter = 0;
|
71
|
+
return function() {
|
72
|
+
return counter++;
|
73
|
+
};
|
74
|
+
}(),
|
75
|
+
templatify: function templatify(obj) {
|
76
|
+
return $.isFunction(obj) ? obj : template;
|
77
|
+
function template() {
|
78
|
+
return String(obj);
|
79
|
+
}
|
80
|
+
},
|
81
|
+
defer: function(fn) {
|
82
|
+
setTimeout(fn, 0);
|
83
|
+
},
|
84
|
+
debounce: function(func, wait, immediate) {
|
85
|
+
var timeout, result;
|
86
|
+
return function() {
|
87
|
+
var context = this, args = arguments, later, callNow;
|
88
|
+
later = function() {
|
89
|
+
timeout = null;
|
90
|
+
if (!immediate) {
|
91
|
+
result = func.apply(context, args);
|
92
|
+
}
|
93
|
+
};
|
94
|
+
callNow = immediate && !timeout;
|
111
95
|
clearTimeout(timeout);
|
96
|
+
timeout = setTimeout(later, wait);
|
97
|
+
if (callNow) {
|
98
|
+
result = func.apply(context, args);
|
99
|
+
}
|
100
|
+
return result;
|
101
|
+
};
|
102
|
+
},
|
103
|
+
throttle: function(func, wait) {
|
104
|
+
var context, args, timeout, result, previous, later;
|
105
|
+
previous = 0;
|
106
|
+
later = function() {
|
107
|
+
previous = new Date();
|
112
108
|
timeout = null;
|
113
|
-
previous = now;
|
114
109
|
result = func.apply(context, args);
|
115
|
-
}
|
116
|
-
|
117
|
-
|
118
|
-
|
110
|
+
};
|
111
|
+
return function() {
|
112
|
+
var now = new Date(), remaining = wait - (now - previous);
|
113
|
+
context = this;
|
114
|
+
args = arguments;
|
115
|
+
if (remaining <= 0) {
|
116
|
+
clearTimeout(timeout);
|
117
|
+
timeout = null;
|
118
|
+
previous = now;
|
119
|
+
result = func.apply(context, args);
|
120
|
+
} else if (!timeout) {
|
121
|
+
timeout = setTimeout(later, remaining);
|
122
|
+
}
|
123
|
+
return result;
|
124
|
+
};
|
125
|
+
},
|
126
|
+
noop: function() {}
|
127
|
+
};
|
128
|
+
}();
|
129
|
+
var VERSION = "0.10.5";
|
130
|
+
var tokenizers = function() {
|
131
|
+
"use strict";
|
132
|
+
return {
|
133
|
+
nonword: nonword,
|
134
|
+
whitespace: whitespace,
|
135
|
+
obj: {
|
136
|
+
nonword: getObjTokenizer(nonword),
|
137
|
+
whitespace: getObjTokenizer(whitespace)
|
138
|
+
}
|
139
|
+
};
|
140
|
+
function whitespace(str) {
|
141
|
+
str = _.toStr(str);
|
142
|
+
return str ? str.split(/\s+/) : [];
|
143
|
+
}
|
144
|
+
function nonword(str) {
|
145
|
+
str = _.toStr(str);
|
146
|
+
return str ? str.split(/\W+/) : [];
|
147
|
+
}
|
148
|
+
function getObjTokenizer(tokenizer) {
|
149
|
+
return function setKey() {
|
150
|
+
var args = [].slice.call(arguments, 0);
|
151
|
+
return function tokenize(o) {
|
152
|
+
var tokens = [];
|
153
|
+
_.each(args, function(k) {
|
154
|
+
tokens = tokens.concat(tokenizer(_.toStr(o[k])));
|
155
|
+
});
|
156
|
+
return tokens;
|
157
|
+
};
|
119
158
|
};
|
120
|
-
}
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
var LruCache = function(root, undefined) {
|
159
|
+
}
|
160
|
+
}();
|
161
|
+
var LruCache = function() {
|
162
|
+
"use strict";
|
125
163
|
function LruCache(maxSize) {
|
126
|
-
this.maxSize = maxSize
|
127
|
-
this.
|
128
|
-
this.
|
129
|
-
|
164
|
+
this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
|
165
|
+
this.reset();
|
166
|
+
if (this.maxSize <= 0) {
|
167
|
+
this.set = this.get = $.noop;
|
168
|
+
}
|
130
169
|
}
|
131
170
|
_.mixin(LruCache.prototype, {
|
132
171
|
set: function set(key, val) {
|
@@ -151,6 +190,11 @@
|
|
151
190
|
this.list.moveToFront(node);
|
152
191
|
return node.val;
|
153
192
|
}
|
193
|
+
},
|
194
|
+
reset: function reset() {
|
195
|
+
this.size = 0;
|
196
|
+
this.hash = {};
|
197
|
+
this.list = new List();
|
154
198
|
}
|
155
199
|
});
|
156
200
|
function List() {
|
@@ -180,8 +224,9 @@
|
|
180
224
|
this.prev = this.next = null;
|
181
225
|
}
|
182
226
|
return LruCache;
|
183
|
-
}(
|
227
|
+
}();
|
184
228
|
var PersistentStorage = function() {
|
229
|
+
"use strict";
|
185
230
|
var ls, methods;
|
186
231
|
try {
|
187
232
|
ls = window.localStorage;
|
@@ -193,7 +238,7 @@
|
|
193
238
|
function PersistentStorage(namespace) {
|
194
239
|
this.prefix = [ "__", namespace, "__" ].join("");
|
195
240
|
this.ttlKey = "__ttl__";
|
196
|
-
this.keyMatcher = new RegExp("^" + this.prefix);
|
241
|
+
this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
|
197
242
|
}
|
198
243
|
if (ls && window.JSON) {
|
199
244
|
methods = {
|
@@ -261,32 +306,42 @@
|
|
261
306
|
}
|
262
307
|
}();
|
263
308
|
var Transport = function() {
|
264
|
-
|
309
|
+
"use strict";
|
310
|
+
var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);
|
265
311
|
function Transport(o) {
|
266
312
|
o = o || {};
|
313
|
+
this.cancelled = false;
|
314
|
+
this.lastUrl = null;
|
267
315
|
this._send = o.transport ? callbackToDeferred(o.transport) : $.ajax;
|
268
316
|
this._get = o.rateLimiter ? o.rateLimiter(this._get) : this._get;
|
317
|
+
this._cache = o.cache === false ? new LruCache(0) : sharedCache;
|
269
318
|
}
|
270
319
|
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
|
271
320
|
maxPendingRequests = num;
|
272
321
|
};
|
273
|
-
Transport.resetCache = function
|
274
|
-
|
322
|
+
Transport.resetCache = function resetCache() {
|
323
|
+
sharedCache.reset();
|
275
324
|
};
|
276
325
|
_.mixin(Transport.prototype, {
|
277
326
|
_get: function(url, o, cb) {
|
278
327
|
var that = this, jqXhr;
|
328
|
+
if (this.cancelled || url !== this.lastUrl) {
|
329
|
+
return;
|
330
|
+
}
|
279
331
|
if (jqXhr = pendingRequests[url]) {
|
280
|
-
jqXhr.done(done);
|
332
|
+
jqXhr.done(done).fail(fail);
|
281
333
|
} else if (pendingRequestsCount < maxPendingRequests) {
|
282
334
|
pendingRequestsCount++;
|
283
|
-
pendingRequests[url] = this._send(url, o).done(done).always(always);
|
335
|
+
pendingRequests[url] = this._send(url, o).done(done).fail(fail).always(always);
|
284
336
|
} else {
|
285
337
|
this.onDeckRequestArgs = [].slice.call(arguments, 0);
|
286
338
|
}
|
287
339
|
function done(resp) {
|
288
|
-
cb && cb(resp);
|
289
|
-
|
340
|
+
cb && cb(null, resp);
|
341
|
+
that._cache.set(url, resp);
|
342
|
+
}
|
343
|
+
function fail() {
|
344
|
+
cb && cb(true);
|
290
345
|
}
|
291
346
|
function always() {
|
292
347
|
pendingRequestsCount--;
|
@@ -298,19 +353,24 @@
|
|
298
353
|
}
|
299
354
|
},
|
300
355
|
get: function(url, o, cb) {
|
301
|
-
var
|
356
|
+
var resp;
|
302
357
|
if (_.isFunction(o)) {
|
303
358
|
cb = o;
|
304
359
|
o = {};
|
305
360
|
}
|
306
|
-
|
361
|
+
this.cancelled = false;
|
362
|
+
this.lastUrl = url;
|
363
|
+
if (resp = this._cache.get(url)) {
|
307
364
|
_.defer(function() {
|
308
|
-
cb && cb(resp);
|
365
|
+
cb && cb(null, resp);
|
309
366
|
});
|
310
367
|
} else {
|
311
368
|
this._get(url, o, cb);
|
312
369
|
}
|
313
370
|
return !!resp;
|
371
|
+
},
|
372
|
+
cancel: function() {
|
373
|
+
this.cancelled = true;
|
314
374
|
}
|
315
375
|
});
|
316
376
|
return Transport;
|
@@ -333,6 +393,7 @@
|
|
333
393
|
}
|
334
394
|
}();
|
335
395
|
var SearchIndex = function() {
|
396
|
+
"use strict";
|
336
397
|
function SearchIndex(o) {
|
337
398
|
o = o || {};
|
338
399
|
if (!o.datumTokenizer || !o.queryTokenizer) {
|
@@ -340,8 +401,7 @@
|
|
340
401
|
}
|
341
402
|
this.datumTokenizer = o.datumTokenizer;
|
342
403
|
this.queryTokenizer = o.queryTokenizer;
|
343
|
-
this.
|
344
|
-
this.trie = newNode();
|
404
|
+
this.reset();
|
345
405
|
}
|
346
406
|
_.mixin(SearchIndex.prototype, {
|
347
407
|
bootstrap: function bootstrap(o) {
|
@@ -356,7 +416,7 @@
|
|
356
416
|
id = that.datums.push(datum) - 1;
|
357
417
|
tokens = normalizeTokens(that.datumTokenizer(datum));
|
358
418
|
_.each(tokens, function(token) {
|
359
|
-
var node, chars, ch
|
419
|
+
var node, chars, ch;
|
360
420
|
node = that.trie;
|
361
421
|
chars = token.split("");
|
362
422
|
while (ch = chars.shift()) {
|
@@ -391,6 +451,10 @@
|
|
391
451
|
return that.datums[id];
|
392
452
|
}) : [];
|
393
453
|
},
|
454
|
+
reset: function reset() {
|
455
|
+
this.datums = [];
|
456
|
+
this.trie = newNode();
|
457
|
+
},
|
394
458
|
serialize: function serialize() {
|
395
459
|
return {
|
396
460
|
datums: this.datums,
|
@@ -416,7 +480,7 @@
|
|
416
480
|
}
|
417
481
|
function unique(array) {
|
418
482
|
var seen = {}, uniques = [];
|
419
|
-
for (var i = 0
|
483
|
+
for (var i = 0, len = array.length; i < len; i++) {
|
420
484
|
if (!seen[array[i]]) {
|
421
485
|
seen[array[i]] = true;
|
422
486
|
uniques.push(array[i]);
|
@@ -428,7 +492,8 @@
|
|
428
492
|
var ai = 0, bi = 0, intersection = [];
|
429
493
|
arrayA = arrayA.sort(compare);
|
430
494
|
arrayB = arrayB.sort(compare);
|
431
|
-
|
495
|
+
var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
|
496
|
+
while (ai < lenArrayA && bi < lenArrayB) {
|
432
497
|
if (arrayA[ai] < arrayB[bi]) {
|
433
498
|
ai++;
|
434
499
|
} else if (arrayA[ai] > arrayB[bi]) {
|
@@ -446,17 +511,14 @@
|
|
446
511
|
}
|
447
512
|
}();
|
448
513
|
var oParser = function() {
|
514
|
+
"use strict";
|
449
515
|
return {
|
450
516
|
local: getLocal,
|
451
517
|
prefetch: getPrefetch,
|
452
518
|
remote: getRemote
|
453
519
|
};
|
454
520
|
function getLocal(o) {
|
455
|
-
|
456
|
-
if (_.isFunction(local)) {
|
457
|
-
local = local.call(null);
|
458
|
-
}
|
459
|
-
return local;
|
521
|
+
return o.local || null;
|
460
522
|
}
|
461
523
|
function getPrefetch(o) {
|
462
524
|
var prefetch, defaults;
|
@@ -483,6 +545,7 @@
|
|
483
545
|
var remote, defaults;
|
484
546
|
defaults = {
|
485
547
|
url: null,
|
548
|
+
cache: true,
|
486
549
|
wildcard: "%QUERY",
|
487
550
|
replace: null,
|
488
551
|
rateLimitBy: "debounce",
|
@@ -516,13 +579,16 @@
|
|
516
579
|
}
|
517
580
|
}
|
518
581
|
}();
|
519
|
-
|
520
|
-
|
582
|
+
(function(root) {
|
583
|
+
"use strict";
|
584
|
+
var old, keys;
|
585
|
+
old = root.Bloodhound;
|
521
586
|
keys = {
|
522
587
|
data: "data",
|
523
588
|
protocol: "protocol",
|
524
589
|
thumbprint: "thumbprint"
|
525
590
|
};
|
591
|
+
root.Bloodhound = Bloodhound;
|
526
592
|
function Bloodhound(o) {
|
527
593
|
if (!o || !o.local && !o.prefetch && !o.remote) {
|
528
594
|
$.error("one of local, prefetch, or remote is required");
|
@@ -540,14 +606,11 @@
|
|
540
606
|
});
|
541
607
|
this.storage = this.cacheKey ? new PersistentStorage(this.cacheKey) : null;
|
542
608
|
}
|
543
|
-
Bloodhound.
|
544
|
-
|
545
|
-
|
546
|
-
},
|
547
|
-
nonword: function nonwordTokenizer(s) {
|
548
|
-
return s.split(/\W+/);
|
549
|
-
}
|
609
|
+
Bloodhound.noConflict = function noConflict() {
|
610
|
+
root.Bloodhound = old;
|
611
|
+
return Bloodhound;
|
550
612
|
};
|
613
|
+
Bloodhound.tokenizers = tokenizers;
|
551
614
|
_.mixin(Bloodhound.prototype, {
|
552
615
|
_loadPrefetch: function loadPrefetch(o) {
|
553
616
|
var that = this, serialized, deferred;
|
@@ -559,23 +622,27 @@
|
|
559
622
|
}
|
560
623
|
return deferred;
|
561
624
|
function handlePrefetchResponse(resp) {
|
562
|
-
|
563
|
-
|
564
|
-
that.add(filtered);
|
625
|
+
that.clear();
|
626
|
+
that.add(o.filter ? o.filter(resp) : resp);
|
565
627
|
that._saveToStorage(that.index.serialize(), o.thumbprint, o.ttl);
|
566
628
|
}
|
567
629
|
},
|
568
630
|
_getFromRemote: function getFromRemote(query, cb) {
|
569
631
|
var that = this, url, uriEncodedQuery;
|
632
|
+
if (!this.transport) {
|
633
|
+
return;
|
634
|
+
}
|
570
635
|
query = query || "";
|
571
636
|
uriEncodedQuery = encodeURIComponent(query);
|
572
637
|
url = this.remote.replace ? this.remote.replace(this.remote.url, query) : this.remote.url.replace(this.remote.wildcard, uriEncodedQuery);
|
573
638
|
return this.transport.get(url, this.remote.ajax, handleRemoteResponse);
|
574
|
-
function handleRemoteResponse(resp) {
|
575
|
-
|
576
|
-
cb(filtered);
|
639
|
+
function handleRemoteResponse(err, resp) {
|
640
|
+
err ? cb([]) : cb(that.remote.filter ? that.remote.filter(resp) : resp);
|
577
641
|
}
|
578
642
|
},
|
643
|
+
_cancelLastRemoteRequest: function cancelLastRemoteRequest() {
|
644
|
+
this.transport && this.transport.cancel();
|
645
|
+
},
|
579
646
|
_saveToStorage: function saveToStorage(data, thumbprint, ttl) {
|
580
647
|
if (this.storage) {
|
581
648
|
this.storage.set(keys.data, data, ttl);
|
@@ -593,30 +660,30 @@
|
|
593
660
|
isExpired = stored.thumbprint !== thumbprint || stored.protocol !== location.protocol;
|
594
661
|
return stored.data && !isExpired ? stored.data : null;
|
595
662
|
},
|
596
|
-
|
597
|
-
var that = this, deferred;
|
663
|
+
_initialize: function initialize() {
|
664
|
+
var that = this, local = this.local, deferred;
|
598
665
|
deferred = this.prefetch ? this._loadPrefetch(this.prefetch) : $.Deferred().resolve();
|
599
|
-
|
666
|
+
local && deferred.done(addLocalToIndex);
|
600
667
|
this.transport = this.remote ? new Transport(this.remote) : null;
|
601
|
-
this.
|
602
|
-
return deferred.promise();
|
603
|
-
};
|
604
|
-
return deferred.promise();
|
668
|
+
return this.initPromise = deferred.promise();
|
605
669
|
function addLocalToIndex() {
|
606
|
-
that.add(
|
670
|
+
that.add(_.isFunction(local) ? local() : local);
|
607
671
|
}
|
608
672
|
},
|
673
|
+
initialize: function initialize(force) {
|
674
|
+
return !this.initPromise || force ? this._initialize() : this.initPromise;
|
675
|
+
},
|
609
676
|
add: function add(data) {
|
610
677
|
this.index.add(data);
|
611
678
|
},
|
612
679
|
get: function get(query, cb) {
|
613
|
-
var that = this, matches, cacheHit = false;
|
680
|
+
var that = this, matches = [], cacheHit = false;
|
614
681
|
matches = this.index.get(query);
|
615
682
|
matches = this.sorter(matches).slice(0, this.limit);
|
616
|
-
|
617
|
-
|
683
|
+
matches.length < this.limit ? cacheHit = this._getFromRemote(query, returnRemoteMatches) : this._cancelLastRemoteRequest();
|
684
|
+
if (!cacheHit) {
|
685
|
+
(matches.length > 0 || !this.transport) && cb && cb(matches);
|
618
686
|
}
|
619
|
-
!cacheHit && cb && cb(matches);
|
620
687
|
function returnRemoteMatches(remoteMatches) {
|
621
688
|
var matchesWithBackfill = matches.slice(0);
|
622
689
|
_.each(remoteMatches, function(remoteMatch) {
|
@@ -630,6 +697,15 @@
|
|
630
697
|
cb && cb(that.sorter(matchesWithBackfill));
|
631
698
|
}
|
632
699
|
},
|
700
|
+
clear: function clear() {
|
701
|
+
this.index.reset();
|
702
|
+
},
|
703
|
+
clearPrefetchCache: function clearPrefetchCache() {
|
704
|
+
this.storage && this.storage.clear();
|
705
|
+
},
|
706
|
+
clearRemoteCache: function clearRemoteCache() {
|
707
|
+
this.transport && Transport.resetCache();
|
708
|
+
},
|
633
709
|
ttAdapter: function ttAdapter() {
|
634
710
|
return _.bind(this.get, this);
|
635
711
|
}
|
@@ -647,72 +723,80 @@
|
|
647
723
|
function ignoreDuplicates() {
|
648
724
|
return false;
|
649
725
|
}
|
726
|
+
})(this);
|
727
|
+
var html = function() {
|
728
|
+
return {
|
729
|
+
wrapper: '<span class="twitter-typeahead"></span>',
|
730
|
+
dropdown: '<span class="tt-dropdown-menu"></span>',
|
731
|
+
dataset: '<div class="tt-dataset-%CLASS%"></div>',
|
732
|
+
suggestions: '<span class="tt-suggestions"></span>',
|
733
|
+
suggestion: '<div class="tt-suggestion"></div>'
|
734
|
+
};
|
650
735
|
}();
|
651
|
-
var
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
736
|
+
var css = function() {
|
737
|
+
"use strict";
|
738
|
+
var css = {
|
739
|
+
wrapper: {
|
740
|
+
position: "relative",
|
741
|
+
display: "inline-block"
|
742
|
+
},
|
743
|
+
hint: {
|
744
|
+
position: "absolute",
|
745
|
+
top: "0",
|
746
|
+
left: "0",
|
747
|
+
borderColor: "transparent",
|
748
|
+
boxShadow: "none",
|
749
|
+
opacity: "1"
|
750
|
+
},
|
751
|
+
input: {
|
752
|
+
position: "relative",
|
753
|
+
verticalAlign: "top",
|
754
|
+
backgroundColor: "transparent"
|
755
|
+
},
|
756
|
+
inputWithNoHint: {
|
757
|
+
position: "relative",
|
758
|
+
verticalAlign: "top"
|
759
|
+
},
|
760
|
+
dropdown: {
|
761
|
+
position: "absolute",
|
762
|
+
top: "100%",
|
763
|
+
left: "0",
|
764
|
+
zIndex: "100",
|
765
|
+
display: "none"
|
766
|
+
},
|
767
|
+
suggestions: {
|
768
|
+
display: "block"
|
769
|
+
},
|
770
|
+
suggestion: {
|
771
|
+
whiteSpace: "nowrap",
|
772
|
+
cursor: "pointer"
|
773
|
+
},
|
774
|
+
suggestionChild: {
|
775
|
+
whiteSpace: "normal"
|
776
|
+
},
|
777
|
+
ltr: {
|
778
|
+
left: "0",
|
779
|
+
right: "auto"
|
780
|
+
},
|
781
|
+
rtl: {
|
782
|
+
left: "auto",
|
783
|
+
right: " 0"
|
784
|
+
}
|
785
|
+
};
|
786
|
+
if (_.isMsie()) {
|
787
|
+
_.mixin(css.input, {
|
788
|
+
backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
|
789
|
+
});
|
703
790
|
}
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
}
|
709
|
-
|
710
|
-
|
711
|
-
_.mixin(css.input, {
|
712
|
-
marginTop: "-1px"
|
713
|
-
});
|
714
|
-
}
|
791
|
+
if (_.isMsie() && _.isMsie() <= 7) {
|
792
|
+
_.mixin(css.input, {
|
793
|
+
marginTop: "-1px"
|
794
|
+
});
|
795
|
+
}
|
796
|
+
return css;
|
797
|
+
}();
|
715
798
|
var EventBus = function() {
|
799
|
+
"use strict";
|
716
800
|
var namespace = "typeahead:";
|
717
801
|
function EventBus(o) {
|
718
802
|
if (!o || !o.el) {
|
@@ -729,6 +813,7 @@
|
|
729
813
|
return EventBus;
|
730
814
|
}();
|
731
815
|
var EventEmitter = function() {
|
816
|
+
"use strict";
|
732
817
|
var splitter = /\s+/, nextTick = getNextTick();
|
733
818
|
return {
|
734
819
|
onSync: onSync,
|
@@ -771,7 +856,7 @@
|
|
771
856
|
return this;
|
772
857
|
}
|
773
858
|
function trigger(types) {
|
774
|
-
var
|
859
|
+
var type, callbacks, args, syncFlush, asyncFlush;
|
775
860
|
if (!this._callbacks) {
|
776
861
|
return this;
|
777
862
|
}
|
@@ -788,14 +873,14 @@
|
|
788
873
|
return flush;
|
789
874
|
function flush() {
|
790
875
|
var cancelled;
|
791
|
-
for (var i = 0; !cancelled && i <
|
876
|
+
for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
|
792
877
|
cancelled = callbacks[i].apply(context, args) === false;
|
793
878
|
}
|
794
879
|
return !cancelled;
|
795
880
|
}
|
796
881
|
}
|
797
882
|
function getNextTick() {
|
798
|
-
var nextTickFn
|
883
|
+
var nextTickFn;
|
799
884
|
if (window.setImmediate) {
|
800
885
|
nextTickFn = function nextTickSetImmediate(fn) {
|
801
886
|
setImmediate(function() {
|
@@ -818,6 +903,7 @@
|
|
818
903
|
}
|
819
904
|
}();
|
820
905
|
var highlight = function(doc) {
|
906
|
+
"use strict";
|
821
907
|
var defaults = {
|
822
908
|
node: null,
|
823
909
|
pattern: null,
|
@@ -836,7 +922,7 @@
|
|
836
922
|
regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
|
837
923
|
traverse(o.node, hightlightTextNode);
|
838
924
|
function hightlightTextNode(textNode) {
|
839
|
-
var match, patternNode;
|
925
|
+
var match, patternNode, wrapperNode;
|
840
926
|
if (match = regex.exec(textNode.data)) {
|
841
927
|
wrapperNode = doc.createElement(o.tagName);
|
842
928
|
o.className && (wrapperNode.className = o.className);
|
@@ -861,7 +947,7 @@
|
|
861
947
|
};
|
862
948
|
function getRegex(patterns, caseSensitive, wordsOnly) {
|
863
949
|
var escapedPatterns = [], regexStr;
|
864
|
-
for (var i = 0
|
950
|
+
for (var i = 0, len = patterns.length; i < len; i++) {
|
865
951
|
escapedPatterns.push(_.escapeRegExChars(patterns[i]));
|
866
952
|
}
|
867
953
|
regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
|
@@ -869,6 +955,7 @@
|
|
869
955
|
}
|
870
956
|
}(window.document);
|
871
957
|
var Input = function() {
|
958
|
+
"use strict";
|
872
959
|
var specialKeyCodeMap;
|
873
960
|
specialKeyCodeMap = {
|
874
961
|
9: "tab",
|
@@ -892,7 +979,7 @@
|
|
892
979
|
this.$hint = $(o.hint);
|
893
980
|
this.$input = $(o.input).on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
|
894
981
|
if (this.$hint.length === 0) {
|
895
|
-
this.
|
982
|
+
this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
|
896
983
|
}
|
897
984
|
if (!_.isMsie()) {
|
898
985
|
this.$input.on("input.tt", onInput);
|
@@ -911,11 +998,11 @@
|
|
911
998
|
return (str || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
|
912
999
|
};
|
913
1000
|
_.mixin(Input.prototype, EventEmitter, {
|
914
|
-
_onBlur: function onBlur(
|
1001
|
+
_onBlur: function onBlur() {
|
915
1002
|
this.resetInputValue();
|
916
1003
|
this.trigger("blurred");
|
917
1004
|
},
|
918
|
-
_onFocus: function onFocus(
|
1005
|
+
_onFocus: function onFocus() {
|
919
1006
|
this.trigger("focused");
|
920
1007
|
},
|
921
1008
|
_onKeydown: function onKeydown($e) {
|
@@ -925,14 +1012,14 @@
|
|
925
1012
|
this.trigger(keyName + "Keyed", $e);
|
926
1013
|
}
|
927
1014
|
},
|
928
|
-
_onInput: function onInput(
|
1015
|
+
_onInput: function onInput() {
|
929
1016
|
this._checkInputValue();
|
930
1017
|
},
|
931
1018
|
_managePreventDefault: function managePreventDefault(keyName, $e) {
|
932
1019
|
var preventDefault, hintValue, inputValue;
|
933
1020
|
switch (keyName) {
|
934
1021
|
case "tab":
|
935
|
-
hintValue = this.
|
1022
|
+
hintValue = this.getHint();
|
936
1023
|
inputValue = this.getInputValue();
|
937
1024
|
preventDefault = hintValue && hintValue !== inputValue && !withModifier($e);
|
938
1025
|
break;
|
@@ -964,8 +1051,9 @@
|
|
964
1051
|
inputValue = this.getInputValue();
|
965
1052
|
areEquivalent = areQueriesEquivalent(inputValue, this.query);
|
966
1053
|
hasDifferentWhitespace = areEquivalent ? this.query.length !== inputValue.length : false;
|
1054
|
+
this.query = inputValue;
|
967
1055
|
if (!areEquivalent) {
|
968
|
-
this.trigger("queryChanged", this.query
|
1056
|
+
this.trigger("queryChanged", this.query);
|
969
1057
|
} else if (hasDifferentWhitespace) {
|
970
1058
|
this.trigger("whitespaceChanged", this.query);
|
971
1059
|
}
|
@@ -987,19 +1075,27 @@
|
|
987
1075
|
},
|
988
1076
|
setInputValue: function setInputValue(value, silent) {
|
989
1077
|
this.$input.val(value);
|
990
|
-
|
1078
|
+
silent ? this.clearHint() : this._checkInputValue();
|
1079
|
+
},
|
1080
|
+
resetInputValue: function resetInputValue() {
|
1081
|
+
this.setInputValue(this.query, true);
|
991
1082
|
},
|
992
|
-
|
1083
|
+
getHint: function getHint() {
|
993
1084
|
return this.$hint.val();
|
994
1085
|
},
|
995
|
-
|
1086
|
+
setHint: function setHint(value) {
|
996
1087
|
this.$hint.val(value);
|
997
1088
|
},
|
998
|
-
resetInputValue: function resetInputValue() {
|
999
|
-
this.$input.val(this.query);
|
1000
|
-
},
|
1001
1089
|
clearHint: function clearHint() {
|
1002
|
-
this
|
1090
|
+
this.setHint("");
|
1091
|
+
},
|
1092
|
+
clearHintIfInvalid: function clearHintIfInvalid() {
|
1093
|
+
var val, hint, valIsPrefixOfHint, isValid;
|
1094
|
+
val = this.getInputValue();
|
1095
|
+
hint = this.getHint();
|
1096
|
+
valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
|
1097
|
+
isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
|
1098
|
+
!isValid && this.clearHint();
|
1003
1099
|
},
|
1004
1100
|
getLanguageDirection: function getLanguageDirection() {
|
1005
1101
|
return (this.$input.css("direction") || "ltr").toLowerCase();
|
@@ -1033,7 +1129,7 @@
|
|
1033
1129
|
return $('<pre aria-hidden="true"></pre>').css({
|
1034
1130
|
position: "absolute",
|
1035
1131
|
visibility: "hidden",
|
1036
|
-
whiteSpace: "
|
1132
|
+
whiteSpace: "pre",
|
1037
1133
|
fontFamily: $input.css("font-family"),
|
1038
1134
|
fontSize: $input.css("font-size"),
|
1039
1135
|
fontStyle: $input.css("font-style"),
|
@@ -1054,6 +1150,7 @@
|
|
1054
1150
|
}
|
1055
1151
|
}();
|
1056
1152
|
var Dataset = function() {
|
1153
|
+
"use strict";
|
1057
1154
|
var datasetKey = "ttDataset", valueKey = "ttValue", datumKey = "ttDatum";
|
1058
1155
|
function Dataset(o) {
|
1059
1156
|
o = o || {};
|
@@ -1107,15 +1204,14 @@
|
|
1107
1204
|
nodes = _.map(suggestions, getSuggestionNode);
|
1108
1205
|
$suggestions.append.apply($suggestions, nodes);
|
1109
1206
|
that.highlight && highlight({
|
1207
|
+
className: "tt-highlight",
|
1110
1208
|
node: $suggestions[0],
|
1111
1209
|
pattern: query
|
1112
1210
|
});
|
1113
1211
|
return $suggestions;
|
1114
1212
|
function getSuggestionNode(suggestion) {
|
1115
|
-
var $el
|
1116
|
-
|
1117
|
-
outerHtml = html.suggestion.replace("%BODY%", innerHtml);
|
1118
|
-
$el = $(outerHtml).data(datasetKey, that.name).data(valueKey, that.displayFn(suggestion)).data(datumKey, suggestion);
|
1213
|
+
var $el;
|
1214
|
+
$el = $(html.suggestion).append(that.templates.suggestion(suggestion)).data(datasetKey, that.name).data(valueKey, that.displayFn(suggestion)).data(datumKey, suggestion);
|
1119
1215
|
$el.children().each(function() {
|
1120
1216
|
$(this).css(css.suggestionChild);
|
1121
1217
|
});
|
@@ -1141,13 +1237,21 @@
|
|
1141
1237
|
update: function update(query) {
|
1142
1238
|
var that = this;
|
1143
1239
|
this.query = query;
|
1144
|
-
this.
|
1145
|
-
|
1146
|
-
|
1240
|
+
this.canceled = false;
|
1241
|
+
this.source(query, render);
|
1242
|
+
function render(suggestions) {
|
1243
|
+
if (!that.canceled && query === that.query) {
|
1244
|
+
that._render(query, suggestions);
|
1245
|
+
}
|
1147
1246
|
}
|
1148
1247
|
},
|
1248
|
+
cancel: function cancel() {
|
1249
|
+
this.canceled = true;
|
1250
|
+
},
|
1149
1251
|
clear: function clear() {
|
1150
|
-
this.
|
1252
|
+
this.cancel();
|
1253
|
+
this.$el.empty();
|
1254
|
+
this.trigger("rendered");
|
1151
1255
|
},
|
1152
1256
|
isEmpty: function isEmpty() {
|
1153
1257
|
return this.$el.is(":empty");
|
@@ -1180,6 +1284,7 @@
|
|
1180
1284
|
}
|
1181
1285
|
}();
|
1182
1286
|
var Dropdown = function() {
|
1287
|
+
"use strict";
|
1183
1288
|
function Dropdown(o) {
|
1184
1289
|
var that = this, onSuggestionClick, onSuggestionMouseEnter, onSuggestionMouseLeave;
|
1185
1290
|
o = o || {};
|
@@ -1206,7 +1311,7 @@
|
|
1206
1311
|
this._removeCursor();
|
1207
1312
|
this._setCursor($($e.currentTarget), true);
|
1208
1313
|
},
|
1209
|
-
_onSuggestionMouseLeave: function onSuggestionMouseLeave(
|
1314
|
+
_onSuggestionMouseLeave: function onSuggestionMouseLeave() {
|
1210
1315
|
this._removeCursor();
|
1211
1316
|
},
|
1212
1317
|
_onRendered: function onRendered() {
|
@@ -1339,19 +1444,37 @@
|
|
1339
1444
|
}
|
1340
1445
|
}();
|
1341
1446
|
var Typeahead = function() {
|
1447
|
+
"use strict";
|
1342
1448
|
var attrsKey = "ttAttrs";
|
1343
1449
|
function Typeahead(o) {
|
1344
|
-
var $menu, $input, $hint
|
1450
|
+
var $menu, $input, $hint;
|
1345
1451
|
o = o || {};
|
1346
1452
|
if (!o.input) {
|
1347
1453
|
$.error("missing input");
|
1348
1454
|
}
|
1455
|
+
this.isActivated = false;
|
1349
1456
|
this.autoselect = !!o.autoselect;
|
1350
1457
|
this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
|
1351
|
-
this.$node =
|
1458
|
+
this.$node = buildDom(o.input, o.withHint);
|
1352
1459
|
$menu = this.$node.find(".tt-dropdown-menu");
|
1353
1460
|
$input = this.$node.find(".tt-input");
|
1354
1461
|
$hint = this.$node.find(".tt-hint");
|
1462
|
+
$input.on("blur.tt", function($e) {
|
1463
|
+
var active, isActive, hasActive;
|
1464
|
+
active = document.activeElement;
|
1465
|
+
isActive = $menu.is(active);
|
1466
|
+
hasActive = $menu.has(active).length > 0;
|
1467
|
+
if (_.isMsie() && (isActive || hasActive)) {
|
1468
|
+
$e.preventDefault();
|
1469
|
+
$e.stopImmediatePropagation();
|
1470
|
+
_.defer(function() {
|
1471
|
+
$input.focus();
|
1472
|
+
});
|
1473
|
+
}
|
1474
|
+
});
|
1475
|
+
$menu.on("mousedown.tt", function($e) {
|
1476
|
+
$e.preventDefault();
|
1477
|
+
});
|
1355
1478
|
this.eventBus = o.eventBus || new EventBus({
|
1356
1479
|
el: $input
|
1357
1480
|
});
|
@@ -1363,15 +1486,7 @@
|
|
1363
1486
|
input: $input,
|
1364
1487
|
hint: $hint
|
1365
1488
|
}).onSync("focused", this._onFocused, this).onSync("blurred", this._onBlurred, this).onSync("enterKeyed", this._onEnterKeyed, this).onSync("tabKeyed", this._onTabKeyed, this).onSync("escKeyed", this._onEscKeyed, this).onSync("upKeyed", this._onUpKeyed, this).onSync("downKeyed", this._onDownKeyed, this).onSync("leftKeyed", this._onLeftKeyed, this).onSync("rightKeyed", this._onRightKeyed, this).onSync("queryChanged", this._onQueryChanged, this).onSync("whitespaceChanged", this._onWhitespaceChanged, this);
|
1366
|
-
|
1367
|
-
if (_.isMsie() && _.isMsie() < 9) {
|
1368
|
-
$input[0].onbeforedeactivate = function() {
|
1369
|
-
window.event.returnValue = false;
|
1370
|
-
$input[0].onbeforedeactivate = null;
|
1371
|
-
};
|
1372
|
-
}
|
1373
|
-
$e.preventDefault();
|
1374
|
-
});
|
1489
|
+
this._setLanguageDirection();
|
1375
1490
|
}
|
1376
1491
|
_.mixin(Typeahead.prototype, {
|
1377
1492
|
_onSuggestionClicked: function onSuggestionClicked(type, $el) {
|
@@ -1382,7 +1497,6 @@
|
|
1382
1497
|
},
|
1383
1498
|
_onCursorMoved: function onCursorMoved() {
|
1384
1499
|
var datum = this.dropdown.getDatumForCursor();
|
1385
|
-
this.input.clearHint();
|
1386
1500
|
this.input.setInputValue(datum.value, true);
|
1387
1501
|
this.eventBus.trigger("cursorchanged", datum.raw, datum.datasetName);
|
1388
1502
|
},
|
@@ -1402,10 +1516,12 @@
|
|
1402
1516
|
this.eventBus.trigger("closed");
|
1403
1517
|
},
|
1404
1518
|
_onFocused: function onFocused() {
|
1405
|
-
this.
|
1519
|
+
this.isActivated = true;
|
1406
1520
|
this.dropdown.open();
|
1407
1521
|
},
|
1408
1522
|
_onBlurred: function onBlurred() {
|
1523
|
+
this.isActivated = false;
|
1524
|
+
this.dropdown.empty();
|
1409
1525
|
this.dropdown.close();
|
1410
1526
|
},
|
1411
1527
|
_onEnterKeyed: function onEnterKeyed(type, $e) {
|
@@ -1426,7 +1542,7 @@
|
|
1426
1542
|
this._select(datum);
|
1427
1543
|
$e.preventDefault();
|
1428
1544
|
} else {
|
1429
|
-
this._autocomplete();
|
1545
|
+
this._autocomplete(true);
|
1430
1546
|
}
|
1431
1547
|
},
|
1432
1548
|
_onEscKeyed: function onEscKeyed() {
|
@@ -1435,19 +1551,13 @@
|
|
1435
1551
|
},
|
1436
1552
|
_onUpKeyed: function onUpKeyed() {
|
1437
1553
|
var query = this.input.getQuery();
|
1438
|
-
|
1439
|
-
this.dropdown.update(query);
|
1440
|
-
}
|
1554
|
+
this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorUp();
|
1441
1555
|
this.dropdown.open();
|
1442
|
-
this.dropdown.moveCursorUp();
|
1443
1556
|
},
|
1444
1557
|
_onDownKeyed: function onDownKeyed() {
|
1445
1558
|
var query = this.input.getQuery();
|
1446
|
-
|
1447
|
-
this.dropdown.update(query);
|
1448
|
-
}
|
1559
|
+
this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorDown();
|
1449
1560
|
this.dropdown.open();
|
1450
|
-
this.dropdown.moveCursorDown();
|
1451
1561
|
},
|
1452
1562
|
_onLeftKeyed: function onLeftKeyed() {
|
1453
1563
|
this.dir === "rtl" && this._autocomplete();
|
@@ -1456,9 +1566,8 @@
|
|
1456
1566
|
this.dir === "ltr" && this._autocomplete();
|
1457
1567
|
},
|
1458
1568
|
_onQueryChanged: function onQueryChanged(e, query) {
|
1459
|
-
this.input.
|
1460
|
-
this.dropdown.empty();
|
1461
|
-
query.length >= this.minLength && this.dropdown.update(query);
|
1569
|
+
this.input.clearHintIfInvalid();
|
1570
|
+
query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.empty();
|
1462
1571
|
this.dropdown.open();
|
1463
1572
|
this._setLanguageDirection();
|
1464
1573
|
},
|
@@ -1475,29 +1584,31 @@
|
|
1475
1584
|
}
|
1476
1585
|
},
|
1477
1586
|
_updateHint: function updateHint() {
|
1478
|
-
var datum,
|
1587
|
+
var datum, val, query, escapedQuery, frontMatchRegEx, match;
|
1479
1588
|
datum = this.dropdown.getDatumForTopSuggestion();
|
1480
1589
|
if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) {
|
1481
|
-
|
1482
|
-
query = Input.normalizeQuery(
|
1590
|
+
val = this.input.getInputValue();
|
1591
|
+
query = Input.normalizeQuery(val);
|
1483
1592
|
escapedQuery = _.escapeRegExChars(query);
|
1484
|
-
frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(
|
1593
|
+
frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
|
1485
1594
|
match = frontMatchRegEx.exec(datum.value);
|
1486
|
-
this.input.
|
1595
|
+
match ? this.input.setHint(val + match[1]) : this.input.clearHint();
|
1596
|
+
} else {
|
1597
|
+
this.input.clearHint();
|
1487
1598
|
}
|
1488
1599
|
},
|
1489
|
-
_autocomplete: function autocomplete() {
|
1490
|
-
var hint, query, datum;
|
1491
|
-
hint = this.input.
|
1600
|
+
_autocomplete: function autocomplete(laxCursor) {
|
1601
|
+
var hint, query, isCursorAtEnd, datum;
|
1602
|
+
hint = this.input.getHint();
|
1492
1603
|
query = this.input.getQuery();
|
1493
|
-
|
1604
|
+
isCursorAtEnd = laxCursor || this.input.isCursorAtEnd();
|
1605
|
+
if (hint && query !== hint && isCursorAtEnd) {
|
1494
1606
|
datum = this.dropdown.getDatumForTopSuggestion();
|
1495
1607
|
datum && this.input.setInputValue(datum.value);
|
1496
1608
|
this.eventBus.trigger("autocompleted", datum.raw, datum.datasetName);
|
1497
1609
|
}
|
1498
1610
|
},
|
1499
1611
|
_select: function select(datum) {
|
1500
|
-
this.input.clearHint();
|
1501
1612
|
this.input.setQuery(datum.value);
|
1502
1613
|
this.input.setInputValue(datum.value, true);
|
1503
1614
|
this._setLanguageDirection();
|
@@ -1511,11 +1622,18 @@
|
|
1511
1622
|
close: function close() {
|
1512
1623
|
this.dropdown.close();
|
1513
1624
|
},
|
1514
|
-
|
1515
|
-
|
1625
|
+
setVal: function setVal(val) {
|
1626
|
+
val = _.toStr(val);
|
1627
|
+
if (this.isActivated) {
|
1628
|
+
this.input.setInputValue(val);
|
1629
|
+
} else {
|
1630
|
+
this.input.setQuery(val);
|
1631
|
+
this.input.setInputValue(val, true);
|
1632
|
+
}
|
1633
|
+
this._setLanguageDirection();
|
1516
1634
|
},
|
1517
|
-
|
1518
|
-
this.input.
|
1635
|
+
getVal: function getVal() {
|
1636
|
+
return this.input.getQuery();
|
1519
1637
|
},
|
1520
1638
|
destroy: function destroy() {
|
1521
1639
|
this.input.destroy();
|
@@ -1525,15 +1643,16 @@
|
|
1525
1643
|
}
|
1526
1644
|
});
|
1527
1645
|
return Typeahead;
|
1528
|
-
function
|
1646
|
+
function buildDom(input, withHint) {
|
1529
1647
|
var $input, $wrapper, $dropdown, $hint;
|
1530
1648
|
$input = $(input);
|
1531
1649
|
$wrapper = $(html.wrapper).css(css.wrapper);
|
1532
1650
|
$dropdown = $(html.dropdown).css(css.dropdown);
|
1533
1651
|
$hint = $input.clone().css(css.hint).css(getBackgroundStyles($input));
|
1534
|
-
$hint.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder").prop("
|
1652
|
+
$hint.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly", true).attr({
|
1535
1653
|
autocomplete: "off",
|
1536
|
-
spellcheck: "false"
|
1654
|
+
spellcheck: "false",
|
1655
|
+
tabindex: -1
|
1537
1656
|
});
|
1538
1657
|
$input.data(attrsKey, {
|
1539
1658
|
dir: $input.attr("dir"),
|
@@ -1572,6 +1691,7 @@
|
|
1572
1691
|
}
|
1573
1692
|
}();
|
1574
1693
|
(function() {
|
1694
|
+
"use strict";
|
1575
1695
|
var old, typeaheadKey, methods;
|
1576
1696
|
old = $.fn.typeahead;
|
1577
1697
|
typeaheadKey = "ttTypeahead";
|
@@ -1617,17 +1737,17 @@
|
|
1617
1737
|
}
|
1618
1738
|
},
|
1619
1739
|
val: function val(newVal) {
|
1620
|
-
return !arguments.length ?
|
1621
|
-
function
|
1740
|
+
return !arguments.length ? getVal(this.first()) : this.each(setVal);
|
1741
|
+
function setVal() {
|
1622
1742
|
var $input = $(this), typeahead;
|
1623
1743
|
if (typeahead = $input.data(typeaheadKey)) {
|
1624
|
-
typeahead.
|
1744
|
+
typeahead.setVal(newVal);
|
1625
1745
|
}
|
1626
1746
|
}
|
1627
|
-
function
|
1747
|
+
function getVal($input) {
|
1628
1748
|
var typeahead, query;
|
1629
1749
|
if (typeahead = $input.data(typeaheadKey)) {
|
1630
|
-
query = typeahead.
|
1750
|
+
query = typeahead.getVal();
|
1631
1751
|
}
|
1632
1752
|
return query;
|
1633
1753
|
}
|
@@ -1644,8 +1764,12 @@
|
|
1644
1764
|
}
|
1645
1765
|
};
|
1646
1766
|
$.fn.typeahead = function(method) {
|
1647
|
-
|
1648
|
-
|
1767
|
+
var tts;
|
1768
|
+
if (methods[method] && method !== "initialize") {
|
1769
|
+
tts = this.filter(function() {
|
1770
|
+
return !!$(this).data(typeaheadKey);
|
1771
|
+
});
|
1772
|
+
return methods[method].apply(tts, [].slice.call(arguments, 1));
|
1649
1773
|
} else {
|
1650
1774
|
return methods.initialize.apply(this, arguments);
|
1651
1775
|
}
|