|
349 | 349 | var valLower = query.query.toLowerCase(),
|
350 | 350 | val = valLower,
|
351 | 351 | typeFilter = itemTypeFromName(query.type),
|
352 |
| - results = [], |
| 352 | + results = {}, |
353 | 353 | split = valLower.split("::");
|
354 | 354 |
|
355 | 355 | // remove empty keywords
|
|
360 | 360 | }
|
361 | 361 | }
|
362 | 362 |
|
| 363 | + function min(a, b) { |
| 364 | + if (a < b) { |
| 365 | + return a; |
| 366 | + } |
| 367 | + return b; |
| 368 | + } |
| 369 | + |
| 370 | + function nbElements(obj) { |
| 371 | + var size = 0, key; |
| 372 | + for (key in obj) { |
| 373 | + if (obj.hasOwnProperty(key)) { |
| 374 | + size += 1; |
| 375 | + } |
| 376 | + } |
| 377 | + return size; |
| 378 | + } |
| 379 | + |
363 | 380 | function findArg(obj, val) {
|
364 | 381 | var lev_distance = MAX_LEV_DISTANCE + 1;
|
365 | 382 | if (obj && obj.type && obj.type.inputs.length > 0) {
|
|
368 | 385 | // No need to check anything else: we found it. Let's just move on.
|
369 | 386 | return 0;
|
370 | 387 | }
|
371 |
| - var tmp = levenshtein(obj.type.inputs[i].name, val); |
372 |
| - if (tmp < lev_distance) { |
373 |
| - lev_distance = tmp; |
| 388 | + lev_distance = min(levenshtein(obj.type.inputs[i].name, val), lev_distance); |
| 389 | + if (lev_distance === 0) { |
| 390 | + return 0; |
374 | 391 | }
|
375 | 392 | }
|
376 | 393 | }
|
377 | 394 | return lev_distance;
|
378 | 395 | }
|
379 | 396 |
|
380 | 397 | function checkReturned(obj, val) {
|
| 398 | + var lev_distance = MAX_LEV_DISTANCE + 1; |
381 | 399 | if (obj && obj.type && obj.type.output) {
|
382 | 400 | if (obj.type.output.name.toLowerCase() === val) {
|
383 | 401 | return 0;
|
384 | 402 | }
|
385 |
| - return levenshtein(obj.type.output.name.toLowerCase(), val); |
| 403 | + lev_distance = min(levenshtein(obj.type.output.name, val)); |
| 404 | + if (lev_distance === 0) { |
| 405 | + return 0; |
| 406 | + } |
386 | 407 | }
|
387 |
| - return MAX_LEV_DISTANCE + 1; |
| 408 | + return lev_distance; |
388 | 409 | }
|
389 | 410 |
|
390 | 411 | function typePassesFilter(filter, type) {
|
|
414 | 435 | if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
|
415 | 436 | val.charAt(val.length - 1) === val.charAt(0))
|
416 | 437 | {
|
417 |
| - val = val.substr(1, val.length - 2); |
| 438 | + val = val.substr(1, val.length - 2).toLowerCase(); |
418 | 439 | for (var i = 0; i < nSearchWords; ++i) {
|
| 440 | + var ty = searchIndex[i]; |
419 | 441 | if (searchWords[i] === val) {
|
420 | 442 | // filter type: ... queries
|
421 | 443 | if (typePassesFilter(typeFilter, searchIndex[i].ty)) {
|
422 |
| - results.push({id: i, index: -1}); |
| 444 | + results[ty.path + ty.name] = {id: i, index: -1}; |
423 | 445 | }
|
424 |
| - } else if (findArg(searchIndex[i], val.toLowerCase()) || |
425 |
| - (searchIndex[i].type && |
426 |
| - searchIndex[i].type.output && |
427 |
| - searchIndex[i].type.output.name === val.toLowerCase())) { |
| 446 | + } else if (findArg(searchIndex[i], val) || |
| 447 | + (ty.type && |
| 448 | + ty.type.output && |
| 449 | + ty.type.output.name === val)) { |
428 | 450 | if (typePassesFilter(typeFilter, searchIndex[i].ty)) {
|
429 |
| - results.push({id: i, index: -1, dontValidate: true}); |
| 451 | + results[ty.path + ty.name] = { |
| 452 | + id: i, |
| 453 | + index: -1, |
| 454 | + dontValidate: true, |
| 455 | + }; |
430 | 456 | }
|
431 | 457 | }
|
432 |
| - if (results.length === max) { |
| 458 | + if (nbElements(results) === max) { |
433 | 459 | break;
|
434 | 460 | }
|
435 | 461 | }
|
|
447 | 473 |
|
448 | 474 | for (var i = 0; i < nSearchWords; ++i) {
|
449 | 475 | var type = searchIndex[i].type;
|
| 476 | + var ty = searchIndex[i]; |
450 | 477 | if (!type) {
|
451 | 478 | continue;
|
452 | 479 | }
|
|
460 | 487 | var typeOutput = type.output ? type.output.name : "";
|
461 | 488 | if (output === "*" || output == typeOutput) {
|
462 | 489 | if (input === "*") {
|
463 |
| - results.push({id: i, index: -1, dontValidate: true}); |
| 490 | + results[ty.path + ty.name] = {id: i, index: -1, dontValidate: true}; |
464 | 491 | } else {
|
465 | 492 | var allFound = true;
|
466 | 493 | for (var it = 0; allFound === true && it < inputs.length; it++) {
|
|
471 | 498 | allFound = found;
|
472 | 499 | }
|
473 | 500 | if (allFound === true) {
|
474 |
| - results.push({id: i, index: -1, dontValidate: true}); |
| 501 | + results[ty.path + ty.name] = { |
| 502 | + id: i, |
| 503 | + index: -1, |
| 504 | + dontValidate: true, |
| 505 | + }; |
475 | 506 | }
|
476 | 507 | }
|
477 | 508 | }
|
|
487 | 518 | for (var i = 0; i < split.length; ++i) {
|
488 | 519 | for (var j = 0; j < nSearchWords; ++j) {
|
489 | 520 | var lev_distance;
|
| 521 | + var ty = searchIndex[j]; |
| 522 | + if (!ty) { |
| 523 | + continue; |
| 524 | + } |
490 | 525 | if (searchWords[j].indexOf(split[i]) > -1 ||
|
491 | 526 | searchWords[j].indexOf(val) > -1 ||
|
492 | 527 | searchWords[j].replace(/_/g, "").indexOf(val) > -1)
|
493 | 528 | {
|
494 | 529 | // filter type: ... queries
|
495 | 530 | if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
|
496 |
| - results.push({ |
| 531 | + results[ty.path + ty.name] = { |
497 | 532 | id: j,
|
498 | 533 | index: searchWords[j].replace(/_/g, "").indexOf(val),
|
499 | 534 | lev: 0,
|
500 |
| - }); |
| 535 | + }; |
501 | 536 | }
|
502 | 537 | } else if (
|
503 | 538 | (lev_distance = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) {
|
504 | 539 | if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
|
505 |
| - results.push({ |
506 |
| - id: j, |
507 |
| - index: 0, |
508 |
| - // we want lev results to go lower than others |
509 |
| - lev: lev_distance, |
510 |
| - }); |
| 540 | + if (results[ty.path + ty.name] === undefined || |
| 541 | + results[ty.path + ty.name].lev > lev_distance) { |
| 542 | + results[ty.path + ty.name] = { |
| 543 | + id: j, |
| 544 | + index: 0, |
| 545 | + // we want lev results to go lower than others |
| 546 | + lev: lev_distance, |
| 547 | + }; |
| 548 | + } |
511 | 549 | }
|
512 | 550 | } else if (
|
513 | 551 | (lev_distance = findArg(searchIndex[j], val)) <= MAX_LEV_DISTANCE) {
|
514 | 552 | if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
|
515 |
| - results.push({ |
516 |
| - id: j, |
517 |
| - index: 0, |
518 |
| - // we want lev results to go lower than others |
519 |
| - lev: lev_distance, |
520 |
| - }); |
| 553 | + if (results[ty.path + ty.name] === undefined || |
| 554 | + results[ty.path + ty.name].lev > lev_distance) { |
| 555 | + results[ty.path + ty.name] = { |
| 556 | + id: j, |
| 557 | + index: 0, |
| 558 | + // we want lev results to go lower than others |
| 559 | + lev: lev_distance, |
| 560 | + }; |
| 561 | + } |
521 | 562 | }
|
522 | 563 | } else if (
|
523 | 564 | (lev_distance = checkReturned(searchIndex[j], val)) <=
|
524 | 565 | MAX_LEV_DISTANCE) {
|
525 | 566 | if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
|
526 |
| - results.push({ |
527 |
| - id: j, |
528 |
| - index: 0, |
529 |
| - // we want lev results to go lower than others |
530 |
| - lev: lev_distance, |
531 |
| - }); |
| 567 | + if (results[ty.path + ty.name] === undefined || |
| 568 | + results[ty.path + ty.name].lev > lev_distance) { |
| 569 | + results[ty.path + ty.name] = { |
| 570 | + id: j, |
| 571 | + index: 0, |
| 572 | + // we want lev results to go lower than others |
| 573 | + lev: lev_distance, |
| 574 | + }; |
| 575 | + } |
532 | 576 | }
|
533 | 577 | }
|
534 |
| - if (results.length === max) { |
| 578 | + if (nbElements(results) === max) { |
535 | 579 | break;
|
536 | 580 | }
|
537 | 581 | }
|
538 | 582 | }
|
539 | 583 | }
|
540 | 584 |
|
| 585 | + var ar = []; |
| 586 | + for (var entry in results) { |
| 587 | + if (results.hasOwnProperty(entry)) { |
| 588 | + ar.push(results[entry]); |
| 589 | + } |
| 590 | + } |
| 591 | + results = ar; |
541 | 592 | var nresults = results.length;
|
542 | 593 | for (var i = 0; i < nresults; ++i) {
|
543 | 594 | results[i].word = searchWords[results[i].id];
|
|
613 | 664 | return 0;
|
614 | 665 | });
|
615 | 666 |
|
616 |
| - // remove duplicates, according to the data provided |
617 |
| - for (var i = results.length - 1; i > 0; i -= 1) { |
618 |
| - if (results[i].word === results[i - 1].word && |
619 |
| - results[i].item.ty === results[i - 1].item.ty && |
620 |
| - results[i].item.path === results[i - 1].item.path && |
621 |
| - (results[i].item.parent || {}).name === (results[i - 1].item.parent || {}).name) |
622 |
| - { |
623 |
| - results[i].id = -1; |
624 |
| - } |
625 |
| - } |
626 | 667 | for (var i = 0; i < results.length; ++i) {
|
627 | 668 | var result = results[i],
|
628 | 669 | name = result.item.name.toLowerCase(),
|
|
0 commit comments