summaryrefslogtreecommitdiffstats
path: root/target/doc/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'target/doc/main.js')
-rw-r--r--target/doc/main.js1118
1 files changed, 859 insertions, 259 deletions
diff --git a/target/doc/main.js b/target/doc/main.js
index 788cd80..f688be8 100644
--- a/target/doc/main.js
+++ b/target/doc/main.js
@@ -37,26 +37,44 @@
"associatedtype",
"constant",
"associatedconstant",
- "union"];
+ "union",
+ "foreigntype"];
+
+ // On the search screen, so you remain on the last tab you opened.
+ //
+ // 0 for "In Names"
+ // 1 for "In Parameters"
+ // 2 for "In Return Types"
+ var currentTab = 0;
+
+ var themesWidth = null;
function hasClass(elem, className) {
if (elem && className && elem.className) {
var elemClass = elem.className;
var start = elemClass.indexOf(className);
- if (start == -1) {
+ if (start === -1) {
return false;
- } else if (elemClass.length == className.length) {
+ } else if (elemClass.length === className.length) {
return true;
} else {
- if (start > 0 && elemClass[start - 1] != ' ') {
+ if (start > 0 && elemClass[start - 1] !== ' ') {
return false;
}
var end = start + className.length;
- if (end < elemClass.length && elemClass[end] != ' ') {
+ if (end < elemClass.length && elemClass[end] !== ' ') {
return false;
}
return true;
}
+ if (start > 0 && elemClass[start - 1] !== ' ') {
+ return false;
+ }
+ var end = start + className.length;
+ if (end < elemClass.length && elemClass[end] !== ' ') {
+ return false;
+ }
+ return true;
}
return false;
}
@@ -90,6 +108,45 @@
return (elem.offsetParent === null)
}
+ function showSidebar() {
+ var elems = document.getElementsByClassName("sidebar-elems")[0];
+ if (elems) {
+ addClass(elems, "show-it");
+ }
+ var sidebar = document.getElementsByClassName('sidebar')[0];
+ if (sidebar) {
+ addClass(sidebar, 'mobile');
+ var filler = document.getElementById("sidebar-filler");
+ if (!filler) {
+ var div = document.createElement("div");
+ div.id = "sidebar-filler";
+ sidebar.appendChild(div);
+ }
+ }
+ var themePicker = document.getElementsByClassName("theme-picker");
+ if (themePicker && themePicker.length > 0) {
+ themePicker[0].style.display = "none";
+ }
+ }
+
+ function hideSidebar() {
+ var elems = document.getElementsByClassName("sidebar-elems")[0];
+ if (elems) {
+ removeClass(elems, "show-it");
+ }
+ var sidebar = document.getElementsByClassName('sidebar')[0];
+ removeClass(sidebar, 'mobile');
+ var filler = document.getElementById("sidebar-filler");
+ if (filler) {
+ filler.remove();
+ }
+ document.getElementsByTagName("body")[0].style.marginTop = '';
+ var themePicker = document.getElementsByClassName("theme-picker");
+ if (themePicker && themePicker.length > 0) {
+ themePicker[0].style.display = null;
+ }
+ }
+
// used for special search precedence
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
@@ -103,8 +160,7 @@
map(function(s) {
var pair = s.split("=");
params[decodeURIComponent(pair[0])] =
- typeof pair[1] === "undefined" ?
- null : decodeURIComponent(pair[1]);
+ typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
});
return params;
}
@@ -115,6 +171,9 @@
}
function highlightSourceLines(ev) {
+ // If we're in mobile mode, we should add the sidebar in any case.
+ hideSidebar();
+ var search = document.getElementById("search");
var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
if (match) {
from = parseInt(match[1], 10);
@@ -129,7 +188,7 @@
if (x) {
x.scrollIntoView();
}
- };
+ }
onEach(document.getElementsByClassName('line-numbers'), function(e) {
onEach(e.getElementsByTagName('span'), function(i_e) {
removeClass(i_e, 'line-highlighted');
@@ -138,6 +197,17 @@
for (i = from; i <= to; ++i) {
addClass(document.getElementById(i), 'line-highlighted');
}
+ } else if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
+ addClass(search, "hidden");
+ removeClass(document.getElementById("main"), "hidden");
+ var hash = ev.newURL.slice(ev.newURL.indexOf('#') + 1);
+ if (browserSupportsHistoryApi()) {
+ history.replaceState(hash, "", "?search=#" + hash);
+ }
+ var elem = document.getElementById(hash);
+ if (elem) {
+ elem.scrollIntoView();
+ }
}
}
highlightSourceLines(null);
@@ -163,6 +233,20 @@
return String.fromCharCode(c);
}
+ function displayHelp(display, ev) {
+ if (display === true) {
+ if (hasClass(help, "hidden")) {
+ ev.preventDefault();
+ removeClass(help, "hidden");
+ addClass(document.body, "blur");
+ }
+ } else if (!hasClass(help, "hidden")) {
+ ev.preventDefault();
+ addClass(help, "hidden");
+ removeClass(document.body, "blur");
+ }
+ }
+
function handleShortcut(ev) {
if (document.activeElement.tagName === "INPUT")
return;
@@ -174,34 +258,36 @@
var help = document.getElementById("help");
switch (getVirtualKey(ev)) {
case "Escape":
+ hideModal();
var search = document.getElementById("search");
if (!hasClass(help, "hidden")) {
- ev.preventDefault();
- addClass(help, "hidden");
- removeClass(document.body, "blur");
+ displayHelp(false, ev);
} else if (!hasClass(search, "hidden")) {
ev.preventDefault();
addClass(search, "hidden");
removeClass(document.getElementById("main"), "hidden");
}
+ defocusSearchBar();
break;
case "s":
case "S":
+ displayHelp(false, ev);
+ hideModal();
ev.preventDefault();
focusSearchBar();
break;
case "+":
+ case "-":
ev.preventDefault();
toggleAllDocs();
break;
case "?":
- if (ev.shiftKey && hasClass(help, "hidden")) {
- ev.preventDefault();
- removeClass(help, "hidden");
- addClass(document.body, "blur");
+ if (ev.shiftKey) {
+ hideModal();
+ displayHelp(true, ev);
}
break;
}
@@ -276,39 +362,38 @@
* This code is an unmodified version of the code written by Marco de Wit
* and was found at http://stackoverflow.com/a/18514751/745719
*/
- var levenshtein = (function() {
- var row2 = [];
- return function(s1, s2) {
- if (s1 === s2) {
- return 0;
+ var levenshtein_row2 = [];
+ function levenshtein(s1, s2) {
+ if (s1 === s2) {
+ return 0;
+ }
+ var s1_len = s1.length, s2_len = s2.length;
+ if (s1_len && s2_len) {
+ var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2;
+ while (i1 < s1_len) {
+ row[i1] = ++i1;
}
- var s1_len = s1.length, s2_len = s2.length;
- if (s1_len && s2_len) {
- var i1 = 0, i2 = 0, a, b, c, c2, row = row2;
- while (i1 < s1_len) {
- row[i1] = ++i1;
- }
- while (i2 < s2_len) {
- c2 = s2.charCodeAt(i2);
- a = i2;
- ++i2;
- b = i2;
- for (i1 = 0; i1 < s1_len; ++i1) {
- c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0);
- a = row[i1];
- b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c);
- row[i1] = b;
- }
+ while (i2 < s2_len) {
+ c2 = s2.charCodeAt(i2);
+ a = i2;
+ ++i2;
+ b = i2;
+ for (i1 = 0; i1 < s1_len; ++i1) {
+ c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0);
+ a = row[i1];
+ b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c);
+ row[i1] = b;
}
- return b;
}
- return s1_len + s2_len;
- };
- })();
+ return b;
+ }
+ return s1_len + s2_len;
+ }
function initSearch(rawSearchIndex) {
var currentResults, index, searchIndex;
var MAX_LEV_DISTANCE = 3;
+ var MAX_RESULTS = 200;
var params = getQueryStringParams();
// Populate search bar with query string search term when provided,
@@ -322,24 +407,336 @@
/**
* Executes the query and builds an index of results
* @param {[Object]} query [The user query]
- * @param {[type]} max [The maximum results returned]
* @param {[type]} searchWords [The list of search words to query
* against]
* @return {[type]} [A search index of results]
*/
- function execQuery(query, max, searchWords) {
+ function execQuery(query, searchWords) {
+ function itemTypeFromName(typename) {
+ for (var i = 0; i < itemTypes.length; ++i) {
+ if (itemTypes[i] === typename) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
var valLower = query.query.toLowerCase(),
val = valLower,
typeFilter = itemTypeFromName(query.type),
- results = [],
+ results = {}, results_in_args = {}, results_returned = {},
split = valLower.split("::");
- // remove empty keywords
- for (var j = 0; j < split.length; ++j) {
- split[j].toLowerCase();
- if (split[j] === "") {
- split.splice(j, 1);
+ for (var z = 0; z < split.length; ++z) {
+ if (split[z] === "") {
+ split.splice(z, 1);
+ z -= 1;
+ }
+ }
+
+ function transformResults(results, isType) {
+ var out = [];
+ for (i = 0; i < results.length; ++i) {
+ if (results[i].id > -1) {
+ var obj = searchIndex[results[i].id];
+ obj.lev = results[i].lev;
+ if (isType !== true || obj.type) {
+ out.push(obj);
+ }
+ }
+ if (out.length >= MAX_RESULTS) {
+ break;
+ }
+ }
+ return out;
+ }
+
+ function sortResults(results, isType) {
+ var ar = [];
+ for (var entry in results) {
+ if (results.hasOwnProperty(entry)) {
+ ar.push(results[entry]);
+ }
+ }
+ results = ar;
+ var nresults = results.length;
+ for (var i = 0; i < nresults; ++i) {
+ results[i].word = searchWords[results[i].id];
+ results[i].item = searchIndex[results[i].id] || {};
+ }
+ // if there are no results then return to default and fail
+ if (results.length === 0) {
+ return [];
+ }
+
+ results.sort(function(aaa, bbb) {
+ var a, b;
+
+ // Sort by non levenshtein results and then levenshtein results by the distance
+ // (less changes required to match means higher rankings)
+ a = (aaa.lev);
+ b = (bbb.lev);
+ if (a !== b) { return a - b; }
+
+ // sort by crate (non-current crate goes later)
+ a = (aaa.item.crate !== window.currentCrate);
+ b = (bbb.item.crate !== window.currentCrate);
+ if (a !== b) { return a - b; }
+
+ // sort by exact match (mismatch goes later)
+ a = (aaa.word !== valLower);
+ b = (bbb.word !== valLower);
+ if (a !== b) { return a - b; }
+
+ // sort by item name length (longer goes later)
+ a = aaa.word.length;
+ b = bbb.word.length;
+ if (a !== b) { return a - b; }
+
+ // sort by item name (lexicographically larger goes later)
+ a = aaa.word;
+ b = bbb.word;
+ if (a !== b) { return (a > b ? +1 : -1); }
+
+ // sort by index of keyword in item name (no literal occurrence goes later)
+ a = (aaa.index < 0);
+ b = (bbb.index < 0);
+ if (a !== b) { return a - b; }
+ // (later literal occurrence, if any, goes later)
+ a = aaa.index;
+ b = bbb.index;
+ if (a !== b) { return a - b; }
+
+ // special precedence for primitive pages
+ if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
+ return -1;
+ }
+ if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
+ return 1;
+ }
+
+ // sort by description (no description goes later)
+ a = (aaa.item.desc === '');
+ b = (bbb.item.desc === '');
+ if (a !== b) { return a - b; }
+
+ // sort by type (later occurrence in `itemTypes` goes later)
+ a = aaa.item.ty;
+ b = bbb.item.ty;
+ if (a !== b) { return a - b; }
+
+ // sort by path (lexicographically larger goes later)
+ a = aaa.item.path;
+ b = bbb.item.path;
+ if (a !== b) { return (a > b ? +1 : -1); }
+
+ // que sera, sera
+ return 0;
+ });
+
+ for (var i = 0; i < results.length; ++i) {
+ var result = results[i];
+
+ // this validation does not make sense when searching by types
+ if (result.dontValidate) {
+ continue;
+ }
+ var name = result.item.name.toLowerCase(),
+ path = result.item.path.toLowerCase(),
+ parent = result.item.parent;
+
+ if (isType !== true &&
+ validateResult(name, path, split, parent) === false)
+ {
+ result.id = -1;
+ }
+ }
+ return transformResults(results);
+ }
+
+ function extractGenerics(val) {
+ val = val.toLowerCase();
+ if (val.indexOf('<') !== -1) {
+ var values = val.substring(val.indexOf('<') + 1, val.lastIndexOf('>'));
+ return {
+ name: val.substring(0, val.indexOf('<')),
+ generics: values.split(/\s*,\s*/),
+ };
+ }
+ return {
+ name: val,
+ generics: [],
+ };
+ }
+
+ function checkGenerics(obj, val) {
+ // The names match, but we need to be sure that all generics kinda
+ // match as well.
+ var lev_distance = MAX_LEV_DISTANCE + 1;
+ if (val.generics.length > 0) {
+ if (obj.generics && obj.generics.length >= val.generics.length) {
+ var elems = obj.generics.slice(0);
+ var total = 0;
+ var done = 0;
+ // We need to find the type that matches the most to remove it in order
+ // to move forward.
+ for (var y = 0; y < val.generics.length; ++y) {
+ var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1};
+ for (var x = 0; x < elems.length; ++x) {
+ var tmp_lev = levenshtein(elems[x], val.generics[y]);
+ if (tmp_lev < lev.lev) {
+ lev.lev = tmp_lev;
+ lev.pos = x;
+ }
+ }
+ if (lev.pos !== -1) {
+ elems.splice(lev.pos, 1);
+ lev_distance = Math.min(lev.lev, lev_distance);
+ total += lev.lev;
+ done += 1;
+ } else {
+ return MAX_LEV_DISTANCE + 1;
+ }
+ }
+ return lev_distance;//Math.ceil(total / done);
+ }
+ }
+ return MAX_LEV_DISTANCE + 1;
+ }
+
+ // Check for type name and type generics (if any).
+ function checkType(obj, val, literalSearch) {
+ var lev_distance = MAX_LEV_DISTANCE + 1;
+ if (obj.name === val.name) {
+ if (literalSearch === true) {
+ if (val.generics && val.generics.length !== 0) {
+ if (obj.generics && obj.length >= val.generics.length) {
+ var elems = obj.generics.slice(0);
+ var allFound = true;
+ var x;
+
+ for (var y = 0; allFound === true && y < val.generics.length; ++y) {
+ allFound = false;
+ for (x = 0; allFound === false && x < elems.length; ++x) {
+ allFound = elems[x] === val.generics[y];
+ }
+ if (allFound === true) {
+ elems.splice(x - 1, 1);
+ }
+ }
+ if (allFound === true) {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ // If the type has generics but don't match, then it won't return at this point.
+ // Otherwise, `checkGenerics` will return 0 and it'll return.
+ if (obj.generics && obj.generics.length !== 0) {
+ var tmp_lev = checkGenerics(obj, val);
+ if (tmp_lev <= MAX_LEV_DISTANCE) {
+ return tmp_lev;
+ }
+ } else {
+ return 0;
+ }
+ }
+ // Names didn't match so let's check if one of the generic types could.
+ if (literalSearch === true) {
+ if (obj.generics && obj.generics.length > 0) {
+ for (var x = 0; x < obj.generics.length; ++x) {
+ if (obj.generics[x] === val.name) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ var lev_distance = Math.min(levenshtein(obj.name, val.name), lev_distance);
+ if (lev_distance <= MAX_LEV_DISTANCE) {
+ lev_distance = Math.min(checkGenerics(obj, val), lev_distance);
+ } else if (obj.generics && obj.generics.length > 0) {
+ // We can check if the type we're looking for is inside the generics!
+ for (var x = 0; x < obj.generics.length; ++x) {
+ lev_distance = Math.min(levenshtein(obj.generics[x], val.name),
+ lev_distance);
+ }
+ }
+ // Now whatever happens, the returned distance is "less good" so we should mark it
+ // as such, and so we add 1 to the distance to make it "less good".
+ return lev_distance + 1;
+ }
+
+ function findArg(obj, val, literalSearch) {
+ var lev_distance = MAX_LEV_DISTANCE + 1;
+
+ if (obj && obj.type && obj.type.inputs.length > 0) {
+ for (var i = 0; i < obj.type.inputs.length; i++) {
+ var tmp = checkType(obj.type.inputs[i], val, literalSearch);
+ if (literalSearch === true && tmp === true) {
+ return true;
+ }
+ lev_distance = Math.min(tmp, lev_distance);
+ if (lev_distance === 0) {
+ return 0;
+ }
+ }
+ }
+ return literalSearch === true ? false : lev_distance;
+ }
+
+ function checkReturned(obj, val, literalSearch) {
+ var lev_distance = MAX_LEV_DISTANCE + 1;
+
+ if (obj && obj.type && obj.type.output) {
+ var tmp = checkType(obj.type.output, val, literalSearch);
+ if (literalSearch === true && tmp === true) {
+ return true;
+ }
+ lev_distance = Math.min(tmp, lev_distance);
+ if (lev_distance === 0) {
+ return 0;
+ }
+ }
+ return literalSearch === true ? false : lev_distance;
+ }
+
+ function checkPath(startsWith, lastElem, ty) {
+ if (startsWith.length === 0) {
+ return 0;
}
+ var ret_lev = MAX_LEV_DISTANCE + 1;
+ var path = ty.path.split("::");
+
+ if (ty.parent && ty.parent.name) {
+ path.push(ty.parent.name.toLowerCase());
+ }
+
+ if (startsWith.length > path.length) {
+ return MAX_LEV_DISTANCE + 1;
+ }
+ for (var i = 0; i < path.length; ++i) {
+ if (i + startsWith.length > path.length) {
+ break;
+ }
+ var lev_total = 0;
+ var aborted = false;
+ for (var x = 0; x < startsWith.length; ++x) {
+ var lev = levenshtein(path[i + x], startsWith[x]);
+ if (lev > MAX_LEV_DISTANCE) {
+ aborted = true;
+ break;
+ }
+ lev_total += lev;
+ }
+ if (aborted === false) {
+ ret_lev = Math.min(ret_lev, Math.round(lev_total / startsWith.length));
+ }
+ }
+ return ret_lev;
}
function typePassesFilter(filter, type) {
@@ -364,189 +761,245 @@
return false;
}
+ function generateId(ty) {
+ if (ty.parent && ty.parent.name) {
+ return itemTypes[ty.ty] + ty.path + ty.parent.name + ty.name;
+ }
+ return itemTypes[ty.ty] + ty.path + ty.name;
+ }
+
// quoted values mean literal search
var nSearchWords = searchWords.length;
if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
val.charAt(val.length - 1) === val.charAt(0))
{
- val = val.substr(1, val.length - 2);
+ val = extractGenerics(val.substr(1, val.length - 2));
for (var i = 0; i < nSearchWords; ++i) {
- if (searchWords[i] === val) {
+ var in_args = findArg(searchIndex[i], val, true);
+ var returned = checkReturned(searchIndex[i], val, true);
+ var ty = searchIndex[i];
+ var fullId = generateId(ty);
+
+ if (searchWords[i] === val.name) {
// filter type: ... queries
- if (typePassesFilter(typeFilter, searchIndex[i].ty)) {
- results.push({id: i, index: -1});
+ if (typePassesFilter(typeFilter, searchIndex[i].ty) &&
+ results[fullId] === undefined)
+ {
+ results[fullId] = {id: i, index: -1};
+ }
+ } else if ((in_args === true || returned === true) &&
+ typePassesFilter(typeFilter, searchIndex[i].ty)) {
+ if (in_args === true || returned === true) {
+ if (in_args === true) {
+ results_in_args[fullId] = {
+ id: i,
+ index: -1,
+ dontValidate: true,
+ };
+ }
+ if (returned === true) {
+ results_returned[fullId] = {
+ id: i,
+ index: -1,
+ dontValidate: true,
+ };
+ }
+ } else {
+ results[fullId] = {
+ id: i,
+ index: -1,
+ dontValidate: true,
+ };
}
- }
- if (results.length === max) {
- break;
}
}
+ query.inputs = [val];
+ query.output = val;
+ query.search = val;
// searching by type
} else if (val.search("->") > -1) {
var trimmer = function (s) { return s.trim(); };
var parts = val.split("->").map(trimmer);
var input = parts[0];
// sort inputs so that order does not matter
- var inputs = input.split(",").map(trimmer).sort().toString();
- var output = parts[1];
+ var inputs = input.split(",").map(trimmer).sort();
+ for (var i = 0; i < inputs.length; ++i) {
+ inputs[i] = extractGenerics(inputs[i]);
+ }
+ var output = extractGenerics(parts[1]);
for (var i = 0; i < nSearchWords; ++i) {
var type = searchIndex[i].type;
+ var ty = searchIndex[i];
if (!type) {
continue;
}
-
- // sort index inputs so that order does not matter
- var typeInputs = type.inputs.map(function (input) {
- return input.name;
- }).sort();
+ var fullId = generateId(ty);
// allow searching for void (no output) functions as well
var typeOutput = type.output ? type.output.name : "";
- if ((inputs === "*" || inputs === typeInputs.toString()) &&
- (output === "*" || output == typeOutput)) {
- results.push({id: i, index: -1, dontValidate: true});
- }
- }
- } else {
- // gather matching search results up to a certain maximum
- val = val.replace(/\_/g, "");
- for (var i = 0; i < split.length; ++i) {
- for (var j = 0; j < nSearchWords; ++j) {
- var lev_distance;
- if (searchWords[j].indexOf(split[i]) > -1 ||
- searchWords[j].indexOf(val) > -1 ||
- searchWords[j].replace(/_/g, "").indexOf(val) > -1)
- {
- // filter type: ... queries
- if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
- results.push({
- id: j,
- index: searchWords[j].replace(/_/g, "").indexOf(val),
- lev: 0,
- });
- }
- } else if (
- (lev_distance = levenshtein(searchWords[j], val)) <=
- MAX_LEV_DISTANCE) {
- if (typePassesFilter(typeFilter, searchIndex[j].ty)) {
- results.push({
- id: j,
- index: 0,
- // we want lev results to go lower than others
- lev: lev_distance,
- });
+ var returned = checkReturned(ty, output, true);
+ if (output.name === "*" || returned === true) {
+ var in_args = false;
+ var module = false;
+
+ if (input === "*") {
+ module = true;
+ } else {
+ var allFound = true;
+ for (var it = 0; allFound === true && it < inputs.length; it++) {
+ allFound = checkType(type, inputs[it], true);
}
+ in_args = allFound;
}
- if (results.length === max) {
- break;
+ if (in_args === true) {
+ results_in_args[fullId] = {
+ id: i,
+ index: -1,
+ dontValidate: true,
+ };
+ }
+ if (returned === true) {
+ results_returned[fullId] = {
+ id: i,
+ index: -1,
+ dontValidate: true,
+ };
+ }
+ if (module === true) {
+ results[fullId] = {
+ id: i,
+ index: -1,
+ dontValidate: true,
+ };
}
}
}
- }
+ query.inputs = inputs.map(function(input) {
+ return input.name;
+ });
+ query.output = output.name;
+ } else {
+ query.inputs = [val];
+ query.output = val;
+ query.search = val;
+ // gather matching search results up to a certain maximum
+ val = val.replace(/\_/g, "");
- var nresults = results.length;
- for (var i = 0; i < nresults; ++i) {
- results[i].word = searchWords[results[i].id];
- results[i].item = searchIndex[results[i].id] || {};
- }
- // if there are no results then return to default and fail
- if (results.length === 0) {
- return [];
- }
+ var valGenerics = extractGenerics(val);
- results.sort(function sortResults(aaa, bbb) {
- var a, b;
-
- // Sort by non levenshtein results and then levenshtein results by the distance
- // (less changes required to match means higher rankings)
- a = (aaa.lev);
- b = (bbb.lev);
- if (a !== b) { return a - b; }
-
- // sort by crate (non-current crate goes later)
- a = (aaa.item.crate !== window.currentCrate);
- b = (bbb.item.crate !== window.currentCrate);
- if (a !== b) { return a - b; }
-
- // sort by exact match (mismatch goes later)
- a = (aaa.word !== valLower);
- b = (bbb.word !== valLower);
- if (a !== b) { return a - b; }
-
- // sort by item name length (longer goes later)
- a = aaa.word.length;
- b = bbb.word.length;
- if (a !== b) { return a - b; }
-
- // sort by item name (lexicographically larger goes later)
- a = aaa.word;
- b = bbb.word;
- if (a !== b) { return (a > b ? +1 : -1); }
-
- // sort by index of keyword in item name (no literal occurrence goes later)
- a = (aaa.index < 0);
- b = (bbb.index < 0);
- if (a !== b) { return a - b; }
- // (later literal occurrence, if any, goes later)
- a = aaa.index;
- b = bbb.index;
- if (a !== b) { return a - b; }
-
- // special precedence for primitive pages
- if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
- return -1;
- }
- if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
- return 1;
+ var paths = valLower.split("::");
+ var j;
+ for (j = 0; j < paths.length; ++j) {
+ if (paths[j] === "") {
+ paths.splice(j, 1);
+ j -= 1;
+ }
}
+ val = paths[paths.length - 1];
+ var startsWith = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1);
- // sort by description (no description goes later)
- a = (aaa.item.desc === '');
- b = (bbb.item.desc === '');
- if (a !== b) { return a - b; }
-
- // sort by type (later occurrence in `itemTypes` goes later)
- a = aaa.item.ty;
- b = bbb.item.ty;
- if (a !== b) { return a - b; }
-
- // sort by path (lexicographically larger goes later)
- a = aaa.item.path;
- b = bbb.item.path;
- if (a !== b) { return (a > b ? +1 : -1); }
+ for (j = 0; j < nSearchWords; ++j) {
+ var lev_distance;
+ var ty = searchIndex[j];
+ if (!ty) {
+ continue;
+ }
+ var lev_add = 0;
+ if (paths.length > 1) {
+ var lev = checkPath(startsWith, paths[paths.length - 1], ty);
+ if (lev > MAX_LEV_DISTANCE) {
+ continue;
+ } else if (lev > 0) {
+ lev_add = 1;
+ }
+ }
- // que sera, sera
- return 0;
- });
+ var returned = MAX_LEV_DISTANCE + 1;
+ var in_args = MAX_LEV_DISTANCE + 1;
+ var index = -1;
+ // we want lev results to go lower than others
+ var lev = MAX_LEV_DISTANCE + 1;
+ var fullId = generateId(ty);
+
+ if (searchWords[j].indexOf(split[i]) > -1 ||
+ searchWords[j].indexOf(val) > -1 ||
+ searchWords[j].replace(/_/g, "").indexOf(val) > -1)
+ {
+ // filter type: ... queries
+ if (typePassesFilter(typeFilter, ty.ty) && results[fullId] === undefined) {
+ index = searchWords[j].replace(/_/g, "").indexOf(val);
+ }
+ }
+ if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) {
+ if (typePassesFilter(typeFilter, ty.ty) === false) {
+ lev = MAX_LEV_DISTANCE + 1;
+ } else {
+ lev += 1;
+ }
+ }
+ if ((in_args = findArg(ty, valGenerics)) <= MAX_LEV_DISTANCE) {
+ if (typePassesFilter(typeFilter, ty.ty) === false) {
+ in_args = MAX_LEV_DISTANCE + 1;
+ }
+ }
+