diff options
| author | Oliver Middleton <olliemail27@gmail.com> | 2016-10-11 09:56:30 +0100 |
|---|---|---|
| committer | Oliver Middleton <olliemail27@gmail.com> | 2016-10-15 18:32:03 +0100 |
| commit | 0b2746c8db6fc11965b1b6fd1d8536309a0d98b6 (patch) | |
| tree | adbfb9474dbe8dd1810f1669fefaf757627fd42e /src | |
| parent | 8e05e7ee3c19a5594b79d67c8390cef78970be7c (diff) | |
| download | rust-0b2746c8db6fc11965b1b6fd1d8536309a0d98b6.tar.gz rust-0b2746c8db6fc11965b1b6fd1d8536309a0d98b6.zip | |
rustdoc: Improve playground run buttons
The main change is to stop using javascript to generate the URLs and use rustdoc instead. This also adds run buttons to the error index examples.
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc/footer.inc | 1 | ||||
| -rw-r--r-- | src/doc/rust.css | 8 | ||||
| -rw-r--r-- | src/librustdoc/html/layout.rs | 9 | ||||
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 43 | ||||
| -rw-r--r-- | src/librustdoc/html/render.rs | 8 | ||||
| -rw-r--r-- | src/librustdoc/html/static/extra.js | 25 | ||||
| -rw-r--r-- | src/librustdoc/html/static/playpen.js | 48 | ||||
| -rw-r--r-- | src/librustdoc/html/static/rustdoc.css | 1 | ||||
| -rw-r--r-- | src/librustdoc/markdown.rs | 10 | ||||
| -rw-r--r-- | src/librustdoc/test.rs | 2 | ||||
| -rw-r--r-- | src/test/rustdoc/playground-empty.rs | 21 | ||||
| -rw-r--r-- | src/test/rustdoc/playground-none.rs | 19 | ||||
| -rw-r--r-- | src/test/rustdoc/playground.rs | 39 | ||||
| -rw-r--r-- | src/tools/error_index_generator/main.rs | 5 | ||||
| -rw-r--r-- | src/tools/rustbook/build.rs | 7 |
15 files changed, 131 insertions, 115 deletions
diff --git a/src/doc/footer.inc b/src/doc/footer.inc index 7513e524e73..77e151235e8 100644 --- a/src/doc/footer.inc +++ b/src/doc/footer.inc @@ -5,4 +5,3 @@ or the <a href="https://opensource.org/licenses/MIT">MIT license</a>, at your op </p><p> This file may not be copied, modified, or distributed except according to those terms. </p></footer> -<script type="text/javascript" src="playpen.js"></script> diff --git a/src/doc/rust.css b/src/doc/rust.css index 262db5673e8..932594b9912 100644 --- a/src/doc/rust.css +++ b/src/doc/rust.css @@ -336,13 +336,11 @@ table th { /* Code snippets */ -.rusttest { display: none; } pre.rust { position: relative; } a.test-arrow { + background-color: rgba(78, 139, 202, 0.2); display: inline-block; position: absolute; - - background-color: #4e8bca; color: #f5f5f5; padding: 5px 10px 5px 10px; border-radius: 5px; @@ -350,6 +348,10 @@ a.test-arrow { top: 5px; right: 5px; } +a.test-arrow:hover{ + background-color: #4e8bca; + text-decoration: none; +} .unstable-feature { border: 2px solid red; diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index b7c5876c4f9..5353642e294 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -19,7 +19,6 @@ pub struct Layout { pub favicon: String, pub external_html: ExternalHtml, pub krate: String, - pub playground_url: String, } pub struct Page<'a> { @@ -136,11 +135,9 @@ r##"<!DOCTYPE html> <script> window.rootPath = "{root_path}"; window.currentCrate = "{krate}"; - window.playgroundUrl = "{play_url}"; </script> <script src="{root_path}jquery.js"></script> <script src="{root_path}main.js"></script> - {play_js} <script defer src="{root_path}search-index.js"></script> </body> </html>"##, @@ -174,12 +171,6 @@ r##"<!DOCTYPE html> after_content = layout.external_html.after_content, sidebar = *sidebar, krate = layout.krate, - play_url = layout.playground_url, - play_js = if layout.playground_url.is_empty() { - format!(r#"<script src="{}extra.js"></script>"#, page.root_path) - } else { - format!(r#"<script src="{}playpen.js"></script>"#, page.root_path) - } ) } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index e9a1f650c9b..f12349e5b7c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -31,7 +31,7 @@ use std::ascii::AsciiExt; use std::cell::RefCell; use std::default::Default; use std::ffi::CString; -use std::fmt; +use std::fmt::{self, Write}; use std::slice; use std::str; use syntax::feature_gate::UnstableFeatures; @@ -214,7 +214,9 @@ fn collapse_whitespace(s: &str) -> String { s.split_whitespace().collect::<Vec<_>>().join(" ") } -thread_local!(pub static PLAYGROUND_KRATE: RefCell<Option<Option<String>>> = { +// Information about the playground if a URL has been specified, containing an +// optional crate name and the URL. +thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> = { RefCell::new(None) }); @@ -248,24 +250,53 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { }); let text = lines.collect::<Vec<&str>>().join("\n"); if rendered { return } - PLAYGROUND_KRATE.with(|krate| { + PLAYGROUND.with(|play| { // insert newline to clearly separate it from the // previous block so we can shorten the html output let mut s = String::from("\n"); - krate.borrow().as_ref().map(|krate| { + let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| { + if url.is_empty() { + return None; + } let test = origtext.lines().map(|l| { stripped_filtered_line(l).unwrap_or(l) }).collect::<Vec<&str>>().join("\n"); let krate = krate.as_ref().map(|s| &**s); let test = test::maketest(&test, krate, false, &Default::default()); - s.push_str(&format!("<span class='rusttest'>{}</span>", Escape(&test))); + let channel = if test.contains("#![feature(") { + "&version=nightly" + } else { + "" + }; + // These characters don't need to be escaped in a URI. + // FIXME: use a library function for percent encoding. + fn dont_escape(c: u8) -> bool { + (b'a' <= c && c <= b'z') || + (b'A' <= c && c <= b'Z') || + (b'0' <= c && c <= b'9') || + c == b'-' || c == b'_' || c == b'.' || + c == b'~' || c == b'!' || c == b'\'' || + c == b'(' || c == b')' || c == b'*' + } + let mut test_escaped = String::new(); + for b in test.bytes() { + if dont_escape(b) { + test_escaped.push(char::from(b)); + } else { + write!(test_escaped, "%{:02X}", b).unwrap(); + } + } + Some(format!( + r#"<a class="test-arrow" target="_blank" href="{}?code={}{}">Run</a>"#, + url, test_escaped, channel + )) }); s.push_str(&highlight::render_with_highlighting( &text, Some("rust-example-rendered"), None, - Some("<a class='test-arrow' target='_blank' href=''>Run</a>"))); + playground_button.as_ref().map(String::as_str))); let output = CString::new(s).unwrap(); hoedown_buffer_puts(ob, output.as_ptr()); }) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d8dba00e7d5..77a5ff3243a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -449,7 +449,6 @@ pub fn run(mut krate: clean::Crate, favicon: "".to_string(), external_html: external_html.clone(), krate: krate.name.clone(), - playground_url: "".to_string(), }, css_file_extension: css_file_extension.clone(), }; @@ -469,11 +468,10 @@ pub fn run(mut krate: clean::Crate, } clean::NameValue(ref x, ref s) if "html_playground_url" == *x => { - scx.layout.playground_url = s.to_string(); - markdown::PLAYGROUND_KRATE.with(|slot| { + markdown::PLAYGROUND.with(|slot| { if slot.borrow().is_none() { let name = krate.name.clone(); - *slot.borrow_mut() = Some(Some(name)); + *slot.borrow_mut() = Some((Some(name), s.clone())); } }); } @@ -659,8 +657,6 @@ fn write_shared(cx: &Context, include_bytes!("static/jquery-2.1.4.min.js"))?; write(cx.dst.join("main.js"), include_bytes!("static/main.js"))?; - write(cx.dst.join("playpen.js"), - include_bytes!("static/playpen.js"))?; write(cx.dst.join("rustdoc.css"), include_bytes!("static/rustdoc.css"))?; write(cx.dst.join("main.css"), diff --git a/src/librustdoc/html/static/extra.js b/src/librustdoc/html/static/extra.js deleted file mode 100644 index d9d97d9b883..00000000000 --- a/src/librustdoc/html/static/extra.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2014-2016 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. - -/*jslint browser: true, es5: true */ -/*globals $: true, rootPath: true */ - -document.addEventListener('DOMContentLoaded', function() { - 'use strict'; - - if (!window.playgroundUrl) { - var runButtons = document.querySelectorAll(".test-arrow"); - - for (var i = 0; i < runButtons.length; i++) { - runButtons[i].classList.remove("test-arrow"); - } - return; - } -}); diff --git a/src/librustdoc/html/static/playpen.js b/src/librustdoc/html/static/playpen.js deleted file mode 100644 index 8d8953d56e1..00000000000 --- a/src/librustdoc/html/static/playpen.js +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014-2015 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. - -/*jslint browser: true, es5: true */ -/*globals $: true, rootPath: true */ - -document.addEventListener('DOMContentLoaded', function() { - 'use strict'; - - if (!window.playgroundUrl) { - var runButtons = document.querySelectorAll(".test-arrow"); - - for (var i = 0; i < runButtons.length; i++) { - runButtons[i].classList.remove("test-arrow"); - } - return; - } - - var featureRegexp = new RegExp('^\s*#!\\[feature\\(\.*?\\)\\]'); - var elements = document.querySelectorAll('pre.rust-example-rendered'); - - Array.prototype.forEach.call(elements, function(el) { - el.onmouseover = function(e) { - if (el.contains(e.relatedTarget)) { - return; - } - - var a = el.querySelectorAll('a.test-arrow')[0]; - - var code = el.previousElementSibling.textContent; - - var channel = ''; - if (featureRegexp.test(code)) { - channel = '&version=nightly'; - } - - a.setAttribute('href', window.playgroundUrl + '?code=' + - encodeURIComponent(code) + channel); - }; - }); -}); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 85ec4fe3f3f..f49b8556f66 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -575,7 +575,6 @@ pre.rust .question-mark { font-weight: bold; } -.rusttest { display: none; } pre.rust { position: relative; } a.test-arrow { background-color: rgba(78, 139, 202, 0.2); diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index f708aa54619..b617acfabbb 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -63,11 +63,9 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches, Err(LoadStringError::ReadFail) => return 1, Err(LoadStringError::BadUtf8) => return 2, }; - let playground = matches.opt_str("markdown-playground-url"); - if playground.is_some() { - markdown::PLAYGROUND_KRATE.with(|s| { *s.borrow_mut() = Some(None); }); + if let Some(playground) = matches.opt_str("markdown-playground-url") { + markdown::PLAYGROUND.with(|s| { *s.borrow_mut() = Some((None, playground)); }); } - let playground = playground.unwrap_or("".to_string()); let mut out = match File::create(&output) { Err(e) => { @@ -119,9 +117,6 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches, {before_content} <h1 class="title">{title}</h1> {text} - <script type="text/javascript"> - window.playgroundUrl = "{playground}"; - </script> {after_content} </body> </html>"#, @@ -131,7 +126,6 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches, before_content = external_html.before_content, text = rendered, after_content = external_html.after_content, - playground = playground, ); match err { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 15fdb0341cb..d1d2b14806f 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -355,7 +355,7 @@ pub fn maketest(s: &str, cratename: Option<&str>, dont_insert_main: bool, if dont_insert_main || s.contains("fn main") { prog.push_str(&everything_else); } else { - prog.push_str("fn main() {\n "); + prog.push_str("fn main() {\n"); prog.push_str(&everything_else); prog = prog.trim().into(); prog.push_str("\n}"); diff --git a/src/test/rustdoc/playground-empty.rs b/src/test/rustdoc/playground-empty.rs new file mode 100644 index 00000000000..00881a62dd0 --- /dev/null +++ b/src/test/rustdoc/playground-empty.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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. + +#![crate_name = "foo"] + +#![doc(html_playground_url = "")] + +//! module docs +//! +//! ``` +//! println!("Hello, world!"); +//! ``` + +// @!has foo/index.html '//a[@class="test-arrow"]' "Run" diff --git a/src/test/rustdoc/playground-none.rs b/src/test/rustdoc/playground-none.rs new file mode 100644 index 00000000000..83c312d7ab2 --- /dev/null +++ b/src/test/rustdoc/playground-none.rs @@ -0,0 +1,19 @@ +// Copyright 2016 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. + +#![crate_name = "foo"] + +//! module docs +//! +//! ``` +//! println!("Hello, world!"); +//! ``` + +// @!has foo/index.html '//a[@class="test-arrow"]' "Run" diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs new file mode 100644 index 00000000000..9eb8dec51a7 --- /dev/null +++ b/src/test/rustdoc/playground.rs @@ -0,0 +1,39 @@ +// Copyright 2016 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-tidy-linelength + +#![crate_name = "foo"] + +#![doc(html_playground_url = "https://www.example.com/")] + +//! module docs +//! +//! ``` +//! println!("Hello, world!"); +//! ``` +//! +//! ``` +//! fn main() { +//! println!("Hello, world!"); +//! } +//! ``` +//! +//! ``` +//! #![feature(something)] +//! +//! fn main() { +//! println!("Hello, world!"); +//! } +//! ``` + +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=fn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=fn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A&version=nightly"]' "Run" diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 7bdf1343aa9..e33df0dfbc8 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -24,7 +24,7 @@ use std::path::PathBuf; use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata}; -use rustdoc::html::markdown::Markdown; +use rustdoc::html::markdown::{Markdown, PLAYGROUND}; use rustc_serialize::json; enum OutputFormat { @@ -201,6 +201,9 @@ fn parse_args() -> (OutputFormat, PathBuf) { } fn main() { + PLAYGROUND.with(|slot| { + *slot.borrow_mut() = Some((None, String::from("https://play.rust-lang.org/"))); + }); let (format, dst) = parse_args(); if let Err(e) = main_with_result(format, &dst) { panic!("{}", e.description()); diff --git a/src/tools/rustbook/build.rs b/src/tools/rustbook/build.rs index 09c2d2510e3..d88ff48843a 100644 --- a/src/tools/rustbook/build.rs +++ b/src/tools/rustbook/build.rs @@ -131,7 +131,6 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { { let mut buffer = BufWriter::new(File::create(&postlude)?); writeln!(&mut buffer, "<script src='rustbook.js'></script>")?; - writeln!(&mut buffer, "<script src='playpen.js'></script>")?; writeln!(&mut buffer, "</div></div>")?; } @@ -143,7 +142,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { format!("-o{}", out_path.display()), format!("--html-before-content={}", prelude.display()), format!("--html-after-content={}", postlude.display()), - format!("--markdown-playground-url=https://play.rust-lang.org"), + format!("--markdown-playground-url=https://play.rust-lang.org/"), format!("--markdown-css={}", item.path_to_root.join("rustbook.css").display()), "--markdown-no-toc".to_string(), ]; @@ -158,10 +157,6 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { // create index.html from the root README fs::copy(&tgt.join("README.html"), &tgt.join("index.html"))?; - // Copy js for playpen - let mut playpen = File::create(tgt.join("playpen.js"))?; - let js = include_bytes!("../../librustdoc/html/static/playpen.js"); - playpen.write_all(js)?; Ok(()) } |
