Unified · Split
| @@ -1,16 +1,3 @@ | ||
| 1 | −// TODO: This file was created by bulk-decaffeinate. | |
| 2 | −// Sanity-check the conversion and remove this comment. | |
| 3 | −/* | |
| 4 | − * decaffeinate suggestions: | |
| 5 | − * DS101: Remove unnecessary use of Array.from | |
| 6 | − * DS102: Remove unnecessary code created because of implicit returns | |
| 7 | − * DS104: Avoid inline assignments | |
| 8 | − * DS202: Simplify dynamic range loops | |
| 9 | − * DS206: Consider reworking classes to avoid initClass | |
| 10 | − * DS207: Consider shorter variations of null checks | |
| 11 | − * DS209: Avoid top-level return | |
| 12 | − * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md | |
| 13 | − */ | |
| 14 | 1 | // |
| 15 | 2 | // Match functions |
| 16 | 3 | // |
| @@ -158,249 +145,226 @@ function scoreFuzzyMatch() { · 141 unmodified lines | ||
| 158 | 145 | // Searchers |
| 159 | 146 | // |
| 160 | 147 | |
| 161 | −(function () { | |
| 162 | − let CHUNK_SIZE = undefined; | |
| 163 | − let DEFAULTS = undefined; | |
| 164 | − let SEPARATORS_REGEXP = undefined; | |
| 165 | − let EOS_SEPARATORS_REGEXP = undefined; | |
| 166 | − let INFO_PARANTHESES_REGEXP = undefined; | |
| 167 | − let EMPTY_PARANTHESES_REGEXP = undefined; | |
| 168 | − let EVENT_REGEXP = undefined; | |
| 169 | − let DOT_REGEXP = undefined; | |
| 170 | − let WHITESPACE_REGEXP = undefined; | |
| 171 | − let EMPTY_STRING = undefined; | |
| 172 | − let ELLIPSIS = undefined; | |
| 173 | − let STRING = undefined; | |
| 174 | − app.Searcher = class Searcher extends Events { | |
| 175 | − static initClass() { | |
| 176 | − CHUNK_SIZE = 20000; | |
| 177 | − | |
| 178 | − DEFAULTS = { | |
| 179 | − max_results: app.config.max_results, | |
| 180 | − fuzzy_min_length: 3, | |
| 181 | − }; | |
| 182 | − | |
| 183 | − SEPARATORS_REGEXP = | |
| 184 | − /#|::|:-|->|\$(?=\w)|\-(?=\w)|\:(?=\w)|\ [\/\-&]\ |:\ |\ /g; | |
| 185 | − EOS_SEPARATORS_REGEXP = /(\w)[\-:]$/; | |
| 186 | − INFO_PARANTHESES_REGEXP = /\ \(\w+?\)$/; | |
| 187 | − EMPTY_PARANTHESES_REGEXP = /\(\)/; | |
| 188 | − EVENT_REGEXP = /\ event$/; | |
| 189 | − DOT_REGEXP = /\.+/g; | |
| 190 | − WHITESPACE_REGEXP = /\s/g; | |
| 191 | − | |
| 192 | − EMPTY_STRING = ""; | |
| 193 | − ELLIPSIS = "..."; | |
| 194 | − STRING = "string"; | |
| 195 | − } | |
| 148 | +app.Searcher = class Searcher extends Events { | |
| 149 | + static CHUNK_SIZE = 20000; | |
| 196 | 150 | |
| 197 | − static normalizeString(string) { | |
| 198 | − return string | |
| 199 | − .toLowerCase() | |
| 200 | − .replace(ELLIPSIS, EMPTY_STRING) | |
| 201 | − .replace(EVENT_REGEXP, EMPTY_STRING) | |
| 202 | − .replace(INFO_PARANTHESES_REGEXP, EMPTY_STRING) | |
| 203 | − .replace(SEPARATORS_REGEXP, SEPARATOR) | |
| 204 | − .replace(DOT_REGEXP, SEPARATOR) | |
| 205 | − .replace(EMPTY_PARANTHESES_REGEXP, EMPTY_STRING) | |
| 206 | − .replace(WHITESPACE_REGEXP, EMPTY_STRING); | |
| 207 | − } | |
| 151 | + static DEFAULTS = { | |
| 152 | + max_results: app.config.max_results, | |
| 153 | + fuzzy_min_length: 3, | |
| 154 | + }; | |
| 208 | 155 | |
| 209 | − static normalizeQuery(string) { | |
| 210 | − string = this.normalizeString(string); | |
| 211 | − return string.replace(EOS_SEPARATORS_REGEXP, "$1."); | |
| 212 | − } | |
| 156 | + static SEPARATORS_REGEXP = | |
| 157 | + /#|::|:-|->|\$(?=\w)|\-(?=\w)|\:(?=\w)|\ [\/\-&]\ |:\ |\ /g; | |
| 158 | + static EOS_SEPARATORS_REGEXP = /(\w)[\-:]$/; | |
| 159 | + static INFO_PARANTHESES_REGEXP = /\ \(\w+?\)$/; | |
| 160 | + static EMPTY_PARANTHESES_REGEXP = /\(\)/; | |
| 161 | + static EVENT_REGEXP = /\ event$/; | |
| 162 | + static DOT_REGEXP = /\.+/g; | |
| 163 | + static WHITESPACE_REGEXP = /\s/g; | |
| 164 | + | |
| 165 | + static EMPTY_STRING = ""; | |
| 166 | + static ELLIPSIS = "..."; | |
| 167 | + static STRING = "string"; | |
| 168 | + | |
| 169 | + static normalizeString(string) { | |
| 170 | + return string | |
| 171 | + .toLowerCase() | |
| 172 | + .replace(Searcher.ELLIPSIS, Searcher.EMPTY_STRING) | |
| 173 | + .replace(Searcher.EVENT_REGEXP, Searcher.EMPTY_STRING) | |
| 174 | + .replace(Searcher.INFO_PARANTHESES_REGEXP, Searcher.EMPTY_STRING) | |
| 175 | + .replace(Searcher.SEPARATORS_REGEXP, SEPARATOR) | |
| 176 | + .replace(Searcher.DOT_REGEXP, SEPARATOR) | |
| 177 | + .replace(Searcher.EMPTY_PARANTHESES_REGEXP, Searcher.EMPTY_STRING) | |
| 178 | + .replace(Searcher.WHITESPACE_REGEXP, Searcher.EMPTY_STRING); | |
| 179 | + } | |
| 213 | 180 | |
| 214 | − constructor(options) { | |
| 215 | − super(); | |
| 216 | − this.options = $.extend({}, DEFAULTS, options || {}); | |
| 217 | − } | |
| 181 | + static normalizeQuery(string) { | |
| 182 | + string = this.normalizeString(string); | |
| 183 | + return string.replace(Searcher.EOS_SEPARATORS_REGEXP, "$1."); | |
| 184 | + } | |
| 218 | 185 | |
| 219 | − find(data, attr, q) { | |
| 220 | − this.kill(); | |
| 186 | + constructor(options) { | |
| 187 | + super(); | |
| 188 | + this.options = $.extend({}, Searcher.DEFAULTS, options || {}); | |
| 189 | + } | |
| 221 | 190 | |
| 222 | − this.data = data; | |
| 223 | − this.attr = attr; | |
| 224 | − this.query = q; | |
| 225 | − this.setup(); | |
| 191 | + find(data, attr, q) { | |
| 192 | + this.kill(); | |
| 226 | 193 | |
| 227 | − if (this.isValid()) { | |
| 228 | − this.match(); | |
| 229 | − } else { | |
| 230 | − this.end(); | |
| 231 | − } | |
| 232 | − } | |
| 194 | + this.data = data; | |
| 195 | + this.attr = attr; | |
| 196 | + this.query = q; | |
| 197 | + this.setup(); | |
| 233 | 198 | |
| 234 | − setup() { | |
| 235 | − query = this.query = this.constructor.normalizeQuery(this.query); | |
| 236 | − queryLength = query.length; | |
| 237 | − this.dataLength = this.data.length; | |
| 238 | − this.matchers = [exactMatch]; | |
| 239 | − this.totalResults = 0; | |
| 240 | − this.setupFuzzy(); | |
| 199 | + if (this.isValid()) { | |
| 200 | + this.match(); | |
| 201 | + } else { | |
| 202 | + this.end(); | |
| 241 | 203 | } |
| 204 | + } | |
| 242 | 205 | |
| 243 | − setupFuzzy() { | |
| 244 | − if (queryLength >= this.options.fuzzy_min_length) { | |
| 245 | − fuzzyRegexp = this.queryToFuzzyRegexp(query); | |
| 246 | − this.matchers.push(fuzzyMatch); | |
| 247 | − } else { | |
| 248 | − fuzzyRegexp = null; | |
| 249 | − } | |
| 250 | − } | |
| 206 | + setup() { | |
| 207 | + query = this.query = this.constructor.normalizeQuery(this.query); | |
| 208 | + queryLength = query.length; | |
| 209 | + this.dataLength = this.data.length; | |
| 210 | + this.matchers = [exactMatch]; | |
| 211 | + this.totalResults = 0; | |
| 212 | + this.setupFuzzy(); | |
| 213 | + } | |
| 251 | 214 | |
| 252 | − isValid() { | |
| 253 | − return queryLength > 0 && query !== SEPARATOR; | |
| 215 | + setupFuzzy() { | |
| 216 | + if (queryLength >= this.options.fuzzy_min_length) { | |
| 217 | + fuzzyRegexp = this.queryToFuzzyRegexp(query); | |
| 218 | + this.matchers.push(fuzzyMatch); | |
| 219 | + } else { | |
| 220 | + fuzzyRegexp = null; | |
| 254 | 221 | } |
| 222 | + } | |
| 255 | 223 | |
| 256 | − end() { | |
| 257 | − if (!this.totalResults) { | |
| 258 | − this.triggerResults([]); | |
| 259 | − } | |
| 260 | − this.trigger("end"); | |
| 261 | − this.free(); | |
| 262 | − } | |
| 224 | + isValid() { | |
| 225 | + return queryLength > 0 && query !== SEPARATOR; | |
| 226 | + } | |
| 263 | 227 | |
| 264 | − kill() { | |
| 265 | − if (this.timeout) { | |
| 266 | − clearTimeout(this.timeout); | |
| 267 | − this.free(); | |
| 268 | − } | |
| 228 | + end() { | |
| 229 | + if (!this.totalResults) { | |
| 230 | + this.triggerResults([]); | |
| 269 | 231 | } |
| 232 | + this.trigger("end"); | |
| 233 | + this.free(); | |
| 234 | + } | |
| 270 | 235 | |
| 271 | − free() { | |
| 272 | − this.data = | |
| 273 | − this.attr = | |
| 274 | − this.dataLength = | |
| 275 | − this.matchers = | |
| 276 | − this.matcher = | |
| 277 | − this.query = | |
| 278 | − this.totalResults = | |
| 279 | − this.scoreMap = | |
| 280 | − this.cursor = | |
| 281 | − this.timeout = | |
| 282 | − null; | |
| 236 | + kill() { | |
| 237 | + if (this.timeout) { | |
| 238 | + clearTimeout(this.timeout); | |
| 239 | + this.free(); | |
| 283 | 240 | } |
| 241 | + } | |
| 284 | 242 | |
| 285 | − match() { | |
| 286 | − if (!this.foundEnough() && (this.matcher = this.matchers.shift())) { | |
| 287 | − this.setupMatcher(); | |
| 288 | − this.matchChunks(); | |
| 289 | − } else { | |
| 290 | − this.end(); | |
| 291 | − } | |
| 292 | − } | |
| 243 | + free() { | |
| 244 | + this.data = null; | |
| 245 | + this.attr = null; | |
| 246 | + this.dataLength = null; | |
| 247 | + this.matchers = null; | |
| 248 | + this.matcher = null; | |
| 249 | + this.query = null; | |
| 250 | + this.totalResults = null; | |
| 251 | + this.scoreMap = null; | |
| 252 | + this.cursor = null; | |
| 253 | + this.timeout = null; | |
| 254 | + } | |
| 293 | 255 | |
| 294 | − setupMatcher() { | |
| 295 | − this.cursor = 0; | |
| 296 | − this.scoreMap = new Array(101); | |
| 256 | + match() { | |
| 257 | + if (!this.foundEnough() && (this.matcher = this.matchers.shift())) { | |
| 258 | + this.setupMatcher(); | |
| 259 | + this.matchChunks(); | |
| 260 | + } else { | |
| 261 | + this.end(); | |
| 297 | 262 | } |
| 263 | + } | |
| 298 | 264 | |
| 299 | − matchChunks() { | |
| 300 | − this.matchChunk(); | |
| 265 | + setupMatcher() { | |
| 266 | + this.cursor = 0; | |
| 267 | + this.scoreMap = new Array(101); | |
| 268 | + } | |
| 301 | 269 | |
| 302 | − if (this.cursor === this.dataLength || this.scoredEnough()) { | |
| 303 | − this.delay(() => this.match()); | |
| 304 | − this.sendResults(); | |
| 305 | − } else { | |
| 306 | − this.delay(() => this.matchChunks()); | |
| 307 | − } | |
| 270 | + matchChunks() { | |
| 271 | + this.matchChunk(); | |
| 272 | + | |
| 273 | + if (this.cursor === this.dataLength || this.scoredEnough()) { | |
| 274 | + this.delay(() => this.match()); | |
| 275 | + this.sendResults(); | |
| 276 | + } else { | |
| 277 | + this.delay(() => this.matchChunks()); | |
| 308 | 278 | } |
| 279 | + } | |
| 309 | 280 | |
| 310 | − matchChunk() { | |
| 311 | − ({ matcher } = this); | |
| 312 | − for ( | |
| 313 | − let j = 0, end = this.chunkSize(), asc = 0 <= end; | |
| 314 | − asc ? j < end : j > end; | |
| 315 | − asc ? j++ : j-- | |
| 316 | − ) { | |
| 317 | − value = this.data[this.cursor][this.attr]; | |
| 318 | − if (value.split) { | |
| 319 | − // string | |
| 281 | + matchChunk() { | |
| 282 | + ({ matcher } = this); | |
| 283 | + for (let j = 0, end = this.chunkSize(); j < end; j++) { | |
| 284 | + value = this.data[this.cursor][this.attr]; | |
| 285 | + if (value.split) { | |
| 286 | + // string | |
| 287 | + valueLength = value.length; | |
| 288 | + if ((score = matcher())) { | |
| 289 | + this.addResult(this.data[this.cursor], score); | |
| 290 | + } | |
| 291 | + } else { | |
| 292 | + // array | |
| 293 | + score = 0; | |
| 294 | + for (value of Array.from(this.data[this.cursor][this.attr])) { | |
| 320 | 295 | valueLength = value.length; |
| 321 | − if ((score = matcher())) { | |
| 322 | − this.addResult(this.data[this.cursor], score); | |
| 323 | − } | |
| 324 | − } else { | |
| 325 | − // array | |
| 326 | − score = 0; | |
| 327 | − for (value of Array.from(this.data[this.cursor][this.attr])) { | |
| 328 | − valueLength = value.length; | |
| 329 | − score = Math.max(score, matcher() || 0); | |
| 330 | − } | |
| 331 | − if (score > 0) { | |
| 332 | − this.addResult(this.data[this.cursor], score); | |
| 333 | − } | |
| 296 | + score = Math.max(score, matcher() || 0); | |
| 297 | + } | |
| 298 | + if (score > 0) { | |
| 299 | + this.addResult(this.data[this.cursor], score); | |
| 334 | 300 | } |
| 335 | − this.cursor++; | |
| 336 | 301 | } |
| 302 | + this.cursor++; | |
| 337 | 303 | } |
| 304 | + } | |
| 338 | 305 | |
| 339 | − chunkSize() { | |
| 340 | − if (this.cursor + CHUNK_SIZE > this.dataLength) { | |
| 341 | − return this.dataLength % CHUNK_SIZE; | |
| 342 | − } else { | |
| 343 | − return CHUNK_SIZE; | |
| 344 | − } | |
| 306 | + chunkSize() { | |
| 307 | + if (this.cursor + Searcher.CHUNK_SIZE > this.dataLength) { | |
| 308 | + return this.dataLength % Searcher.CHUNK_SIZE; | |
| 309 | + } else { | |
| 310 | + return Searcher.CHUNK_SIZE; | |
| 345 | 311 | } |
| 312 | + } | |
| 346 | 313 | |
| 347 | − scoredEnough() { | |
| 348 | − return ( | |
| 349 | − (this.scoreMap[100] != null ? this.scoreMap[100].length : undefined) >= | |
| 350 | − this.options.max_results | |
| 351 | − ); | |
| 352 | − } | |
| 314 | + scoredEnough() { | |
| 315 | + return ( | |
| 316 | + (this.scoreMap[100] != null ? this.scoreMap[100].length : undefined) >= | |
| 317 | + this.options.max_results | |
| 318 | + ); | |
| 319 | + } | |
| 353 | 320 | |
| 354 | − foundEnough() { | |
| 355 | − return this.totalResults >= this.options.max_results; | |
| 356 | − } | |
| 321 | + foundEnough() { | |
| 322 | + return this.totalResults >= this.options.max_results; | |
| 323 | + } | |
| 357 | 324 | |
| 358 | − addResult(object, score) { | |
| 359 | − let name; | |
| 360 | − ( | |
| 361 | − this.scoreMap[(name = Math.round(score))] || (this.scoreMap[name] = []) | |
| 362 | − ).push(object); | |
| 363 | − this.totalResults++; | |
| 364 | − } | |
| 325 | + addResult(object, score) { | |
| 326 | + let name; | |
| 327 | + ( | |
| 328 | + this.scoreMap[(name = Math.round(score))] || (this.scoreMap[name] = []) | |
| 329 | + ).push(object); | |
| 330 | + this.totalResults++; | |
| 331 | + } | |
| 365 | 332 | |
| 366 | − getResults() { | |
| 367 | − const results = []; | |
| 368 | − for (let j = this.scoreMap.length - 1; j >= 0; j--) { | |
| 369 | − var objects = this.scoreMap[j]; | |
| 370 | − if (objects) { | |
| 371 | − results.push.apply(results, objects); | |
| 372 | − } | |
| 333 | + getResults() { | |
| 334 | + const results = []; | |
| 335 | + for (let j = this.scoreMap.length - 1; j >= 0; j--) { | |
| 336 | + var objects = this.scoreMap[j]; | |
| 337 | + if (objects) { | |
| 338 | + results.push.apply(results, objects); | |
| 373 | 339 | } |
| 374 | − return results.slice(0, this.options.max_results); | |
| 375 | 340 | } |
| 341 | + return results.slice(0, this.options.max_results); | |
| 342 | + } | |
| 376 | 343 | |
| 377 | − sendResults() { | |
| 378 | − const results = this.getResults(); | |
| 379 | − if (results.length) { | |
| 380 | − this.triggerResults(results); | |
| 381 | − } | |
| 344 | + sendResults() { | |
| 345 | + const results = this.getResults(); | |
| 346 | + if (results.length) { | |
| 347 | + this.triggerResults(results); | |
| 382 | 348 | } |
| 349 | + } | |
| 383 | 350 | |
| 384 | − triggerResults(results) { | |
| 385 | − this.trigger("results", results); | |
| 386 | − } | |
| 351 | + triggerResults(results) { | |
| 352 | + this.trigger("results", results); | |
| 353 | + } | |
| 387 | 354 | |
| 388 | − delay(fn) { | |
| 389 | − return (this.timeout = setTimeout(fn, 1)); | |
| 390 | − } | |
| 355 | + delay(fn) { | |
| 356 | + return (this.timeout = setTimeout(fn, 1)); | |
| 357 | + } | |
| 391 | 358 | |
| 392 | − queryToFuzzyRegexp(string) { | |
| 393 | − const chars = string.split(""); | |
| 394 | − for (i = 0; i < chars.length; i++) { | |
| 395 | − var char = chars[i]; | |
| 396 | − chars[i] = $.escapeRegexp(char); | |
| 397 | − } | |
| 398 | − return new RegExp(chars.join(".*?")); // abc -> /a.*?b.*?c.*?/ | |
| 359 | + queryToFuzzyRegexp(string) { | |
| 360 | + const chars = string.split(""); | |
| 361 | + for (i = 0; i < chars.length; i++) { | |
| 362 | + var char = chars[i]; | |
| 363 | + chars[i] = $.escapeRegexp(char); | |
| 399 | 364 | } |
| 400 | − }; | |
| 401 | − app.Searcher.initClass(); | |
| 402 | − return app.Searcher; | |
| 403 | −})(); | |
| 365 | + return new RegExp(chars.join(".*?")); // abc -> /a.*?b.*?c.*?/ | |
| 366 | + } | |
| 367 | +}; | |
| 404 | 368 | |
| 405 | 369 | app.SynchronousSearcher = class SynchronousSearcher extends app.Searcher { |
| 406 | 370 | match() { |