| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- // TODO: This file was created by bulk-decaffeinate.
- // Sanity-check the conversion and remove this comment.
- /*
- * decaffeinate suggestions:
- * DS002: Fix invalid constructor
- * DS101: Remove unnecessary use of Array.from
- * DS102: Remove unnecessary code created because of implicit returns
- * DS104: Avoid inline assignments
- * DS202: Simplify dynamic range loops
- * DS206: Consider reworking classes to avoid initClass
- * DS207: Consider shorter variations of null checks
- * DS209: Avoid top-level return
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
- */
- //
- // Match functions
- //
- let fuzzyRegexp,
- i,
- index,
- lastIndex,
- match,
- matcher,
- matchIndex,
- matchLength,
- queryLength,
- score,
- separators,
- value,
- valueLength;
- const SEPARATOR = ".";
- let query =
- (queryLength =
- value =
- valueLength =
- matcher = // current match function
- fuzzyRegexp = // query fuzzy regexp
- index = // position of the query in the string being matched
- lastIndex = // last position of the query in the string being matched
- match = // regexp match data
- matchIndex =
- matchLength =
- score = // score for the current match
- separators = // counter
- i =
- null); // cursor
- function exactMatch() {
- index = value.indexOf(query);
- if (!(index >= 0)) {
- return;
- }
- lastIndex = value.lastIndexOf(query);
- if (index !== lastIndex) {
- return Math.max(
- scoreExactMatch(),
- ((index = lastIndex) && scoreExactMatch()) || 0,
- );
- } else {
- return scoreExactMatch();
- }
- }
- function scoreExactMatch() {
- // Remove one point for each unmatched character.
- score = 100 - (valueLength - queryLength);
- if (index > 0) {
- // If the character preceding the query is a dot, assign the same score
- // as if the query was found at the beginning of the string, minus one.
- if (value.charAt(index - 1) === SEPARATOR) {
- score += index - 1;
- // Don't match a single-character query unless it's found at the beginning
- // of the string or is preceded by a dot.
- } else if (queryLength === 1) {
- return;
- // (1) Remove one point for each unmatched character up to the nearest
- // preceding dot or the beginning of the string.
- // (2) Remove one point for each unmatched character following the query.
- } else {
- i = index - 2;
- while (i >= 0 && value.charAt(i) !== SEPARATOR) {
- i--;
- }
- score -=
- index -
- i + // (1)
- (valueLength - queryLength - index); // (2)
- }
- // Remove one point for each dot preceding the query, except for the one
- // immediately before the query.
- separators = 0;
- i = index - 2;
- while (i >= 0) {
- if (value.charAt(i) === SEPARATOR) {
- separators++;
- }
- i--;
- }
- score -= separators;
- }
- // Remove five points for each dot following the query.
- separators = 0;
- i = valueLength - queryLength - index - 1;
- while (i >= 0) {
- if (value.charAt(index + queryLength + i) === SEPARATOR) {
- separators++;
- }
- i--;
- }
- score -= separators * 5;
- return Math.max(1, score);
- }
- function fuzzyMatch() {
- if (valueLength <= queryLength || value.indexOf(query) >= 0) {
- return;
- }
- if (!(match = fuzzyRegexp.exec(value))) {
- return;
- }
- matchIndex = match.index;
- matchLength = match[0].length;
- score = scoreFuzzyMatch();
- if (
- (match = fuzzyRegexp.exec(
- value.slice((i = value.lastIndexOf(SEPARATOR) + 1)),
- ))
- ) {
- matchIndex = i + match.index;
- matchLength = match[0].length;
- return Math.max(score, scoreFuzzyMatch());
- } else {
- return score;
- }
- }
- function scoreFuzzyMatch() {
- // When the match is at the beginning of the string or preceded by a dot.
- if (matchIndex === 0 || value.charAt(matchIndex - 1) === SEPARATOR) {
- return Math.max(66, 100 - matchLength);
- // When the match is at the end of the string.
- } else if (matchIndex + matchLength === valueLength) {
- return Math.max(33, 67 - matchLength);
- // When the match is in the middle of the string.
- } else {
- return Math.max(1, 34 - matchLength);
- }
- }
- //
- // Searchers
- //
- (function () {
- let CHUNK_SIZE = undefined;
- let DEFAULTS = undefined;
- let SEPARATORS_REGEXP = undefined;
- let EOS_SEPARATORS_REGEXP = undefined;
- let INFO_PARANTHESES_REGEXP = undefined;
- let EMPTY_PARANTHESES_REGEXP = undefined;
- let EVENT_REGEXP = undefined;
- let DOT_REGEXP = undefined;
- let WHITESPACE_REGEXP = undefined;
- let EMPTY_STRING = undefined;
- let ELLIPSIS = undefined;
- let STRING = undefined;
- app.Searcher = class Searcher {
- static initClass() {
- $.extend(this.prototype, Events);
- CHUNK_SIZE = 20000;
- DEFAULTS = {
- max_results: app.config.max_results,
- fuzzy_min_length: 3,
- };
- SEPARATORS_REGEXP =
- /#|::|:-|->|\$(?=\w)|\-(?=\w)|\:(?=\w)|\ [\/\-&]\ |:\ |\ /g;
- EOS_SEPARATORS_REGEXP = /(\w)[\-:]$/;
- INFO_PARANTHESES_REGEXP = /\ \(\w+?\)$/;
- EMPTY_PARANTHESES_REGEXP = /\(\)/;
- EVENT_REGEXP = /\ event$/;
- DOT_REGEXP = /\.+/g;
- WHITESPACE_REGEXP = /\s/g;
- EMPTY_STRING = "";
- ELLIPSIS = "...";
- STRING = "string";
- }
- static normalizeString(string) {
- return string
- .toLowerCase()
- .replace(ELLIPSIS, EMPTY_STRING)
- .replace(EVENT_REGEXP, EMPTY_STRING)
- .replace(INFO_PARANTHESES_REGEXP, EMPTY_STRING)
- .replace(SEPARATORS_REGEXP, SEPARATOR)
- .replace(DOT_REGEXP, SEPARATOR)
- .replace(EMPTY_PARANTHESES_REGEXP, EMPTY_STRING)
- .replace(WHITESPACE_REGEXP, EMPTY_STRING);
- }
- static normalizeQuery(string) {
- string = this.normalizeString(string);
- return string.replace(EOS_SEPARATORS_REGEXP, "$1.");
- }
- constructor(options) {
- this.match = this.match.bind(this);
- this.matchChunks = this.matchChunks.bind(this);
- if (options == null) {
- options = {};
- }
- this.options = $.extend({}, DEFAULTS, options);
- }
- find(data, attr, q) {
- this.kill();
- this.data = data;
- this.attr = attr;
- this.query = q;
- this.setup();
- if (this.isValid()) {
- this.match();
- } else {
- this.end();
- }
- }
- setup() {
- query = this.query = this.constructor.normalizeQuery(this.query);
- queryLength = query.length;
- this.dataLength = this.data.length;
- this.matchers = [exactMatch];
- this.totalResults = 0;
- this.setupFuzzy();
- }
- setupFuzzy() {
- if (queryLength >= this.options.fuzzy_min_length) {
- fuzzyRegexp = this.queryToFuzzyRegexp(query);
- this.matchers.push(fuzzyMatch);
- } else {
- fuzzyRegexp = null;
- }
- }
- isValid() {
- return queryLength > 0 && query !== SEPARATOR;
- }
- end() {
- if (!this.totalResults) {
- this.triggerResults([]);
- }
- this.trigger("end");
- this.free();
- }
- kill() {
- if (this.timeout) {
- clearTimeout(this.timeout);
- this.free();
- }
- }
- free() {
- this.data =
- this.attr =
- this.dataLength =
- this.matchers =
- this.matcher =
- this.query =
- this.totalResults =
- this.scoreMap =
- this.cursor =
- this.timeout =
- null;
- }
- match() {
- if (!this.foundEnough() && (this.matcher = this.matchers.shift())) {
- this.setupMatcher();
- this.matchChunks();
- } else {
- this.end();
- }
- }
- setupMatcher() {
- this.cursor = 0;
- this.scoreMap = new Array(101);
- }
- matchChunks() {
- this.matchChunk();
- if (this.cursor === this.dataLength || this.scoredEnough()) {
- this.delay(this.match);
- this.sendResults();
- } else {
- this.delay(this.matchChunks);
- }
- }
- matchChunk() {
- ({ matcher } = this);
- for (
- let j = 0, end = this.chunkSize(), asc = 0 <= end;
- asc ? j < end : j > end;
- asc ? j++ : j--
- ) {
- value = this.data[this.cursor][this.attr];
- if (value.split) {
- // string
- valueLength = value.length;
- if ((score = matcher())) {
- this.addResult(this.data[this.cursor], score);
- }
- } else {
- // array
- score = 0;
- for (value of Array.from(this.data[this.cursor][this.attr])) {
- valueLength = value.length;
- score = Math.max(score, matcher() || 0);
- }
- if (score > 0) {
- this.addResult(this.data[this.cursor], score);
- }
- }
- this.cursor++;
- }
- }
- chunkSize() {
- if (this.cursor + CHUNK_SIZE > this.dataLength) {
- return this.dataLength % CHUNK_SIZE;
- } else {
- return CHUNK_SIZE;
- }
- }
- scoredEnough() {
- return (
- (this.scoreMap[100] != null ? this.scoreMap[100].length : undefined) >=
- this.options.max_results
- );
- }
- foundEnough() {
- return this.totalResults >= this.options.max_results;
- }
- addResult(object, score) {
- let name;
- (
- this.scoreMap[(name = Math.round(score))] || (this.scoreMap[name] = [])
- ).push(object);
- this.totalResults++;
- }
- getResults() {
- const results = [];
- for (let j = this.scoreMap.length - 1; j >= 0; j--) {
- var objects = this.scoreMap[j];
- if (objects) {
- results.push.apply(results, objects);
- }
- }
- return results.slice(0, this.options.max_results);
- }
- sendResults() {
- const results = this.getResults();
- if (results.length) {
- this.triggerResults(results);
- }
- }
- triggerResults(results) {
- this.trigger("results", results);
- }
- delay(fn) {
- return (this.timeout = setTimeout(fn, 1));
- }
- queryToFuzzyRegexp(string) {
- const chars = string.split("");
- for (i = 0; i < chars.length; i++) {
- var char = chars[i];
- chars[i] = $.escapeRegexp(char);
- }
- return new RegExp(chars.join(".*?"));
- }
- };
- app.Searcher.initClass();
- return app.Searcher; // abc -> /a.*?b.*?c.*?/
- })();
- app.SynchronousSearcher = class SynchronousSearcher extends app.Searcher {
- constructor(...args) {
- this.match = this.match.bind(this);
- super(...args);
- }
- match() {
- if (this.matcher) {
- if (!this.allResults) {
- this.allResults = [];
- }
- this.allResults.push.apply(this.allResults, this.getResults());
- }
- return super.match(...arguments);
- }
- free() {
- this.allResults = null;
- return super.free(...arguments);
- }
- end() {
- this.sendResults(true);
- return super.end(...arguments);
- }
- sendResults(end) {
- if (end && (this.allResults != null ? this.allResults.length : undefined)) {
- return this.triggerResults(this.allResults);
- }
- }
- delay(fn) {
- return fn();
- }
- };
|