提交 d5ecf70f 编写于 作者: B bors

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

Rustdoc improvements

Fixes #50658. (last commit)

A lot of small improvements.

r? @QuietMisdreavus
......@@ -413,9 +413,9 @@ fn to_json(&self) -> Json {
match self.name {
Some(ref name) => {
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 {
data.insert("generics".to_owned(), generics.to_json());
data.insert("g".to_owned(), generics.to_json());
}
Json::Object(data)
},
......@@ -438,8 +438,12 @@ fn to_json(&self) -> Json {
Json::Null
} else {
let mut data = BTreeMap::new();
data.insert("inputs".to_owned(), self.inputs.to_json());
data.insert("output".to_owned(), self.output.to_json());
if !self.inputs.is_empty() {
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)
}
}
......@@ -789,7 +793,8 @@ fn write_shared(cx: &Context,
format!(
r#"var themes = document.getElementById("theme-choices");
var themePicker = document.getElementById("theme-picker");
themePicker.onclick = function() {{
function switchThemeButtonState() {{
if (themes.style.display === "block") {{
themes.style.display = "none";
themePicker.style.borderBottomRightRadius = "3px";
......@@ -800,12 +805,29 @@ fn write_shared(cx: &Context,
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) {{
var but = document.createElement('button');
but.innerHTML = item;
but.onclick = function(el) {{
switchTheme(currentTheme, mainTheme, item);
}};
but.onblur = handleThemeButtonsBlur;
themes.appendChild(but);
}});"#,
themes.iter()
......@@ -879,8 +901,8 @@ fn collect(path: &Path, krate: &str, key: &str) -> io::Result<Vec<String>> {
}
fn show_item(item: &IndexItem, krate: &str) -> String {
format!("{{'crate':'{}','ty':{},'name':'{}','path':'{}'{}}}",
krate, item.ty as usize, item.name, item.path,
format!("{{'crate':'{}','ty':{},'name':'{}','desc':'{}','p':'{}'{}}}",
krate, item.ty as usize, item.name, item.desc.replace("'", "\\'"), item.path,
if let Some(p) = item.parent_idx {
format!(",'parent':{}", p)
} else {
......@@ -1442,7 +1464,7 @@ fn add_aliases(&mut self, item: &clean::Item) {
ty: item.type_(),
name: item_name.to_string(),
path: path.clone(),
desc: String::new(),
desc: plain_summary_line(item.doc_value()),
parent: None,
parent_idx: None,
search_type: get_index_search_type(&item),
......
......@@ -57,6 +57,12 @@
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() {
var id = document.location.href.split('#')[1];
......@@ -454,12 +460,16 @@
var obj = searchIndex[results[i].id];
obj.lev = results[i].lev;
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);
if (out.length >= MAX_RESULTS) {
break;
}
}
}
if (out.length >= MAX_RESULTS) {
break;
}
}
return out;
}
......@@ -587,8 +597,8 @@
// 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);
if (obj.g && obj.g.length >= val.generics.length) {
var elems = obj.g.slice(0);
var total = 0;
var done = 0;
// 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).
function checkType(obj, val, literalSearch) {
var lev_distance = MAX_LEV_DISTANCE + 1;
if (obj.name === val.name) {
if (obj.n === 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);
if (obj.g && obj.length >= val.generics.length) {
var elems = obj.g.slice(0);
var allFound = true;
var x;
......@@ -648,7 +658,7 @@
}
// 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) {
if (obj.g && obj.g.length !== 0) {
var tmp_lev = checkGenerics(obj, val);
if (tmp_lev <= MAX_LEV_DISTANCE) {
return tmp_lev;
......@@ -659,22 +669,22 @@
}
// 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) {
if (obj.g && obj.g.length > 0) {
for (var x = 0; x < obj.g.length; ++x) {
if (obj.g[x] === val.name) {
return true;
}
}
}
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) {
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!
for (var x = 0; x < obj.generics.length; ++x) {
lev_distance = Math.min(levenshtein(obj.generics[x], val.name),
for (var x = 0; x < obj.g.length; ++x) {
lev_distance = Math.min(levenshtein(obj.g[x], val.name),
lev_distance);
}
}
......@@ -686,9 +696,9 @@
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 (obj && obj.type && obj.type.i && obj.type.i.length > 0) {
for (var i = 0; i < obj.type.i.length; i++) {
var tmp = checkType(obj.type.i[i], val, literalSearch);
if (literalSearch === true && tmp === true) {
return true;
}
......@@ -704,8 +714,8 @@
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 (obj && obj.type && obj.type.o) {
var tmp = checkType(obj.type.o, val, literalSearch);
if (literalSearch === true && tmp === true) {
return true;
}
......@@ -850,7 +860,7 @@
var fullId = generateId(ty);
// 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);
if (output.name === "*" || returned === true) {
var in_args = false;
......@@ -1017,6 +1027,13 @@
ALIASES[window.currentCrate][query.raw]) {
var aliases = ALIASES[window.currentCrate][query.raw];
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]);
if (ret['others'].length > MAX_RESULTS) {
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) {
var displayPath;
var href;
......@@ -1227,6 +1234,20 @@
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) {
var extraStyle = '';
if (display === false) {
......@@ -1234,31 +1255,33 @@
}
var output = '';
var duplicates = {};
var length = 0;
if (array.length > 0) {
output = '<table class="search-results"' + extraStyle + '>';
var shown = [];
array.forEach(function(item) {
var name, type, href, displayPath;
var id_ty = item.ty + item.path + item.name;
if (shown.indexOf(id_ty) !== -1) {
return;
}
var name, type;
shown.push(id_ty);
name = item.name;
type = itemTypes[item.ty];
var res = buildHrefAndPath(item);
var href = res[1];
var displayPath = res[0];
if (item.is_alias !== true) {
if (duplicates[item.fullPath]) {
return;
}
duplicates[item.fullPath] = true;
}
length += 1;
output += '<tr class="' + type + ' result"><td>' +
'<a href="' + href + '">' +
pathSplitter(displayPath) + '<span class="' + type + '">' +
'<a href="' + item.href + '">' +
(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>' +
'<a href="' + href + '">' +
'<a href="' + item.href + '">' +
'<span class="desc">' + escape(item.desc) +
'&nbsp;</span></a></td></tr>';
});
......@@ -1269,7 +1292,7 @@
encodeURIComponent('rust ' + query.query) +
'">DuckDuckGo</a>?</div>';
}
return output;
return [output, length];
}
function makeTabHeader(tabNb, text, nbElems) {
......@@ -1284,28 +1307,28 @@
if (results['others'].length === 1 &&
getCurrentValue('rustdoc-go-to-only-result') === "true") {
var elem = document.createElement('a');
var res = buildHrefAndPath(results['others'][0]);
elem.href = res[1];
elem.href = results['others'][0].href;
elem.style.display = 'none';
// For firefox, we need the element to be in the DOM so it can be clicked.
document.body.appendChild(elem);
elem.click();
}
var output, query = getQuery(search_input.value);
var query = getQuery(search_input.value);
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>' +
'<div id="titles">' +
makeTabHeader(0, "In Names", results['others'].length) +
makeTabHeader(1, "In Parameters", results['in_args'].length) +
makeTabHeader(2, "In Return Types", results['returned'].length) +
'</div><div id="results">';
output += addTab(results['others'], query);
output += addTab(results['in_args'], query, false);
output += addTab(results['returned'], query, false);
output += '</div>';
makeTabHeader(0, "In Names", ret_others[1]) +
makeTabHeader(1, "In Parameters", ret_in_args[1]) +
makeTabHeader(2, "In Return Types", ret_returned[1]) +
'</div><div id="results">' +
ret_others[0] + ret_in_args[0] + ret_returned[0] + '</div>';
addClass(document.getElementById('main'), 'hidden');
var search = document.getElementById('search');
......@@ -1347,12 +1370,13 @@
}
}
if (queries.length > 1) {
function getSmallest(arrays, positions) {
function getSmallest(arrays, positions, notDuplicates) {
var start = null;
for (var it = 0; it < positions.length; ++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;
}
}
......@@ -1362,19 +1386,23 @@
function mergeArrays(arrays) {
var ret = [];
var positions = [];
var notDuplicates = {};
for (var x = 0; x < arrays.length; ++x) {
positions.push(0);
}
while (ret.length < MAX_RESULTS) {
var smallest = getSmallest(arrays, positions);
var smallest = getSmallest(arrays, positions, notDuplicates);
if (smallest === null) {
break;
}
for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++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]]);
notDuplicates[arrays[x][positions[x]].fullPath] = true;
positions[x] += 1;
}
}
......
......@@ -382,7 +382,7 @@ kbd {
}
#theme-choices > button:hover, #theme-choices > button:focus {
background-color: #444;
background-color: #4e4e4e;
}
@media (max-width: 700px) {
......@@ -397,3 +397,10 @@ kbd {
#all-types:hover {
background-color: #606060;
}
.search-results td span.alias {
color: #fff;
}
.search-results td span.grey {
color: #ccc;
}
\ No newline at end of file
......@@ -390,4 +390,11 @@ kbd {
}
#all-types:hover {
background-color: #f9f9f9;
}
.search-results td span.alias {
color: #000;
}
.search-results td span.grey {
color: #999;
}
\ No newline at end of file
// 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' },
],
};
......@@ -160,10 +160,11 @@ function main(argv) {
// execQuery first parameter is built in getQuery (which takes in the search input).
// execQuery last parameter is built in buildIndex.
// buildIndex requires the hashmap from search-index.
var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery",
"execSearch"];
var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
"getQuery", "buildIndex", "execQuery", "execSearch"];
finalJS += 'window = { "currentCrate": "std" };\n';
finalJS += 'var rootPath = "../";\n';
finalJS += ALIASES;
finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册