twitter-typeahead-rails 0.10.2 → 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.
@@ -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
  }