Skip to content

Commit 3bde5e7

Browse files
committedNov 28, 2017
Auto merge of #46175 - GuillaumeGomez:fix-global-search, r=QuietMisdreavus
Fix global search Fixes #46021. r? @QuietMisdreavus
·
1.90.01.24.0
2 parents 436ac89 + 0a12198 commit 3bde5e7

File tree

1 file changed

+227
-227
lines changed

1 file changed

+227
-227
lines changed
 

‎src/librustdoc/html/static/main.js‎

Lines changed: 227 additions & 227 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@
352352
function initSearch(rawSearchIndex) {
353353
var currentResults, index, searchIndex;
354354
var MAX_LEV_DISTANCE = 3;
355+
var MAX_RESULTS = 200;
355356
var params = getQueryStringParams();
356357

357358
// Populate search bar with query string search term when provided,
@@ -374,7 +375,7 @@
374375
var valLower = query.query.toLowerCase(),
375376
val = valLower,
376377
typeFilter = itemTypeFromName(query.type),
377-
results = {},
378+
results = {}, results_in_args = {}, results_returned = {},
378379
split = valLower.split("::");
379380

380381
for (var z = 0; z < split.length; ++z) {
@@ -384,6 +385,126 @@
384385
}
385386
}
386387

388+
function transformResults(results, isType) {
389+
var out = [];
390+
for (i = 0; i < results.length; ++i) {
391+
if (results[i].id > -1) {
392+
var obj = searchIndex[results[i].id];
393+
obj.lev = results[i].lev;
394+
if (isType !== true || obj.type) {
395+
out.push(obj);
396+
}
397+
}
398+
if (out.length >= MAX_RESULTS) {
399+
break;
400+
}
401+
}
402+
return out;
403+
}
404+
405+
function sortResults(results, isType) {
406+
var ar = [];
407+
for (var entry in results) {
408+
if (results.hasOwnProperty(entry)) {
409+
ar.push(results[entry]);
410+
}
411+
}
412+
results = ar;
413+
var nresults = results.length;
414+
for (var i = 0; i < nresults; ++i) {
415+
results[i].word = searchWords[results[i].id];
416+
results[i].item = searchIndex[results[i].id] || {};
417+
}
418+
// if there are no results then return to default and fail
419+
if (results.length === 0) {
420+
return [];
421+
}
422+
423+
results.sort(function(aaa, bbb) {
424+
var a, b;
425+
426+
// Sort by non levenshtein results and then levenshtein results by the distance
427+
// (less changes required to match means higher rankings)
428+
a = (aaa.lev);
429+
b = (bbb.lev);
430+
if (a !== b) { return a - b; }
431+
432+
// sort by crate (non-current crate goes later)
433+
a = (aaa.item.crate !== window.currentCrate);
434+
b = (bbb.item.crate !== window.currentCrate);
435+
if (a !== b) { return a - b; }
436+
437+
// sort by exact match (mismatch goes later)
438+
a = (aaa.word !== valLower);
439+
b = (bbb.word !== valLower);
440+
if (a !== b) { return a - b; }
441+
442+
// sort by item name length (longer goes later)
443+
a = aaa.word.length;
444+
b = bbb.word.length;
445+
if (a !== b) { return a - b; }
446+
447+
// sort by item name (lexicographically larger goes later)
448+
a = aaa.word;
449+
b = bbb.word;
450+
if (a !== b) { return (a > b ? +1 : -1); }
451+
452+
// sort by index of keyword in item name (no literal occurrence goes later)
453+
a = (aaa.index < 0);
454+
b = (bbb.index < 0);
455+
if (a !== b) { return a - b; }
456+
// (later literal occurrence, if any, goes later)
457+
a = aaa.index;
458+
b = bbb.index;
459+
if (a !== b) { return a - b; }
460+
461+
// special precedence for primitive pages
462+
if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
463+
return -1;
464+
}
465+
if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
466+
return 1;
467+
}
468+
469+
// sort by description (no description goes later)
470+
a = (aaa.item.desc === '');
471+
b = (bbb.item.desc === '');
472+
if (a !== b) { return a - b; }
473+
474+
// sort by type (later occurrence in `itemTypes` goes later)
475+
a = aaa.item.ty;
476+
b = bbb.item.ty;
477+
if (a !== b) { return a - b; }
478+
479+
// sort by path (lexicographically larger goes later)
480+
a = aaa.item.path;
481+
b = bbb.item.path;
482+
if (a !== b) { return (a > b ? +1 : -1); }
483+
484+
// que sera, sera
485+
return 0;
486+
});
487+
488+
for (var i = 0; i < results.length; ++i) {
489+
var result = results[i];
490+
491+
// this validation does not make sense when searching by types
492+
if (result.dontValidate) {
493+
continue;
494+
}
495+
var name = result.item.name.toLowerCase(),
496+
path = result.item.path.toLowerCase(),
497+
parent = result.item.parent;
498+
499+
if (isType !== true &&
500+
validateResult(name, path, split, parent) === false)
501+
{
502+
result.id = -1;
503+
}
504+
}
505+
return transformResults(results);
506+
}
507+
387508
function extractGenerics(val) {
388509
val = val.toLowerCase();
389510
if (val.indexOf('<') !== -1) {
@@ -404,11 +525,13 @@
404525
// match as well.
405526
var lev_distance = MAX_LEV_DISTANCE + 1;
406527
if (val.generics.length > 0) {
407-
if (obj.generics &&
408-
obj.generics.length >= val.generics.length) {
528+
if (obj.generics && obj.generics.length >= val.generics.length) {
409529
var elems = obj.generics.slice(0);
530+
var total = 0;
531+
var done = 0;
532+
// We need to find the type that matches the most to remove it in order
533+
// to move forward.
410534
for (var y = 0; y < val.generics.length; ++y) {
411-
// The point here is to find the type that matches the most.
412535
var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1};
413536
for (var x = 0; x < elems.length; ++x) {
414537
var tmp_lev = levenshtein(elems[x], val.generics[y]);
@@ -420,14 +543,14 @@
420543
if (lev.pos !== -1) {
421544
elems.splice(lev.pos, 1);
422545
lev_distance = Math.min(lev.lev, lev_distance);
546+
total += lev.lev;
547+
done += 1;
423548
} else {
424549
return MAX_LEV_DISTANCE + 1;
425550
}
426551
}
427-
return lev_distance;
552+
return lev_distance;//Math.ceil(total / done);
428553
}
429-
} else {
430-
return 0;
431554
}
432555
return MAX_LEV_DISTANCE + 1;
433556
}
@@ -463,9 +586,13 @@
463586
}
464587
// If the type has generics but don't match, then it won't return at this point.
465588
// Otherwise, `checkGenerics` will return 0 and it'll return.
466-
var tmp_lev = checkGenerics(obj, val);
467-
if (tmp_lev <= MAX_LEV_DISTANCE) {
468-
return tmp_lev;
589+
if (obj.generics && obj.generics.length !== 0) {
590+
var tmp_lev = checkGenerics(obj, val);
591+
if (tmp_lev <= MAX_LEV_DISTANCE) {
592+
return tmp_lev;
593+
}
594+
} else {
595+
return 0;
469596
}
470597
}
471598
// Names didn't match so let's check if one of the generic types could.
@@ -479,12 +606,11 @@
479606
}
480607
return false;
481608
}
482-
var new_lev = levenshtein(obj.name, val.name);
483-
if (new_lev < lev_distance) {
484-
if ((lev = checkGenerics(obj, val)) <= MAX_LEV_DISTANCE) {
485-
lev_distance = Math.min(Math.min(new_lev, lev), lev_distance);
486-
}
609+
var lev_distance = Math.min(levenshtein(obj.name, val.name), lev_distance);
610+
if (lev_distance <= MAX_LEV_DISTANCE) {
611+
lev_distance = Math.min(checkGenerics(obj, val), lev_distance);
487612
} else if (obj.generics && obj.generics.length > 0) {
613+
// We can check if the type we're looking for is inside the generics!
488614
for (var x = 0; x < obj.generics.length; ++x) {
489615
lev_distance = Math.min(levenshtein(obj.generics[x], val.name),
490616
lev_distance);
@@ -599,7 +725,6 @@
599725
if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
600726
val.charAt(val.length - 1) === val.charAt(0))
601727
{
602-
var results_length = 0;
603728
val = extractGenerics(val.substr(1, val.length - 2));
604729
for (var i = 0; i < nSearchWords; ++i) {
605730
var in_args = findArg(searchIndex[i], val, true);
@@ -613,31 +738,32 @@
613738
results[fullId] === undefined)
614739
{
615740
results[fullId] = {id: i, index: -1};
616-
results_length += 1;
617741
}
618742
} else if ((in_args === true || returned === true) &&
619743
typePassesFilter(typeFilter, searchIndex[i].ty)) {
620-
if (results[fullId] === undefined) {
744+
if (in_args === true || returned === true) {
745+
if (in_args === true) {
746+
results_in_args[fullId] = {
747+
id: i,
748+
index: -1,
749+
dontValidate: true,
750+
};
751+
}
752+
if (returned === true) {
753+
results_returned[fullId] = {
754+
id: i,
755+
index: -1,
756+
dontValidate: true,
757+
};
758+
}
759+
} else {
621760
results[fullId] = {
622761
id: i,
623762
index: -1,
624763
dontValidate: true,
625-
in_args: in_args,
626-
returned: returned,
627764
};
628-
results_length += 1;
629-
} else {
630-
if (in_args === true) {
631-
results[fullId].in_args = true;
632-
}
633-
if (returned === true) {
634-
results[fullId].returned = true;
635-
}
636765
}
637766
}
638-
if (results_length === max) {
639-
break;
640-
}
641767
}
642768
query.inputs = [val];
643769
query.output = val;
@@ -678,23 +804,26 @@
678804
}
679805
in_args = allFound;
680806
}
681-
if (in_args === true || returned === true || module === true) {
682-
if (results[fullId] !== undefined) {
683-
if (returned === true) {
684-
results[fullId].returned = true;
685-
}
686-
if (in_args === true) {
687-
results[fullId].in_args = true;
688-
}
689-
} else {
690-
results[fullId] = {
691-
id: i,
692-
index: -1,
693-
dontValidate: true,
694-
returned: returned,
695-
in_args: in_args,
696-
};
697-
}
807+
if (in_args === true) {
808+
results_in_args[fullId] = {
809+
id: i,
810+
index: -1,
811+
dontValidate: true,
812+
};
813+
}
814+
if (returned === true) {
815+
results_returned[fullId] = {
816+
id: i,
817+
index: -1,
818+
dontValidate: true,
819+
};
820+
}
821+
if (module === true) {
822+
results[fullId] = {
823+
id: i,
824+
index: -1,
825+
dontValidate: true,
826+
};
698827
}
699828
}
700829
}
@@ -709,7 +838,6 @@
709838
// gather matching search results up to a certain maximum
710839
val = val.replace(/\_/g, "");
711840

712-
var results_length = 0;
713841
var valGenerics = extractGenerics(val);
714842

715843
var paths = valLower.split("::");
@@ -739,177 +867,84 @@
739867
}
740868
}
741869

742-
var returned = false;
743-
var in_args = false;
870+
var returned = MAX_LEV_DISTANCE + 1;
871+
var in_args = MAX_LEV_DISTANCE + 1;
744872
var index = -1;
745873
// we want lev results to go lower than others
746874
var lev = MAX_LEV_DISTANCE + 1;
747875
var fullId = itemTypes[ty.ty] + ty.path + ty.name;
748876

749-
if (searchWords[j].indexOf(val) > -1 ||
877+
if (searchWords[j].indexOf(split[i]) > -1 ||
878+
searchWords[j].indexOf(val) > -1 ||
750879
searchWords[j].replace(/_/g, "").indexOf(val) > -1)
751880
{
752881
// filter type: ... queries
753-
if (typePassesFilter(typeFilter, ty) &&
754-
results[fullId] === undefined) {
882+
if (typePassesFilter(typeFilter, ty) && results[fullId] === undefined) {
755883
index = searchWords[j].replace(/_/g, "").indexOf(val);
756884
}
757885
}
758-
if ((lev_distance = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) {
759-
if (typePassesFilter(typeFilter, ty) &&
760-
(results[fullId] === undefined ||
761-
results[fullId].lev > lev_distance)) {
762-
lev = Math.min(lev, lev_distance);
763-
index = Math.max(0, index);
886+
if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) {
887+
if (typePassesFilter(typeFilter, ty) === false) {
888+
lev = MAX_LEV_DISTANCE + 1;
889+
} else {
890+
lev += 1;
764891
}
765892
}
766-
if ((lev_distance = findArg(searchIndex[j], valGenerics))
767-
<= MAX_LEV_DISTANCE) {
768-
if (typePassesFilter(typeFilter, ty) &&
769-
(results[fullId] === undefined ||
770-
results[fullId].lev > lev_distance)) {
771-
in_args = true;
772-
lev = Math.min(lev_distance, lev);
773-
index = Math.max(0, index);
893+
if ((in_args = findArg(ty, valGenerics)) <= MAX_LEV_DISTANCE) {
894+
if (typePassesFilter(typeFilter, ty) === false) {
895+
in_args = MAX_LEV_DISTANCE + 1;
774896
}
775897
}
776-
if ((lev_distance = checkReturned(searchIndex[j], valGenerics)) <=
777-
MAX_LEV_DISTANCE) {
778-
if (typePassesFilter(typeFilter, ty) &&
779-
(results[fullId] === undefined ||
780-
results[fullId].lev > lev_distance)) {
781-
returned = true;
782-
lev = Math.min(lev_distance, lev);
783-
index = Math.max(0, index);
898+
if ((returned = checkReturned(ty, valGenerics)) <= MAX_LEV_DISTANCE) {
899+
if (typePassesFilter(typeFilter, ty) === false) {
900+
returned = MAX_LEV_DISTANCE + 1;
784901
}
785902
}
903+
786904
lev += lev_add;
787-
if (index !== -1) {
905+
if (in_args <= MAX_LEV_DISTANCE) {
906+
if (results_in_args[fullId] === undefined) {
907+
results_in_args[fullId] = {
908+
id: j,
909+
index: index,
910+
lev: in_args,
911+
};
912+
}
913+
results_in_args[fullId].lev =
914+
Math.min(results_in_args[fullId].lev, in_args);
915+
}
916+
if (returned <= MAX_LEV_DISTANCE) {
917+
if (results_returned[fullId] === undefined) {
918+
results_returned[fullId] = {
919+
id: j,
920+
index: index,
921+
lev: returned,
922+
};
923+
}
924+
results_returned[fullId].lev =
925+
Math.min(results_returned[fullId].lev, returned);
926+
}
927+
if (index !== -1 || lev <= MAX_LEV_DISTANCE) {
928+
if (index !== -1) {
929+
lev = 0;
930+
}
788931
if (results[fullId] === undefined) {
789932
results[fullId] = {
790933
id: j,
791934
index: index,
792935
lev: lev,
793-
in_args: in_args,
794-
returned: returned,
795936
};
796-
results_length += 1;
797-
} else {
798-
if (results[fullId].lev > lev) {
799-
results[fullId].lev = lev;
800-
}
801-
if (in_args === true) {
802-
results[fullId].in_args = true;
803-
}
804-
if (returned === true) {
805-
results[fullId].returned = true;
806-
}
807937
}
808-
}
809-
if (results_length === max) {
810-
break;
938+
results[fullId].lev = Math.min(results[fullId].lev, lev);
811939
}
812940
}
813941
}
814942

815-
var ar = [];
816-
for (var entry in results) {
817-
if (results.hasOwnProperty(entry)) {
818-
ar.push(results[entry]);
819-
}
820-
}
821-
results = ar;
822-
var nresults = results.length;
823-
for (var i = 0; i < nresults; ++i) {
824-
results[i].word = searchWords[results[i].id];
825-
results[i].item = searchIndex[results[i].id] || {};
826-
}
827-
// if there are no results then return to default and fail
828-
if (results.length === 0) {
829-
return [];
830-
}
831-
832-
results.sort(function sortResults(aaa, bbb) {
833-
var a, b;
834-
835-
// Sort by non levenshtein results and then levenshtein results by the distance
836-
// (less changes required to match means higher rankings)
837-
a = (aaa.lev);
838-
b = (bbb.lev);
839-
if (a !== b) { return a - b; }
840-
841-
// sort by crate (non-current crate goes later)
842-
a = (aaa.item.crate !== window.currentCrate);
843-
b = (bbb.item.crate !== window.currentCrate);
844-
if (a !== b) { return a - b; }
845-
846-
// sort by exact match (mismatch goes later)
847-
a = (aaa.word !== valLower);
848-
b = (bbb.word !== valLower);
849-
if (a !== b) { return a - b; }
850-
851-
// sort by item name length (longer goes later)
852-
a = aaa.word.length;
853-
b = bbb.word.length;
854-
if (a !== b) { return a - b; }
855-
856-
// sort by item name (lexicographically larger goes later)
857-
a = aaa.word;
858-
b = bbb.word;
859-
if (a !== b) { return (a > b ? +1 : -1); }
860-
861-
// sort by index of keyword in item name (no literal occurrence goes later)
862-
a = (aaa.index < 0);
863-
b = (bbb.index < 0);
864-
if (a !== b) { return a - b; }
865-
// (later literal occurrence, if any, goes later)
866-
a = aaa.index;
867-
b = bbb.index;
868-
if (a !== b) { return a - b; }
869-
870-
// special precedence for primitive pages
871-
if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
872-
return -1;
873-
}
874-
if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
875-
return 1;
876-
}
877-
878-
// sort by description (no description goes later)
879-
a = (aaa.item.desc === '');
880-
b = (bbb.item.desc === '');
881-
if (a !== b) { return a - b; }
882-
883-
// sort by type (later occurrence in `itemTypes` goes later)
884-
a = aaa.item.ty;
885-
b = bbb.item.ty;
886-
if (a !== b) { return a - b; }
887-
888-
// sort by path (lexicographically larger goes later)
889-
a = aaa.item.path;
890-
b = bbb.item.path;
891-
if (a !== b) { return (a > b ? +1 : -1); }
892-
893-
// que sera, sera
894-
return 0;
895-
});
896-
897-
for (var i = 0; i < results.length; ++i) {
898-
var result = results[i];
899-
900-
// this validation does not make sense when searching by types
901-
if (result.dontValidate || result.returned === true && result.param === true) {
902-
continue;
903-
}
904-
var name = result.item.name.toLowerCase(),
905-
path = result.item.path.toLowerCase(),
906-
parent = result.item.parent;
907-
908-
if (validateResult(name, path, split, parent) === false) {
909-
result.id = -1;
910-
}
911-
}
912-
return results;
943+
return {
944+
'in_args': sortResults(results_in_args, true),
945+
'returned': sortResults(results_returned, true),
946+
'others': sortResults(results),
947+
};
913948
}
914949

915950
/**
@@ -1187,10 +1222,8 @@
11871222

11881223
function search(e) {
11891224
var query,
1190-
filterdata = [],
11911225
obj, i, len,
11921226
results = {"in_args": [], "returned": [], "others": []},
1193-
maxResults = 200,
11941227
resultIndex;
11951228
var params = getQueryStringParams();
11961229

@@ -1216,40 +1249,7 @@
12161249
}
12171250
}
12181251

1219-
resultIndex = execQuery(query, 20000, index);
1220-
len = resultIndex.length;
1221-
for (i = 0; i < len; ++i) {
1222-
if (resultIndex[i].id > -1) {
1223-
var added = false;
1224-
obj = searchIndex[resultIndex[i].id];
1225-
filterdata.push([obj.name, obj.ty, obj.path, obj.desc]);
1226-
if (obj.type) {
1227-
if (results['returned'].length < maxResults &&
1228-
resultIndex[i].returned === true)
1229-
{
1230-
results['returned'].push(obj);
1231-
added = true;
1232-
}
1233-
if (results['in_args'].length < maxResults &&
1234-
resultIndex[i].in_args === true)
1235-
{
1236-
results['in_args'].push(obj);
1237-
added = true;
1238-
}
1239-
}
1240-
if (results['others'].length < maxResults &&
1241-
(added === false ||
1242-
(query.search && obj.name.indexOf(query.search) !== -1))) {
1243-
results['others'].push(obj);
1244-
}
1245-
}
1246-
if (results['others'].length >= maxResults &&
1247-
results['in_args'].length >= maxResults &&
1248-
results['returned'].length >= maxResults) {
1249-
break;
1250-
}
1251-
}
1252-
1252+
results = execQuery(query, 20000, index);
12531253
showResults(results);
12541254
}
12551255

0 commit comments

Comments
 (0)
Please sign in to comment.