Skip to content

Commit

Permalink
Auto merge of #49954 - GuillaumeGomez:doc-settings, r=ollie27,QuietMi…
Browse files Browse the repository at this point in the history
…sdreavus

Add rustdoc settings menu

Fixes #18167.

r? @QuietMisdreavus
  • Loading branch information
bors committed Apr 22, 2018
2 parents 0cbd310 + 1f7892f commit 28193e8
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 26 deletions.
8 changes: 6 additions & 2 deletions src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
autocomplete=\"off\" \
placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
type=\"search\">\
<a id=\"settings-menu\" href=\"{root_path}settings.html\">\
<img src=\"{root_path}wheel{suffix}.svg\" width=\"18\" alt=\"Change settings\">\
</a>\
</div>\
</form>\
</nav>\
Expand Down Expand Up @@ -182,9 +185,10 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
themes = themes.iter()
.filter_map(|t| t.file_stem())
.filter_map(|t| t.to_str())
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}">"#,
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#,
page.root_path,
t.replace(".css", &format!("{}.css", page.resource_suffix))))
t,
page.resource_suffix))
.collect::<String>(),
suffix=page.resource_suffix,
)
Expand Down
79 changes: 76 additions & 3 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ fn write_shared(cx: &Context,

write(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
include_bytes!("static/rustdoc.css"))?;
write(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
include_bytes!("static/settings.css"))?;

// To avoid "light.css" to be overwritten, we'll first run over the received themes and only
// then we'll run over the "official" styles.
Expand All @@ -769,6 +771,8 @@ fn write_shared(cx: &Context,

write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)),
include_bytes!("static/brush.svg"))?;
write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
include_bytes!("static/wheel.svg"))?;
write(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
include_bytes!("static/themes/light.css"))?;
themes.insert("light".to_owned());
Expand Down Expand Up @@ -802,8 +806,7 @@ themePicker.onclick = function() {{
switchTheme(currentTheme, mainTheme, item);
}};
themes.appendChild(but);
}});
"#,
}});"#,
themes.iter()
.map(|s| format!("\"{}\"", s))
.collect::<Vec<String>>()
Expand All @@ -812,6 +815,8 @@ themePicker.onclick = function() {{

write(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
include_bytes!("static/main.js"))?;
write(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
include_bytes!("static/settings.js"))?;

{
let mut data = format!("var resourcesSuffix = \"{}\";\n",
Expand Down Expand Up @@ -1575,6 +1580,51 @@ impl fmt::Display for AllTypes {
}
}

#[derive(Debug)]
struct Settings<'a> {
// (id, explanation, default value)
settings: Vec<(&'static str, &'static str, bool)>,
root_path: &'a str,
suffix: &'a str,
}

impl<'a> Settings<'a> {
pub fn new(root_path: &'a str, suffix: &'a str) -> Settings<'a> {
Settings {
settings: vec![
("item-declarations", "Auto-hide item declarations.", true),
("item-attributes", "Auto-hide item attributes.", true),
],
root_path,
suffix,
}
}
}

impl<'a> fmt::Display for Settings<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"<h1 class='fqn'>\
<span class='in-band'>Rustdoc settings</span>\
</h1>\
<div class='settings'>{}</div>\
<script src='{}settings{}.js'></script>",
self.settings.iter()
.map(|(id, text, enabled)| {
format!("<div class='setting-line'>\
<label class='toggle'>\
<input type='checkbox' id='{}' {}>\
<span class='slider'></span>\
</label>\
<div>{}</div>\
</div>", id, if *enabled { " checked" } else { "" }, text)
})
.collect::<String>(),
self.root_path,
self.suffix)
}
}

impl Context {
/// String representation of how to get back to the root path of the 'doc/'
/// folder in terms of a relative URL.
Expand Down Expand Up @@ -1618,6 +1668,8 @@ impl Context {
};
let final_file = self.dst.join(&krate.name)
.join("all.html");
let settings_file = self.dst.join("settings.html");

let crate_name = krate.name.clone();
item.name = Some(krate.name);

Expand All @@ -1639,7 +1691,7 @@ impl Context {
if !root_path.ends_with('/') {
root_path.push('/');
}
let page = layout::Page {
let mut page = layout::Page {
title: "List of all items in this crate",
css_class: "mod",
root_path: "../",
Expand All @@ -1662,6 +1714,27 @@ impl Context {
self.shared.css_file_extension.is_some(),
&self.shared.themes),
&final_file);

// Generating settings page.
let settings = Settings::new("./", &self.shared.resource_suffix);
page.title = "Rustdoc settings";
page.description = "Settings of Rustdoc";
page.root_path = "./";

let mut w = BufWriter::new(try_err!(File::create(&settings_file), &settings_file));
let mut themes = self.shared.themes.clone();
let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>";
themes.push(PathBuf::from("settings.css"));
let mut layout = self.shared.layout.clone();
layout.krate = String::new();
layout.logo = String::new();
layout.favicon = String::new();
try_err!(layout::render(&mut w, &layout,
&page, &sidebar, &settings,
self.shared.css_file_extension.is_some(),
&themes),
&settings_file);

Ok(())
}

Expand Down
26 changes: 11 additions & 15 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,13 @@
return false;
}
var end = start + className.length;
if (end < elemClass.length && elemClass[end] !== ' ') {
return false;
}
return true;
return !(end < elemClass.length && elemClass[end] !== ' ');
}
if (start > 0 && elemClass[start - 1] !== ' ') {
return false;
}
var end = start + className.length;
if (end < elemClass.length && elemClass[end] !== ' ') {
return false;
}
return true;
return !(end < elemClass.length && elemClass[end] !== ' ');
}
return false;
}
Expand Down Expand Up @@ -320,7 +314,7 @@
} else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) {
var prev_id = 0;

var set_fragment = function (name) {
var set_fragment = function(name) {
if (browserSupportsHistoryApi()) {
history.replaceState(null, null, '#' + name);
window.hashchange();
Expand Down Expand Up @@ -835,7 +829,7 @@
query.search = val;
// searching by type
} else if (val.search("->") > -1) {
var trimmer = function (s) { return s.trim(); };
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
Expand Down Expand Up @@ -1559,7 +1553,7 @@
startSearch();

// Draw a convenient sidebar of known crates if we have a listing
if (rootPath === '../') {
if (rootPath === '../' || rootPath === "./") {
var sidebar = document.getElementsByClassName('sidebar-elems')[0];
if (sidebar) {
var div = document.createElement('div');
Expand All @@ -1578,11 +1572,11 @@
crates.sort();
for (var i = 0; i < crates.length; ++i) {
var klass = 'crate';
if (crates[i] === window.currentCrate) {
if (rootPath !== "./" && crates[i] === window.currentCrate) {
klass += ' current';
}
var link = document.createElement('a');
link.href = '../' + crates[i] + '/index.html';
link.href = rootPath + crates[i] + '/index.html';
link.title = rawSearchIndex[crates[i]].doc;
link.className = klass;
link.textContent = crates[i];
Expand Down Expand Up @@ -1959,7 +1953,7 @@
otherMessage = '&nbsp;Show&nbsp;type&nbsp;declaration';
}
e.parentNode.insertBefore(createToggle(otherMessage), e);
if (otherMessage) {
if (otherMessage && getCurrentValue('rustdoc-item-declarations') !== "false") {
collapseDocs(e.previousSibling.childNodes[0], "toggle");
}
}
Expand Down Expand Up @@ -2029,7 +2023,9 @@
onEach(document.getElementById('main').getElementsByTagName('pre'), function(e) {
onEach(e.getElementsByClassName('attributes'), function(i_e) {
i_e.parentNode.insertBefore(createToggleWrapper(), i_e);
collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
if (getCurrentValue("rustdoc-item-attributes") !== "false") {
collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
}
});
});

Expand Down
19 changes: 17 additions & 2 deletions src/librustdoc/html/static/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,16 @@ a {

.block a.current.crate { font-weight: 500; }

.search-container {
position: relative;
}
.search-container > .top-button {
position: absolute;
right: 0;
top: 10px;
}
.search-input {
width: 100%;
width: calc(100% - 34px);
/* Override Normalize.css: we have margins and do
not want to overflow - the `moz` attribute is necessary
until Firefox 29, too early to drop at this point */
Expand Down Expand Up @@ -1224,7 +1232,14 @@ kbd {
outline: none;
}

#theme-picker {
#settings-menu {
position: absolute;
right: 0;
top: 10px;
outline: none;
}

#theme-picker, #settings-menu {
padding: 4px;
width: 27px;
height: 29px;
Expand Down
73 changes: 73 additions & 0 deletions src/librustdoc/html/static/settings.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* 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.
*/

.setting-line {
padding: 5px;
}

.setting-line > div {
max-width: calc(100% - 74px);
display: inline-block;
vertical-align: top;
font-size: 17px;
padding-top: 2px;
}

.toggle {
position: relative;
display: inline-block;
width: 45px;
height: 27px;
margin-right: 20px;
}

.toggle input {
display: none;
}

.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .3s;
transition: .3s;
}

.slider:before {
position: absolute;
content: "";
height: 19px;
width: 19px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .3s;
transition: .3s;
}

input:checked + .slider {
background-color: #2196F3;
}

input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}

input:checked + .slider:before {
-webkit-transform: translateX(19px);
-ms-transform: translateX(19px);
transform: translateX(19px);
}
41 changes: 41 additions & 0 deletions src/librustdoc/html/static/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*!
* 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.
*/

(function () {
function changeSetting(settingName, isEnabled) {
updateLocalStorage('rustdoc-' + settingName, isEnabled);
}

function getSettingValue(settingName) {
return getCurrentValue('rustdoc-' + settingName);
}

function setEvents() {
var elems = document.getElementsByClassName("slider");
if (!elems || elems.length === 0) {
return;
}
for (var i = 0; i < elems.length; ++i) {
var toggle = elems[i].previousElementSibling;
var settingId = toggle.id;
var settingValue = getSettingValue(settingId);
if (settingValue !== null) {
toggle.checked = settingValue === "true";
}
toggle.onchange = function() {
changeSetting(this.id, this.checked);
};
}
}

setEvents();
})();
Loading

0 comments on commit 28193e8

Please sign in to comment.