Skip to content

Commit 40337a1

Browse files
authored
Rollup merge of rust-lang#56332 - GuillaumeGomez:specifi-crate-search, r=QuietMisdreavus
[rustdoc] Specific crate search Reopening of rust-lang#54706. Fixes rust-lang#54616. <img width="1440" alt="screenshot 2018-11-29 at 01 29 11" src="https://user-images.githubusercontent.com/3050060/49191372-979adf80-f376-11e8-963e-e4feb927c1da.png"> r? @QuietMisdreavus
2 parents 8a5cb26 + 3f253f5 commit 40337a1

File tree

10 files changed

+164
-26
lines changed

10 files changed

+164
-26
lines changed

src/librustdoc/html/layout.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
5757
{css_extension}\
5858
{favicon}\
5959
{in_header}\
60+
<style type=\"text/css\">\
61+
#crate-search{{background-image:url(\"{root_path}down-arrow{suffix}.svg\");}}\
62+
</style>\
6063
</head>\
6164
<body class=\"rustdoc {css_class}\">\
6265
<!--[if lte IE 8]>\
@@ -81,11 +84,16 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
8184
<nav class=\"sub\">\
8285
<form class=\"search-form js-only\">\
8386
<div class=\"search-container\">\
84-
<input class=\"search-input\" name=\"search\" \
85-
autocomplete=\"off\" \
86-
spellcheck=\"false\" \
87-
placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
88-
type=\"search\">\
87+
<div>\
88+
<select id=\"crate-search\">\
89+
<option value=\"All crates\">All crates</option>\
90+
</select>\
91+
<input class=\"search-input\" name=\"search\" \
92+
autocomplete=\"off\" \
93+
spellcheck=\"false\" \
94+
placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
95+
type=\"search\">\
96+
</div>\
8997
<a id=\"settings-menu\" href=\"{root_path}settings.html\">\
9098
<img src=\"{root_path}wheel{suffix}.svg\" width=\"18\" alt=\"Change settings\">\
9199
</a>\

src/librustdoc/html/render.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,8 @@ fn write_shared(
793793
static_files::BRUSH_SVG)?;
794794
write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
795795
static_files::WHEEL_SVG)?;
796+
write(cx.dst.join(&format!("down-arrow{}.svg", cx.shared.resource_suffix)),
797+
static_files::DOWN_ARROW_SVG)?;
796798
write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
797799
static_files::themes::LIGHT,
798800
options.enable_minification)?;
@@ -1066,7 +1068,7 @@ themePicker.onblur = handleThemeButtonsBlur;
10661068
&[(minifier::js::Keyword::Null, "N")]),
10671069
&dst);
10681070
}
1069-
try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
1071+
try_err!(writeln!(&mut w, "initSearch(searchIndex);addSearchOptions(searchIndex);"), &dst);
10701072

10711073
if options.enable_index_page {
10721074
if let Some(index_page) = options.index_page.clone() {
Loading

src/librustdoc/html/static/main.js

+83-16
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,14 @@ if (!String.prototype.endsWith) {
214214
//
215215
// So I guess you could say things are getting pretty interoperable.
216216
function getVirtualKey(ev) {
217-
if ("key" in ev && typeof ev.key != "undefined")
217+
if ("key" in ev && typeof ev.key != "undefined") {
218218
return ev.key;
219+
}
219220

220221
var c = ev.charCode || ev.keyCode;
221-
if (c == 27)
222+
if (c == 27) {
222223
return "Escape";
224+
}
223225
return String.fromCharCode(c);
224226
}
225227

@@ -427,12 +429,13 @@ if (!String.prototype.endsWith) {
427429

428430
/**
429431
* Executes the query and builds an index of results
430-
* @param {[Object]} query [The user query]
431-
* @param {[type]} searchWords [The list of search words to query
432-
* against]
433-
* @return {[type]} [A search index of results]
432+
* @param {[Object]} query [The user query]
433+
* @param {[type]} searchWords [The list of search words to query
434+
* against]
435+
* @param {[type]} filterCrates [Crate to search in if defined]
436+
* @return {[type]} [A search index of results]
434437
*/
435-
function execQuery(query, searchWords) {
438+
function execQuery(query, searchWords, filterCrates) {
436439
function itemTypeFromName(typename) {
437440
for (var i = 0; i < itemTypes.length; ++i) {
438441
if (itemTypes[i] === typename) {
@@ -808,6 +811,9 @@ if (!String.prototype.endsWith) {
808811
{
809812
val = extractGenerics(val.substr(1, val.length - 2));
810813
for (var i = 0; i < nSearchWords; ++i) {
814+
if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
815+
continue;
816+
}
811817
var in_args = findArg(searchIndex[i], val, true);
812818
var returned = checkReturned(searchIndex[i], val, true);
813819
var ty = searchIndex[i];
@@ -862,6 +868,9 @@ if (!String.prototype.endsWith) {
862868
var output = extractGenerics(parts[1]);
863869

864870
for (var i = 0; i < nSearchWords; ++i) {
871+
if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
872+
continue;
873+
}
865874
var type = searchIndex[i].type;
866875
var ty = searchIndex[i];
867876
if (!type) {
@@ -933,11 +942,11 @@ if (!String.prototype.endsWith) {
933942
var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1);
934943

935944
for (j = 0; j < nSearchWords; ++j) {
936-
var lev_distance;
937945
var ty = searchIndex[j];
938-
if (!ty) {
946+
if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) {
939947
continue;
940948
}
949+
var lev_distance;
941950
var lev_add = 0;
942951
if (paths.length > 1) {
943952
var lev = checkPath(contains, paths[paths.length - 1], ty);
@@ -1322,7 +1331,7 @@ if (!String.prototype.endsWith) {
13221331
return '<div>' + text + ' <div class="count">(' + nbElems + ')</div></div>';
13231332
}
13241333

1325-
function showResults(results) {
1334+
function showResults(results, filterCrates) {
13261335
if (results['others'].length === 1 &&
13271336
getCurrentValue('rustdoc-go-to-only-result') === "true") {
13281337
var elem = document.createElement('a');
@@ -1340,8 +1349,13 @@ if (!String.prototype.endsWith) {
13401349
var ret_in_args = addTab(results['in_args'], query, false);
13411350
var ret_returned = addTab(results['returned'], query, false);
13421351

1352+
var filter = "";
1353+
if (filterCrates !== undefined) {
1354+
filter = " (in <b>" + filterCrates + "</b> crate)";
1355+
}
1356+
13431357
var output = '<h1>Results for ' + escape(query.query) +
1344-
(query.type ? ' (type: ' + escape(query.type) + ')' : '') + '</h1>' +
1358+
(query.type ? ' (type: ' + escape(query.type) + ')' : '') + filter + '</h1>' +
13451359
'<div id="titles">' +
13461360
makeTabHeader(0, "In Names", ret_others[1]) +
13471361
makeTabHeader(1, "In Parameters", ret_in_args[1]) +
@@ -1370,7 +1384,7 @@ if (!String.prototype.endsWith) {
13701384
printTab(currentTab);
13711385
}
13721386

1373-
function execSearch(query, searchWords) {
1387+
function execSearch(query, searchWords, filterCrates) {
13741388
var queries = query.raw.split(",");
13751389
var results = {
13761390
'in_args': [],
@@ -1381,7 +1395,7 @@ if (!String.prototype.endsWith) {
13811395
for (var i = 0; i < queries.length; ++i) {
13821396
var query = queries[i].trim();
13831397
if (query.length !== 0) {
1384-
var tmp = execQuery(getQuery(query), searchWords);
1398+
var tmp = execQuery(getQuery(query), searchWords, filterCrates);
13851399

13861400
results['in_args'].push(tmp['in_args']);
13871401
results['returned'].push(tmp['returned']);
@@ -1443,15 +1457,27 @@ if (!String.prototype.endsWith) {
14431457
}
14441458
}
14451459

1446-
function search(e) {
1460+
function getFilterCrates() {
1461+
var elem = document.getElementById("crate-search");
1462+
1463+
if (elem && elem.value !== "All crates" && rawSearchIndex.hasOwnProperty(elem.value)) {
1464+
return elem.value;
1465+
}
1466+
return undefined;
1467+
}
1468+
1469+
function search(e, forced) {
14471470
var params = getQueryStringParams();
14481471
var query = getQuery(search_input.value.trim());
14491472

14501473
if (e) {
14511474
e.preventDefault();
14521475
}
14531476

1454-
if (query.query.length === 0 || query.id === currentResults) {
1477+
if (query.query.length === 0) {
1478+
return;
1479+
}
1480+
if (forced !== true && query.id === currentResults) {
14551481
if (query.query.length > 0) {
14561482
putBackSearch(search_input);
14571483
}
@@ -1471,7 +1497,8 @@ if (!String.prototype.endsWith) {
14711497
}
14721498
}
14731499

1474-
showResults(execSearch(query, index));
1500+
var filterCrates = getFilterCrates();
1501+
showResults(execSearch(query, index, filterCrates), filterCrates);
14751502
}
14761503

14771504
function buildIndex(rawSearchIndex) {
@@ -1571,6 +1598,13 @@ if (!String.prototype.endsWith) {
15711598
};
15721599
search_input.onpaste = search_input.onchange;
15731600

1601+
var selectCrate = document.getElementById('crate-search');
1602+
if (selectCrate) {
1603+
selectCrate.onchange = function() {
1604+
search(undefined, true);
1605+
};
1606+
}
1607+
15741608
// Push and pop states are used to add search results to the browser
15751609
// history.
15761610
if (browserSupportsHistoryApi()) {
@@ -2319,6 +2353,39 @@ if (!String.prototype.endsWith) {
23192353
if (window.location.hash && window.location.hash.length > 0) {
23202354
expandSection(window.location.hash.replace(/^#/, ''));
23212355
}
2356+
2357+
function addSearchOptions(crates) {
2358+
var elem = document.getElementById('crate-search');
2359+
2360+
if (!elem) {
2361+
return;
2362+
}
2363+
var crates_text = [];
2364+
for (var crate in crates) {
2365+
if (crates.hasOwnProperty(crate)) {
2366+
crates_text.push(crate);
2367+
}
2368+
}
2369+
crates_text.sort(function(a, b) {
2370+
var lower_a = a.toLowerCase();
2371+
var lower_b = b.toLowerCase();
2372+
2373+
if (lower_a < lower_b) {
2374+
return -1;
2375+
} else if (lower_a > lower_b) {
2376+
return 1;
2377+
}
2378+
return 0;
2379+
});
2380+
for (var i = 0; i < crates_text.length; ++i) {
2381+
var option = document.createElement("option");
2382+
option.value = crates_text[i];
2383+
option.innerText = crates_text[i];
2384+
elem.appendChild(option);
2385+
}
2386+
}
2387+
2388+
window.addSearchOptions = addSearchOptions;
23222389
}());
23232390

23242391
// Sets the focus on the search bar at the top of the page

src/librustdoc/html/static/rustdoc.css

+26-2
Original file line numberDiff line numberDiff line change
@@ -620,27 +620,51 @@ a {
620620
.search-container {
621621
position: relative;
622622
}
623+
.search-container > div {
624+
display: inline-flex;
625+
width: calc(100% - 34px);
626+
}
627+
#crate-search {
628+
margin-top: 5px;
629+
padding: 6px;
630+
padding-right: 19px;
631+
border: 0;
632+
border-right: 0;
633+
border-radius: 4px 0 0 4px;
634+
outline: none;
635+
cursor: pointer;
636+
border-right: 1px solid;
637+
-moz-appearance: none;
638+
-webkit-appearance: none;
639+
/* Removes default arrow from firefox */
640+
text-indent: 0.01px;
641+
text-overflow: "";
642+
background-repeat: no-repeat;
643+
background-color: transparent;
644+
background-size: 16%;
645+
background-position: calc(100% - 1px) 56%;
646+
}
623647
.search-container > .top-button {
624648
position: absolute;
625649
right: 0;
626650
top: 10px;
627651
}
628652
.search-input {
629-
width: calc(100% - 34px);
630653
/* Override Normalize.css: we have margins and do
631654
not want to overflow - the `moz` attribute is necessary
632655
until Firefox 29, too early to drop at this point */
633656
-moz-box-sizing: border-box !important;
634657
box-sizing: border-box !important;
635658
outline: none;
636659
border: none;
637-
border-radius: 1px;
660+
border-radius: 0 1px 1px 0;
638661
margin-top: 5px;
639662
padding: 10px 16px;
640663
font-size: 17px;
641664
transition: border-color 300ms ease;
642665
transition: border-radius 300ms ease-in-out;
643666
transition: box-shadow 300ms ease-in-out;
667+
width: 100%;
644668
}
645669

646670
.search-input:focus {

src/librustdoc/html/static/themes/dark.css

+7-1
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,15 @@ a.test-arrow {
182182
color: #999;
183183
}
184184

185+
#crate-search {
186+
color: #111;
187+
background-color: #f0f0f0;
188+
border-color: #000;
189+
}
190+
185191
.search-input {
186192
color: #111;
187-
box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
193+
box-shadow: 1px 0 0 1px #000, 0 0 0 2px transparent;
188194
background-color: #f0f0f0;
189195
}
190196

src/librustdoc/html/static/themes/light.css

+8-1
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,16 @@ a.test-arrow {
182182
color: #999;
183183
}
184184

185+
#crate-search {
186+
color: #555;
187+
background-color: white;
188+
border-color: #e0e0e0;
189+
box-shadow: 0px 0 0 1px #e0e0e0, 0 0 0 2px transparent;
190+
}
191+
185192
.search-input {
186193
color: #555;
187-
box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
194+
box-shadow: 1px 0 0 1px #e0e0e0, 0 0 0 2px transparent;
188195
background-color: white;
189196
}
190197

src/librustdoc/html/static_files.rs

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ pub static BRUSH_SVG: &'static [u8] = include_bytes!("static/brush.svg");
4545
/// The file contents of `wheel.svg`, the icon used for the settings button.
4646
pub static WHEEL_SVG: &'static [u8] = include_bytes!("static/wheel.svg");
4747

48+
/// The file contents of `down-arrow.svg`, the icon used for the crate choice combobox.
49+
pub static DOWN_ARROW_SVG: &'static [u8] = include_bytes!("static/down-arrow.svg");
50+
4851
/// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
4952
/// output.
5053
pub static COPYRIGHT: &'static [u8] = include_bytes!("static/COPYRIGHT.txt");

src/test/rustdoc-js/filter-crate.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// exact-check
12+
13+
const QUERY = 'hashmap';
14+
const FILTER_CRATE = 'core';
15+
16+
const EXPECTED = {
17+
'others': [
18+
],
19+
};

src/tools/rustdoc-js/tester.js

+1
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ function main(argv) {
259259
'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;');
260260
const expected = loadedFile.EXPECTED;
261261
const query = loadedFile.QUERY;
262+
const filter_crate = loadedFile.FILTER_CRATE;
262263
const ignore_order = loadedFile.ignore_order;
263264
const exact_check = loadedFile.exact_check;
264265
const should_fail = loadedFile.should_fail;

0 commit comments

Comments
 (0)