176 lines
5.8 KiB
JavaScript
176 lines
5.8 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
// Thanks to https://github.com/mattyork/fuzzy
|
|
var TributeSearch = function () {
|
|
function TributeSearch(tribute) {
|
|
_classCallCheck(this, TributeSearch);
|
|
|
|
this.tribute = tribute;
|
|
this.tribute.search = this;
|
|
}
|
|
|
|
_createClass(TributeSearch, [{
|
|
key: 'simpleFilter',
|
|
value: function simpleFilter(pattern, array) {
|
|
var _this = this;
|
|
|
|
return array.filter(function (string) {
|
|
return _this.test(pattern, string);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'test',
|
|
value: function test(pattern, string) {
|
|
return this.match(pattern, string) !== null;
|
|
}
|
|
}, {
|
|
key: 'match',
|
|
value: function match(pattern, string, opts) {
|
|
opts = opts || {};
|
|
var patternIdx = 0,
|
|
result = [],
|
|
len = string.length,
|
|
totalScore = 0,
|
|
currScore = 0,
|
|
pre = opts.pre || '',
|
|
post = opts.post || '',
|
|
compareString = opts.caseSensitive && string || string.toLowerCase(),
|
|
ch = void 0,
|
|
compareChar = void 0;
|
|
|
|
pattern = opts.caseSensitive && pattern || pattern.toLowerCase();
|
|
|
|
var patternCache = this.traverse(compareString, pattern, 0, 0, []);
|
|
if (!patternCache) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
rendered: this.render(string, patternCache.cache, pre, post),
|
|
score: patternCache.score
|
|
};
|
|
}
|
|
}, {
|
|
key: 'traverse',
|
|
value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) {
|
|
// if the pattern search at end
|
|
if (pattern.length === patternIndex) {
|
|
|
|
// calculate score and copy the cache containing the indices where it's found
|
|
return {
|
|
score: this.calculateScore(patternCache),
|
|
cache: patternCache.slice()
|
|
};
|
|
}
|
|
|
|
// if string at end or remaining pattern > remaining string
|
|
if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) {
|
|
return undefined;
|
|
}
|
|
|
|
var c = pattern[patternIndex];
|
|
var index = string.indexOf(c, stringIndex);
|
|
var best = void 0,
|
|
temp = void 0;
|
|
|
|
while (index > -1) {
|
|
patternCache.push(index);
|
|
temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache);
|
|
patternCache.pop();
|
|
|
|
// if downstream traversal failed, return best answer so far
|
|
if (!temp) {
|
|
return best;
|
|
}
|
|
|
|
if (!best || best.score < temp.score) {
|
|
best = temp;
|
|
}
|
|
|
|
index = string.indexOf(c, index + 1);
|
|
}
|
|
|
|
return best;
|
|
}
|
|
}, {
|
|
key: 'calculateScore',
|
|
value: function calculateScore(patternCache) {
|
|
var score = 0;
|
|
var temp = 1;
|
|
|
|
patternCache.forEach(function (index, i) {
|
|
if (i > 0) {
|
|
if (patternCache[i - 1] + 1 === index) {
|
|
temp += temp + 1;
|
|
} else {
|
|
temp = 1;
|
|
}
|
|
}
|
|
|
|
score += temp;
|
|
});
|
|
|
|
return score;
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render(string, indices, pre, post) {
|
|
var rendered = string.substring(0, indices[0]);
|
|
|
|
indices.forEach(function (index, i) {
|
|
rendered += pre + string[index] + post + string.substring(index + 1, indices[i + 1] ? indices[i + 1] : string.length);
|
|
});
|
|
|
|
return rendered;
|
|
}
|
|
}, {
|
|
key: 'filter',
|
|
value: function filter(pattern, arr, opts) {
|
|
var _this2 = this;
|
|
|
|
opts = opts || {};
|
|
return arr.reduce(function (prev, element, idx, arr) {
|
|
var str = element;
|
|
|
|
if (opts.extract) {
|
|
str = opts.extract(element);
|
|
|
|
if (!str) {
|
|
// take care of undefineds / nulls / etc.
|
|
str = '';
|
|
}
|
|
}
|
|
|
|
var rendered = _this2.match(pattern, str, opts);
|
|
|
|
if (rendered != null) {
|
|
prev[prev.length] = {
|
|
string: rendered.rendered,
|
|
score: rendered.score,
|
|
index: idx,
|
|
original: element
|
|
};
|
|
}
|
|
|
|
return prev;
|
|
}, []).sort(function (a, b) {
|
|
var compare = b.score - a.score;
|
|
if (compare) return compare;
|
|
return a.index - b.index;
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return TributeSearch;
|
|
}();
|
|
|
|
exports.default = TributeSearch;
|
|
module.exports = exports['default']; |