Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "corejs-typeahead",
"version": "0.11.1",
"version": "0.11.2",
"main": "dist/typeahead.bundle.js",
"dependencies": {
"jquery": ">=1.7"
Expand Down
21 changes: 18 additions & 3 deletions dist/bloodhound.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*!
* typeahead.js 0.11.1
* https://github.com/twitter/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
* Copyright 2013-2016 Twitter, Inc. and other contributors; Licensed MIT
*/

(function(root, factory) {
Expand All @@ -12,7 +12,7 @@
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"));
} else {
root["Bloodhound"] = factory(jQuery);
root["Bloodhound"] = factory(root["jQuery"]);
}
})(this, function($) {
var _ = function() {
Expand Down Expand Up @@ -157,9 +157,11 @@
return {
nonword: nonword,
whitespace: whitespace,
ngram: ngram,
obj: {
nonword: getObjTokenizer(nonword),
whitespace: getObjTokenizer(whitespace)
whitespace: getObjTokenizer(whitespace),
ngram: getObjTokenizer(ngram)
}
};
function whitespace(str) {
Expand All @@ -170,6 +172,19 @@
str = _.toStr(str);
return str ? str.split(/\W+/) : [];
}
function ngram(str) {
str = _.toStr(str);
var tokens = [], word = "";
_.each(str.split(""), function(char) {
if (char.match(/\s+/)) {
word = "";
} else {
tokens.push(word + char);
word += char;
}
});
return tokens;
}
function getObjTokenizer(tokenizer) {
return function setKey(keys) {
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
Expand Down
4 changes: 2 additions & 2 deletions dist/bloodhound.min.js

Large diffs are not rendered by default.

31 changes: 25 additions & 6 deletions dist/typeahead.bundle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*!
* typeahead.js 0.11.1
* https://github.com/twitter/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
* Copyright 2013-2016 Twitter, Inc. and other contributors; Licensed MIT
*/

(function(root, factory) {
Expand All @@ -12,7 +12,7 @@
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"));
} else {
root["Bloodhound"] = factory(jQuery);
root["Bloodhound"] = factory(root["jQuery"]);
}
})(this, function($) {
var _ = function() {
Expand Down Expand Up @@ -157,9 +157,11 @@
return {
nonword: nonword,
whitespace: whitespace,
ngram: ngram,
obj: {
nonword: getObjTokenizer(nonword),
whitespace: getObjTokenizer(whitespace)
whitespace: getObjTokenizer(whitespace),
ngram: getObjTokenizer(ngram)
}
};
function whitespace(str) {
Expand All @@ -170,6 +172,19 @@
str = _.toStr(str);
return str ? str.split(/\W+/) : [];
}
function ngram(str) {
str = _.toStr(str);
var tokens = [], word = "";
_.each(str.split(""), function(char) {
if (char.match(/\s+/)) {
word = "";
} else {
tokens.push(word + char);
word += char;
}
});
return tokens;
}
function getObjTokenizer(tokenizer) {
return function setKey(keys) {
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
Expand Down Expand Up @@ -935,7 +950,7 @@
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"));
} else {
factory(jQuery);
factory(root["jQuery"]);
}
})(this, function($) {
var _ = function() {
Expand Down Expand Up @@ -1730,8 +1745,9 @@
suggestions = suggestions || [];
if (!canceled && rendered < that.limit) {
that.cancel = $.noop;
that._append(query, suggestions.slice(0, that.limit - rendered));
rendered += suggestions.length;
var idx = Math.abs(rendered - that.limit);
rendered += idx;
that._append(query, suggestions.slice(0, idx));
that.async && that.trigger("asyncReceived", query);
}
}
Expand Down Expand Up @@ -1838,6 +1854,9 @@
this.$node.on("mouseover", this.selectors.selectable, function() {
that.setCursor($(this));
});
this.$node.on("mouseleave", function() {
that._removeCursor();
});
_.each(this.datasets, function(dataset) {
dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
});
Expand Down
6 changes: 3 additions & 3 deletions dist/typeahead.bundle.min.js

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions dist/typeahead.jquery.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*!
* typeahead.js 0.11.1
* https://github.com/twitter/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
* Copyright 2013-2016 Twitter, Inc. and other contributors; Licensed MIT
*/

(function(root, factory) {
Expand All @@ -12,7 +12,7 @@
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"));
} else {
factory(jQuery);
factory(root["jQuery"]);
}
})(this, function($) {
var _ = function() {
Expand Down Expand Up @@ -807,8 +807,9 @@
suggestions = suggestions || [];
if (!canceled && rendered < that.limit) {
that.cancel = $.noop;
that._append(query, suggestions.slice(0, that.limit - rendered));
rendered += suggestions.length;
var idx = Math.abs(rendered - that.limit);
rendered += idx;
that._append(query, suggestions.slice(0, idx));
that.async && that.trigger("asyncReceived", query);
}
}
Expand Down Expand Up @@ -915,6 +916,9 @@
this.$node.on("mouseover", this.selectors.selectable, function() {
that.setCursor($(this));
});
this.$node.on("mouseleave", function() {
that._removeCursor();
});
_.each(this.datasets, function(dataset) {
dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
});
Expand Down
4 changes: 2 additions & 2 deletions dist/typeahead.jquery.min.js

Large diffs are not rendered by default.

22 changes: 20 additions & 2 deletions doc/bloodhound.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Table of Contents
* [Usage](#usage)
* [API](#api)
* [Options](#options)
* [Tokenizers] (#tokenizers)
* [Prefetch](#prefetch)
* [Remote](#remote)

Expand Down Expand Up @@ -164,10 +165,10 @@ When instantiating a Bloodhound suggestion engine, there are a number of
options you can configure.

* `datumTokenizer` – A function with the signature `(datum)` that transforms a
datum into an array of string tokens. **Required**.
datum into an array of string tokens. See [Tokenizers](#tokenizers). **Required**.

* `queryTokenizer` – A function with the signature `(query)` that transforms a
query into an array of string tokens. **Required**.
query into an array of string tokens. See [Tokenizers](#tokenizers). **Required**.

* `matchAnyQueryToken` - By default a search result must match ALL query-tokens.
Instead, this option returns results that match ANY query-tokens. Defaults to
Expand Down Expand Up @@ -204,6 +205,23 @@ options you can configure.

[compare function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

### Tokenizers

The Bloodhound suggestion engine is token-based, so how datums and queries are tokenized plays a vital role in the quality of search results.

A tokenizer is a function with the signature `(string)` that transforms a query into an array of string tokens. When instantiating a Bloodhound suggestion engine, you can use your own tokenizer or one of the following included implementations:

```javascript
// returns ['foo', 'bar', 'foo-bar']
Bloodhound.tokenizers.whitespace('foo bar foo-bar');

// returns ['foo', 'bar', 'foo', 'bar']
Bloodhound.tokenizers.nonword('foo bar foo-bar');

// returns ['f', 'fo', 'foo', 'b', 'ba', 'bar']
Bloodhound.tokenizers.ngram('foo bar');
```

### Prefetch

Prefetched data is fetched and processed on initialization. If the browser
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@
"scripts": {
"test": "bower install && ./node_modules/karma/bin/karma start --single-run --browsers PhantomJS"
},
"version": "0.11.1",
"version": "0.11.2",
"main": "dist/typeahead.bundle.js"
}
22 changes: 21 additions & 1 deletion src/bloodhound/tokenizers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ var tokenizers = (function() {
return {
nonword: nonword,
whitespace: whitespace,
ngram: ngram,
obj: {
nonword: getObjTokenizer(nonword),
whitespace: getObjTokenizer(whitespace)
whitespace: getObjTokenizer(whitespace),
ngram: getObjTokenizer(ngram)
}
};

Expand All @@ -26,6 +28,24 @@ var tokenizers = (function() {
return str ? str.split(/\W+/) : [];
}

function ngram(str) {
str = _.toStr(str);

var tokens = [],
word = '';

_.each(str.split(''), function(char) {
if (char.match(/\s+/)) {
word = '';
} else {
tokens.push(word+char);
word += char;
}
});

return tokens;
}

function getObjTokenizer(tokenizer) {
return function setKey(keys) {
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
Expand Down
36 changes: 36 additions & 0 deletions test/bloodhound/tokenizers_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ describe('tokenizers', function() {
expect(tokens).toEqual([]);
});

it('.ngram should treat null as empty string', function() {
var tokens = tokenizers.ngram(null);
expect(tokens).toEqual([]);
});

it('.ngram should treat undefined as empty string', function() {
var tokens = tokenizers.ngram(undefined);
expect(tokens).toEqual([]);
});

it('.ngram should tokenize to edge ngrams', function() {
var tokens = tokenizers.ngram('foo bar');
expect(tokens).toEqual(['f', 'fo', 'foo', 'b', 'ba', 'bar']);
});

it('.obj.whitespace should tokenize on whitespace', function() {
var t = tokenizers.obj.whitespace('val');
var tokens = t({ val: 'big-deal ok' });
Expand Down Expand Up @@ -71,4 +86,25 @@ describe('tokenizers', function() {

expect(tokens).toEqual(['big', 'deal', 'ok', 'buzz']);
});

it('.obj.ngram should tokenize to edge ngrams', function() {
var t = tokenizers.obj.ngram('val');
var tokens = t({ val: 'foo bar' });

expect(tokens).toEqual(['f', 'fo', 'foo', 'b', 'ba', 'bar']);
});

it('.obj.ngram should accept multiple properties', function() {
var t = tokenizers.obj.ngram('one', 'two');
var tokens = t({ one: 'foo bar', two: 'baz' });

expect(tokens).toEqual(['f', 'fo', 'foo', 'b', 'ba', 'bar', 'b', 'ba', 'baz']);
});

it('.obj.ngram should accept array', function() {
var t = tokenizers.obj.ngram(['one', 'two']);
var tokens = t({ one: 'foo bar', two: 'baz' });

expect(tokens).toEqual(['f', 'fo', 'foo', 'b', 'ba', 'bar', 'b', 'ba', 'baz']);
});
});