1
Fork 0

Auto merge of #50259 - GuillaumeGomez:improve-results, r=ollie27

Rustdoc improvements

Fixes #50658. (last commit)

A lot of small improvements.

r? @QuietMisdreavus
This commit is contained in:
bors 2018-05-15 05:39:35 +00:00
commit d5ecf70fd6
6 changed files with 161 additions and 75 deletions

View file

@ -413,9 +413,9 @@ impl ToJson for Type {
match self.name { match self.name {
Some(ref name) => { Some(ref name) => {
let mut data = BTreeMap::new(); let mut data = BTreeMap::new();
data.insert("name".to_owned(), name.to_json()); data.insert("n".to_owned(), name.to_json());
if let Some(ref generics) = self.generics { if let Some(ref generics) = self.generics {
data.insert("generics".to_owned(), generics.to_json()); data.insert("g".to_owned(), generics.to_json());
} }
Json::Object(data) Json::Object(data)
}, },
@ -438,8 +438,12 @@ impl ToJson for IndexItemFunctionType {
Json::Null Json::Null
} else { } else {
let mut data = BTreeMap::new(); let mut data = BTreeMap::new();
data.insert("inputs".to_owned(), self.inputs.to_json()); if !self.inputs.is_empty() {
data.insert("output".to_owned(), self.output.to_json()); data.insert("i".to_owned(), self.inputs.to_json());
}
if let Some(ref output) = self.output {
data.insert("o".to_owned(), output.to_json());
}
Json::Object(data) Json::Object(data)
} }
} }
@ -789,7 +793,8 @@ fn write_shared(cx: &Context,
format!( format!(
r#"var themes = document.getElementById("theme-choices"); r#"var themes = document.getElementById("theme-choices");
var themePicker = document.getElementById("theme-picker"); var themePicker = document.getElementById("theme-picker");
themePicker.onclick = function() {{
function switchThemeButtonState() {{
if (themes.style.display === "block") {{ if (themes.style.display === "block") {{
themes.style.display = "none"; themes.style.display = "none";
themePicker.style.borderBottomRightRadius = "3px"; themePicker.style.borderBottomRightRadius = "3px";
@ -800,12 +805,29 @@ themePicker.onclick = function() {{
themePicker.style.borderBottomLeftRadius = "0"; themePicker.style.borderBottomLeftRadius = "0";
}} }}
}}; }};
function handleThemeButtonsBlur(e) {{
var active = document.activeElement;
var related = e.relatedTarget;
if (active.id !== "themePicker" &&
(!active.parentNode || active.parentNode.id !== "theme-choices") &&
(!related ||
(related.id !== "themePicker" &&
(!related.parentNode || related.parentNode.id !== "theme-choices")))) {{
switchThemeButtonState();
}}
}}
themePicker.onclick = switchThemeButtonState;
themePicker.onblur = handleThemeButtonsBlur;
[{}].forEach(function(item) {{ [{}].forEach(function(item) {{
var but = document.createElement('button'); var but = document.createElement('button');
but.innerHTML = item; but.innerHTML = item;
but.onclick = function(el) {{ but.onclick = function(el) {{
switchTheme(currentTheme, mainTheme, item); switchTheme(currentTheme, mainTheme, item);
}}; }};
but.onblur = handleThemeButtonsBlur;
themes.appendChild(but); themes.appendChild(but);
}});"#, }});"#,
themes.iter() themes.iter()
@ -879,8 +901,8 @@ themePicker.onclick = function() {{
} }
fn show_item(item: &IndexItem, krate: &str) -> String { fn show_item(item: &IndexItem, krate: &str) -> String {
format!("{{'crate':'{}','ty':{},'name':'{}','path':'{}'{}}}", format!("{{'crate':'{}','ty':{},'name':'{}','desc':'{}','p':'{}'{}}}",
krate, item.ty as usize, item.name, item.path, krate, item.ty as usize, item.name, item.desc.replace("'", "\\'"), item.path,
if let Some(p) = item.parent_idx { if let Some(p) = item.parent_idx {
format!(",'parent':{}", p) format!(",'parent':{}", p)
} else { } else {
@ -1442,7 +1464,7 @@ impl<'a> Cache {
ty: item.type_(), ty: item.type_(),
name: item_name.to_string(), name: item_name.to_string(),
path: path.clone(), path: path.clone(),
desc: String::new(), desc: plain_summary_line(item.doc_value()),
parent: None, parent: None,
parent_idx: None, parent_idx: None,
search_type: get_index_search_type(&item), search_type: get_index_search_type(&item),

View file

@ -57,6 +57,12 @@
return this.indexOf(searchString, position) === position; return this.indexOf(searchString, position) === position;
}; };
} }
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(suffix, length) {
var l = length || this.length;
return this.indexOf(suffix, l - suffix.length) !== -1;
};
}
function getPageId() { function getPageId() {
var id = document.location.href.split('#')[1]; var id = document.location.href.split('#')[1];
@ -454,12 +460,16 @@
var obj = searchIndex[results[i].id]; var obj = searchIndex[results[i].id];
obj.lev = results[i].lev; obj.lev = results[i].lev;
if (isType !== true || obj.type) { if (isType !== true || obj.type) {
var res = buildHrefAndPath(obj);
obj.displayPath = pathSplitter(res[0]);
obj.fullPath = obj.displayPath + obj.name;
obj.href = res[1];
out.push(obj); out.push(obj);
if (out.length >= MAX_RESULTS) {
break;
}
} }
} }
if (out.length >= MAX_RESULTS) {
break;
}
} }
return out; return out;
} }
@ -587,8 +597,8 @@
// match as well. // match as well.
var lev_distance = MAX_LEV_DISTANCE + 1; var lev_distance = MAX_LEV_DISTANCE + 1;
if (val.generics.length > 0) { if (val.generics.length > 0) {
if (obj.generics && obj.generics.length >= val.generics.length) { if (obj.g && obj.g.length >= val.generics.length) {
var elems = obj.generics.slice(0); var elems = obj.g.slice(0);
var total = 0; var total = 0;
var done = 0; var done = 0;
// We need to find the type that matches the most to remove it in order // We need to find the type that matches the most to remove it in order
@ -620,11 +630,11 @@
// Check for type name and type generics (if any). // Check for type name and type generics (if any).
function checkType(obj, val, literalSearch) { function checkType(obj, val, literalSearch) {
var lev_distance = MAX_LEV_DISTANCE + 1; var lev_distance = MAX_LEV_DISTANCE + 1;
if (obj.name === val.name) { if (obj.n === val.name) {
if (literalSearch === true) { if (literalSearch === true) {
if (val.generics && val.generics.length !== 0) { if (val.generics && val.generics.length !== 0) {
if (obj.generics && obj.length >= val.generics.length) { if (obj.g && obj.length >= val.generics.length) {
var elems = obj.generics.slice(0); var elems = obj.g.slice(0);
var allFound = true; var allFound = true;
var x; var x;
@ -648,7 +658,7 @@
} }
// If the type has generics but don't match, then it won't return at this point. // 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. // Otherwise, `checkGenerics` will return 0 and it'll return.
if (obj.generics && obj.generics.length !== 0) { if (obj.g && obj.g.length !== 0) {
var tmp_lev = checkGenerics(obj, val); var tmp_lev = checkGenerics(obj, val);
if (tmp_lev <= MAX_LEV_DISTANCE) { if (tmp_lev <= MAX_LEV_DISTANCE) {
return tmp_lev; return tmp_lev;
@ -659,22 +669,22 @@
} }
// Names didn't match so let's check if one of the generic types could. // Names didn't match so let's check if one of the generic types could.
if (literalSearch === true) { if (literalSearch === true) {
if (obj.generics && obj.generics.length > 0) { if (obj.g && obj.g.length > 0) {
for (var x = 0; x < obj.generics.length; ++x) { for (var x = 0; x < obj.g.length; ++x) {
if (obj.generics[x] === val.name) { if (obj.g[x] === val.name) {
return true; return true;
} }
} }
} }
return false; return false;
} }
var lev_distance = Math.min(levenshtein(obj.name, val.name), lev_distance); var lev_distance = Math.min(levenshtein(obj.n, val.name), lev_distance);
if (lev_distance <= MAX_LEV_DISTANCE) { if (lev_distance <= MAX_LEV_DISTANCE) {
lev_distance = Math.min(checkGenerics(obj, val), lev_distance); lev_distance = Math.min(checkGenerics(obj, val), lev_distance);
} else if (obj.generics && obj.generics.length > 0) { } else if (obj.g && obj.g.length > 0) {
// We can check if the type we're looking for is inside the generics! // We can check if the type we're looking for is inside the generics!
for (var x = 0; x < obj.generics.length; ++x) { for (var x = 0; x < obj.g.length; ++x) {
lev_distance = Math.min(levenshtein(obj.generics[x], val.name), lev_distance = Math.min(levenshtein(obj.g[x], val.name),
lev_distance); lev_distance);
} }
} }
@ -686,9 +696,9 @@
function findArg(obj, val, literalSearch) { function findArg(obj, val, literalSearch) {
var lev_distance = MAX_LEV_DISTANCE + 1; var lev_distance = MAX_LEV_DISTANCE + 1;
if (obj && obj.type && obj.type.inputs.length > 0) { if (obj && obj.type && obj.type.i && obj.type.i.length > 0) {
for (var i = 0; i < obj.type.inputs.length; i++) { for (var i = 0; i < obj.type.i.length; i++) {
var tmp = checkType(obj.type.inputs[i], val, literalSearch); var tmp = checkType(obj.type.i[i], val, literalSearch);
if (literalSearch === true && tmp === true) { if (literalSearch === true && tmp === true) {
return true; return true;
} }
@ -704,8 +714,8 @@
function checkReturned(obj, val, literalSearch) { function checkReturned(obj, val, literalSearch) {
var lev_distance = MAX_LEV_DISTANCE + 1; var lev_distance = MAX_LEV_DISTANCE + 1;
if (obj && obj.type && obj.type.output) { if (obj && obj.type && obj.type.o) {
var tmp = checkType(obj.type.output, val, literalSearch); var tmp = checkType(obj.type.o, val, literalSearch);
if (literalSearch === true && tmp === true) { if (literalSearch === true && tmp === true) {
return true; return true;
} }
@ -850,7 +860,7 @@
var fullId = generateId(ty); var fullId = generateId(ty);
// allow searching for void (no output) functions as well // allow searching for void (no output) functions as well
var typeOutput = type.output ? type.output.name : ""; var typeOutput = type.o ? type.o.name : "";
var returned = checkReturned(ty, output, true); var returned = checkReturned(ty, output, true);
if (output.name === "*" || returned === true) { if (output.name === "*" || returned === true) {
var in_args = false; var in_args = false;
@ -1017,6 +1027,13 @@
ALIASES[window.currentCrate][query.raw]) { ALIASES[window.currentCrate][query.raw]) {
var aliases = ALIASES[window.currentCrate][query.raw]; var aliases = ALIASES[window.currentCrate][query.raw];
for (var i = 0; i < aliases.length; ++i) { for (var i = 0; i < aliases.length; ++i) {
aliases[i].is_alias = true;
aliases[i].alias = query.raw;
aliases[i].path = aliases[i].p;
var res = buildHrefAndPath(aliases[i]);
aliases[i].displayPath = pathSplitter(res[0]);
aliases[i].fullPath = aliases[i].displayPath + aliases[i].name;
aliases[i].href = res[1];
ret['others'].unshift(aliases[i]); ret['others'].unshift(aliases[i]);
if (ret['others'].length > MAX_RESULTS) { if (ret['others'].length > MAX_RESULTS) {
ret['others'].pop(); ret['others'].pop();
@ -1179,16 +1196,6 @@
}; };
} }
function escape(content) {
var h1 = document.createElement('h1');
h1.textContent = content;
return h1.innerHTML;
}
function pathSplitter(path) {
return '<span>' + path.replace(/::/g, '::</span><span>');
}
function buildHrefAndPath(item) { function buildHrefAndPath(item) {
var displayPath; var displayPath;
var href; var href;
@ -1227,6 +1234,20 @@
return [displayPath, href]; return [displayPath, href];
} }
function escape(content) {
var h1 = document.createElement('h1');
h1.textContent = content;
return h1.innerHTML;
}
function pathSplitter(path) {
var tmp = '<span>' + path.replace(/::/g, '::</span><span>');
if (tmp.endsWith("<span>")) {
return tmp.slice(0, tmp.length - 6);
}
return tmp;
}
function addTab(array, query, display) { function addTab(array, query, display) {
var extraStyle = ''; var extraStyle = '';
if (display === false) { if (display === false) {
@ -1234,31 +1255,33 @@
} }
var output = ''; var output = '';
var duplicates = {};
var length = 0;
if (array.length > 0) { if (array.length > 0) {
output = '<table class="search-results"' + extraStyle + '>'; output = '<table class="search-results"' + extraStyle + '>';
var shown = [];
array.forEach(function(item) { array.forEach(function(item) {
var name, type, href, displayPath; var name, type;
var id_ty = item.ty + item.path + item.name;
if (shown.indexOf(id_ty) !== -1) {
return;
}
shown.push(id_ty);
name = item.name; name = item.name;
type = itemTypes[item.ty]; type = itemTypes[item.ty];
var res = buildHrefAndPath(item); if (item.is_alias !== true) {
var href = res[1]; if (duplicates[item.fullPath]) {
var displayPath = res[0]; return;
}
duplicates[item.fullPath] = true;
}
length += 1;
output += '<tr class="' + type + ' result"><td>' + output += '<tr class="' + type + ' result"><td>' +
'<a href="' + href + '">' + '<a href="' + item.href + '">' +
pathSplitter(displayPath) + '<span class="' + type + '">' + (item.is_alias === true ?
('<span class="alias"><b>' + item.alias + ' </b></span><span ' +
'class="grey"><i>&nbsp;- see&nbsp;</i></span>') : '') +
item.displayPath + '<span class="' + type + '">' +
name + '</span></a></td><td>' + name + '</span></a></td><td>' +
'<a href="' + href + '">' + '<a href="' + item.href + '">' +
'<span class="desc">' + escape(item.desc) + '<span class="desc">' + escape(item.desc) +
'&nbsp;</span></a></td></tr>'; '&nbsp;</span></a></td></tr>';
}); });
@ -1269,7 +1292,7 @@
encodeURIComponent('rust ' + query.query) + encodeURIComponent('rust ' + query.query) +
'">DuckDuckGo</a>?</div>'; '">DuckDuckGo</a>?</div>';
} }
return output; return [output, length];
} }
function makeTabHeader(tabNb, text, nbElems) { function makeTabHeader(tabNb, text, nbElems) {
@ -1284,28 +1307,28 @@
if (results['others'].length === 1 && if (results['others'].length === 1 &&
getCurrentValue('rustdoc-go-to-only-result') === "true") { getCurrentValue('rustdoc-go-to-only-result') === "true") {
var elem = document.createElement('a'); var elem = document.createElement('a');
var res = buildHrefAndPath(results['others'][0]); elem.href = results['others'][0].href;
elem.href = res[1];
elem.style.display = 'none'; elem.style.display = 'none';
// For firefox, we need the element to be in the DOM so it can be clicked. // For firefox, we need the element to be in the DOM so it can be clicked.
document.body.appendChild(elem); document.body.appendChild(elem);
elem.click(); elem.click();
} }
var output, query = getQuery(search_input.value); var query = getQuery(search_input.value);
currentResults = query.id; currentResults = query.id;
output = '<h1>Results for ' + escape(query.query) +
var ret_others = addTab(results['others'], query);
var ret_in_args = addTab(results['in_args'], query, false);
var ret_returned = addTab(results['returned'], query, false);
var output = '<h1>Results for ' + escape(query.query) +
(query.type ? ' (type: ' + escape(query.type) + ')' : '') + '</h1>' + (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '</h1>' +
'<div id="titles">' + '<div id="titles">' +
makeTabHeader(0, "In Names", results['others'].length) + makeTabHeader(0, "In Names", ret_others[1]) +
makeTabHeader(1, "In Parameters", results['in_args'].length) + makeTabHeader(1, "In Parameters", ret_in_args[1]) +
makeTabHeader(2, "In Return Types", results['returned'].length) + makeTabHeader(2, "In Return Types", ret_returned[1]) +
'</div><div id="results">'; '</div><div id="results">' +
ret_others[0] + ret_in_args[0] + ret_returned[0] + '</div>';
output += addTab(results['others'], query);
output += addTab(results['in_args'], query, false);
output += addTab(results['returned'], query, false);
output += '</div>';
addClass(document.getElementById('main'), 'hidden'); addClass(document.getElementById('main'), 'hidden');
var search = document.getElementById('search'); var search = document.getElementById('search');
@ -1347,12 +1370,13 @@
} }
} }
if (queries.length > 1) { if (queries.length > 1) {
function getSmallest(arrays, positions) { function getSmallest(arrays, positions, notDuplicates) {
var start = null; var start = null;
for (var it = 0; it < positions.length; ++it) { for (var it = 0; it < positions.length; ++it) {
if (arrays[it].length > positions[it] && if (arrays[it].length > positions[it] &&
(start === null || start > arrays[it][positions[it]].lev)) { (start === null || start > arrays[it][positions[it]].lev) &&
!notDuplicates[arrays[it][positions[it]].fullPath]) {
start = arrays[it][positions[it]].lev; start = arrays[it][positions[it]].lev;
} }
} }
@ -1362,19 +1386,23 @@
function mergeArrays(arrays) { function mergeArrays(arrays) {
var ret = []; var ret = [];
var positions = []; var positions = [];
var notDuplicates = {};
for (var x = 0; x < arrays.length; ++x) { for (var x = 0; x < arrays.length; ++x) {
positions.push(0); positions.push(0);
} }
while (ret.length < MAX_RESULTS) { while (ret.length < MAX_RESULTS) {
var smallest = getSmallest(arrays, positions); var smallest = getSmallest(arrays, positions, notDuplicates);
if (smallest === null) { if (smallest === null) {
break; break;
} }
for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) { for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) {
if (arrays[x].length > positions[x] && if (arrays[x].length > positions[x] &&
arrays[x][positions[x]].lev === smallest) { arrays[x][positions[x]].lev === smallest &&
!notDuplicates[arrays[x][positions[x]].fullPath]) {
ret.push(arrays[x][positions[x]]); ret.push(arrays[x][positions[x]]);
notDuplicates[arrays[x][positions[x]].fullPath] = true;
positions[x] += 1; positions[x] += 1;
} }
} }

View file

@ -382,7 +382,7 @@ kbd {
} }
#theme-choices > button:hover, #theme-choices > button:focus { #theme-choices > button:hover, #theme-choices > button:focus {
background-color: #444; background-color: #4e4e4e;
} }
@media (max-width: 700px) { @media (max-width: 700px) {
@ -397,3 +397,10 @@ kbd {
#all-types:hover { #all-types:hover {
background-color: #606060; background-color: #606060;
} }
.search-results td span.alias {
color: #fff;
}
.search-results td span.grey {
color: #ccc;
}

View file

@ -390,4 +390,11 @@ kbd {
} }
#all-types:hover { #all-types:hover {
background-color: #f9f9f9; background-color: #f9f9f9;
}
.search-results td span.alias {
color: #000;
}
.search-results td span.grey {
color: #999;
} }

View file

@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-order
const QUERY = 'is_nan';
const EXPECTED = {
'others': [
{ 'path': 'std::f32', 'name': 'is_nan' },
{ 'path': 'std::f64', 'name': 'is_nan' },
{ 'path': 'std::option::Option', 'name': 'is_none' },
],
};

View file

@ -160,10 +160,11 @@ function main(argv) {
// execQuery first parameter is built in getQuery (which takes in the search input). // execQuery first parameter is built in getQuery (which takes in the search input).
// execQuery last parameter is built in buildIndex. // execQuery last parameter is built in buildIndex.
// buildIndex requires the hashmap from search-index. // buildIndex requires the hashmap from search-index.
var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery", var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
"execSearch"]; "getQuery", "buildIndex", "execQuery", "execSearch"];
finalJS += 'window = { "currentCrate": "std" };\n'; finalJS += 'window = { "currentCrate": "std" };\n';
finalJS += 'var rootPath = "../";\n';
finalJS += ALIASES; finalJS += ALIASES;
finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);