twitter-typeahead-rails 0.10.2 → 0.10.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTEyNTc3YTNkMTYwYjViMzNiOGUyYzA1N2FjM2MzYjAwMjI1ZWQ5YQ==
5
+ data.tar.gz: !binary |-
6
+ MmQ3ZDUzNTQ3ODU3NWU4Njg1ZDY4ZmMzZDE1NDI0YjEwMjg3NjYwNA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ N2QyNDJjNDQ5MjhkODk4YjM5MTM2NWVkNTAxNzkzMzdjMWRmOWMzZDU1NTQ0
10
+ YTgzNTA5YjI1OWMyNThhZTZmZTQ4ODZlNTEzOTUxY2I4ODhlZGFmMGViNGQ1
11
+ NTU0MDJiYjhkYWI0ODQ4YTg4MzNhNDg4ZWJjNWJhYTliMDU1YTY=
12
+ data.tar.gz: !binary |-
13
+ NGFhNTRhNjViNGYxZGI1ZjBiOWE2YWU0NjIxNWE4ZDAyNmViZjcxZTg4NWEy
14
+ NWEyMWI3ZTM2MDZhYzY5YThjOTBjMjczYmYzODUzYTQ4OTFhYzczNGUyZmJk
15
+ MzgwYWJmMTExMjU1MjRkY2U4ZTA2M2M5MjQ4NTczMmJlNWE4ZGQ=
data/README.md CHANGED
@@ -72,7 +72,7 @@ $('.example-numbers .typeahead').typeahead(null, {
72
72
  });
73
73
  ```
74
74
 
75
- Currently this version tracks version v0.10.2.
75
+ Currently this version tracks version v0.10.5.
76
76
 
77
77
  ## Contributing
78
78
 
@@ -1,7 +1,7 @@
1
1
  module Twitter
2
2
  module Typeahead
3
3
  module Rails
4
- VERSION = "0.10.2"
4
+ VERSION = "0.10.5"
5
5
  end
6
6
  end
7
7
  end
@@ -1,127 +1,134 @@
1
1
  /*!
2
- * typeahead.js 0.10.2
2
+ * typeahead.js 0.10.5
3
3
  * https://github.com/twitter/typeahead.js
4
4
  * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
5
5
  */
6
6
 
7
7
  (function($) {
8
- var _ = {
9
- isMsie: function() {
10
- return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
11
- },
12
- isBlankString: function(str) {
13
- return !str || /^\s*$/.test(str);
14
- },
15
- escapeRegExChars: function(str) {
16
- return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
17
- },
18
- isString: function(obj) {
19
- return typeof obj === "string";
20
- },
21
- isNumber: function(obj) {
22
- return typeof obj === "number";
23
- },
24
- isArray: $.isArray,
25
- isFunction: $.isFunction,
26
- isObject: $.isPlainObject,
27
- isUndefined: function(obj) {
28
- return typeof obj === "undefined";
29
- },
30
- bind: $.proxy,
31
- each: function(collection, cb) {
32
- $.each(collection, reverseArgs);
33
- function reverseArgs(index, value) {
34
- return cb(value, index);
35
- }
36
- },
37
- map: $.map,
38
- filter: $.grep,
39
- every: function(obj, test) {
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
- return !!result;
50
- },
51
- some: function(obj, test) {
52
- var result = false;
53
- if (!obj) {
54
- return result;
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
- return !!result;
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;
52
+ }
53
+ });
54
+ return !!result;
55
+ },
56
+ some: function(obj, test) {
57
+ var result = false;
58
+ if (!obj) {
59
+ return result;
60
+ }
61
+ $.each(obj, function(key, val) {
62
+ if (result = test.call(null, val, key, obj)) {
63
+ return false;
87
64
  }
65
+ });
66
+ return !!result;
67
+ },
68
+ mixin: $.extend,
69
+ getUniqueId: function() {
70
+ var counter = 0;
71
+ return function() {
72
+ return counter++;
88
73
  };
89
- callNow = immediate && !timeout;
90
- clearTimeout(timeout);
91
- timeout = setTimeout(later, wait);
92
- if (callNow) {
93
- result = func.apply(context, args);
74
+ }(),
75
+ templatify: function templatify(obj) {
76
+ return $.isFunction(obj) ? obj : template;
77
+ function template() {
78
+ return String(obj);
94
79
  }
95
- return result;
96
- };
97
- },
98
- throttle: function(func, wait) {
99
- var context, args, timeout, result, previous, later;
100
- previous = 0;
101
- later = function() {
102
- previous = new Date();
103
- timeout = null;
104
- result = func.apply(context, args);
105
- };
106
- return function() {
107
- var now = new Date(), remaining = wait - (now - previous);
108
- context = this;
109
- args = arguments;
110
- if (remaining <= 0) {
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
- } else if (!timeout) {
116
- timeout = setTimeout(later, remaining);
117
- }
118
- return result;
119
- };
120
- },
121
- noop: function() {}
122
- };
123
- var VERSION = "0.10.2";
124
- var tokenizers = function(root) {
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";
125
132
  return {
126
133
  nonword: nonword,
127
134
  whitespace: whitespace,
@@ -130,26 +137,35 @@
130
137
  whitespace: getObjTokenizer(whitespace)
131
138
  }
132
139
  };
133
- function whitespace(s) {
134
- return s.split(/\s+/);
140
+ function whitespace(str) {
141
+ str = _.toStr(str);
142
+ return str ? str.split(/\s+/) : [];
135
143
  }
136
- function nonword(s) {
137
- return s.split(/\W+/);
144
+ function nonword(str) {
145
+ str = _.toStr(str);
146
+ return str ? str.split(/\W+/) : [];
138
147
  }
139
148
  function getObjTokenizer(tokenizer) {
140
- return function setKey(key) {
149
+ return function setKey() {
150
+ var args = [].slice.call(arguments, 0);
141
151
  return function tokenize(o) {
142
- return tokenizer(o[key]);
152
+ var tokens = [];
153
+ _.each(args, function(k) {
154
+ tokens = tokens.concat(tokenizer(_.toStr(o[k])));
155
+ });
156
+ return tokens;
143
157
  };
144
158
  };
145
159
  }
146
160
  }();
147
161
  var LruCache = function() {
162
+ "use strict";
148
163
  function LruCache(maxSize) {
149
- this.maxSize = maxSize || 100;
150
- this.size = 0;
151
- this.hash = {};
152
- this.list = new List();
164
+ this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
165
+ this.reset();
166
+ if (this.maxSize <= 0) {
167
+ this.set = this.get = $.noop;
168
+ }
153
169
  }
154
170
  _.mixin(LruCache.prototype, {
155
171
  set: function set(key, val) {
@@ -174,6 +190,11 @@
174
190
  this.list.moveToFront(node);
175
191
  return node.val;
176
192
  }
193
+ },
194
+ reset: function reset() {
195
+ this.size = 0;
196
+ this.hash = {};
197
+ this.list = new List();
177
198
  }
178
199
  });
179
200
  function List() {
@@ -205,6 +226,7 @@
205
226
  return LruCache;
206
227
  }();
207
228
  var PersistentStorage = function() {
229
+ "use strict";
208
230
  var ls, methods;
209
231
  try {
210
232
  ls = window.localStorage;
@@ -216,7 +238,7 @@
216
238
  function PersistentStorage(namespace) {
217
239
  this.prefix = [ "__", namespace, "__" ].join("");
218
240
  this.ttlKey = "__ttl__";
219
- this.keyMatcher = new RegExp("^" + this.prefix);
241
+ this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
220
242
  }
221
243
  if (ls && window.JSON) {
222
244
  methods = {
@@ -284,21 +306,28 @@
284
306
  }
285
307
  }();
286
308
  var Transport = function() {
287
- var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, requestCache = new LruCache(10);
309
+ "use strict";
310
+ var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);
288
311
  function Transport(o) {
289
312
  o = o || {};
313
+ this.cancelled = false;
314
+ this.lastUrl = null;
290
315
  this._send = o.transport ? callbackToDeferred(o.transport) : $.ajax;
291
316
  this._get = o.rateLimiter ? o.rateLimiter(this._get) : this._get;
317
+ this._cache = o.cache === false ? new LruCache(0) : sharedCache;
292
318
  }
293
319
  Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
294
320
  maxPendingRequests = num;
295
321
  };
296
- Transport.resetCache = function clearCache() {
297
- requestCache = new LruCache(10);
322
+ Transport.resetCache = function resetCache() {
323
+ sharedCache.reset();
298
324
  };
299
325
  _.mixin(Transport.prototype, {
300
326
  _get: function(url, o, cb) {
301
327
  var that = this, jqXhr;
328
+ if (this.cancelled || url !== this.lastUrl) {
329
+ return;
330
+ }
302
331
  if (jqXhr = pendingRequests[url]) {
303
332
  jqXhr.done(done).fail(fail);
304
333
  } else if (pendingRequestsCount < maxPendingRequests) {
@@ -309,7 +338,7 @@
309
338
  }
310
339
  function done(resp) {
311
340
  cb && cb(null, resp);
312
- requestCache.set(url, resp);
341
+ that._cache.set(url, resp);
313
342
  }
314
343
  function fail() {
315
344
  cb && cb(true);
@@ -329,7 +358,9 @@
329
358
  cb = o;
330
359
  o = {};
331
360
  }
332
- if (resp = requestCache.get(url)) {
361
+ this.cancelled = false;
362
+ this.lastUrl = url;
363
+ if (resp = this._cache.get(url)) {
333
364
  _.defer(function() {
334
365
  cb && cb(null, resp);
335
366
  });
@@ -337,6 +368,9 @@
337
368
  this._get(url, o, cb);
338
369
  }
339
370
  return !!resp;
371
+ },
372
+ cancel: function() {
373
+ this.cancelled = true;
340
374
  }
341
375
  });
342
376
  return Transport;
@@ -359,6 +393,7 @@
359
393
  }
360
394
  }();
361
395
  var SearchIndex = function() {
396
+ "use strict";
362
397
  function SearchIndex(o) {
363
398
  o = o || {};
364
399
  if (!o.datumTokenizer || !o.queryTokenizer) {
@@ -445,7 +480,7 @@
445
480
  }
446
481
  function unique(array) {
447
482
  var seen = {}, uniques = [];
448
- for (var i = 0; i < array.length; i++) {
483
+ for (var i = 0, len = array.length; i < len; i++) {
449
484
  if (!seen[array[i]]) {
450
485
  seen[array[i]] = true;
451
486
  uniques.push(array[i]);
@@ -457,7 +492,8 @@
457
492
  var ai = 0, bi = 0, intersection = [];
458
493
  arrayA = arrayA.sort(compare);
459
494
  arrayB = arrayB.sort(compare);
460
- while (ai < arrayA.length && bi < arrayB.length) {
495
+ var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
496
+ while (ai < lenArrayA && bi < lenArrayB) {
461
497
  if (arrayA[ai] < arrayB[bi]) {
462
498
  ai++;
463
499
  } else if (arrayA[ai] > arrayB[bi]) {
@@ -475,6 +511,7 @@
475
511
  }
476
512
  }();
477
513
  var oParser = function() {
514
+ "use strict";
478
515
  return {
479
516
  local: getLocal,
480
517
  prefetch: getPrefetch,
@@ -508,6 +545,7 @@
508
545
  var remote, defaults;
509
546
  defaults = {
510
547
  url: null,
548
+ cache: true,
511
549
  wildcard: "%QUERY",
512
550
  replace: null,
513
551
  rateLimitBy: "debounce",
@@ -542,6 +580,7 @@
542
580
  }
543
581
  }();
544
582
  (function(root) {
583
+ "use strict";
545
584
  var old, keys;
546
585
  old = root.Bloodhound;
547
586
  keys = {
@@ -590,6 +629,9 @@
590
629
  },
591
630
  _getFromRemote: function getFromRemote(query, cb) {
592
631
  var that = this, url, uriEncodedQuery;
632
+ if (!this.transport) {
633
+ return;
634
+ }
593
635
  query = query || "";
594
636
  uriEncodedQuery = encodeURIComponent(query);
595
637
  url = this.remote.replace ? this.remote.replace(this.remote.url, query) : this.remote.url.replace(this.remote.wildcard, uriEncodedQuery);
@@ -598,6 +640,9 @@
598
640
  err ? cb([]) : cb(that.remote.filter ? that.remote.filter(resp) : resp);
599
641
  }
600
642
  },
643
+ _cancelLastRemoteRequest: function cancelLastRemoteRequest() {
644
+ this.transport && this.transport.cancel();
645
+ },
601
646
  _saveToStorage: function saveToStorage(data, thumbprint, ttl) {
602
647
  if (this.storage) {
603
648
  this.storage.set(keys.data, data, ttl);
@@ -635,9 +680,7 @@
635
680
  var that = this, matches = [], cacheHit = false;
636
681
  matches = this.index.get(query);
637
682
  matches = this.sorter(matches).slice(0, this.limit);
638
- if (matches.length < this.limit && this.transport) {
639
- cacheHit = this._getFromRemote(query, returnRemoteMatches);
640
- }
683
+ matches.length < this.limit ? cacheHit = this._getFromRemote(query, returnRemoteMatches) : this._cancelLastRemoteRequest();
641
684
  if (!cacheHit) {
642
685
  (matches.length > 0 || !this.transport) && cb && cb(matches);
643
686
  }