diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 27dea8ec0b312..1fe52353449ba 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2888,9 +2888,6 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite })() .unwrap_or(rustc_span::DUMMY_SP); - // The root path is the inverse of Context::current - let root_path = vec!["../"; cx.current.len() - 1].join(""); - let mut decoration_info = FxHashMap::default(); decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]); decoration_info.insert("highlight", byte_ranges); @@ -2900,7 +2897,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite contents_subset, file_span, cx, - &root_path, + &cx.root_path(), highlight::DecorationInfo(decoration_info), sources::SourceContext::Embedded { offset: line_min, needs_expansion }, ); diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 8a01c01049d6e..50135d6019006 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -276,25 +276,26 @@ pub(crate) fn print_src( let mut line_numbers = Buffer::empty_from(buf); let extra; line_numbers.write_str("
");
+ let current_href = &context
+ .href_from_span(clean::Span::new(file_span), false)
+ .expect("only local crates should have sources emitted");
match source_context {
SourceContext::Standalone => {
extra = None;
for line in 1..=lines {
- writeln!(line_numbers, "{0}", line)
+ writeln!(line_numbers, "{line}")
}
}
SourceContext::Embedded { offset, needs_expansion } => {
extra =
if needs_expansion { Some(r#""#) } else { None };
- for line in 1..=lines {
- writeln!(line_numbers, "{0}", line + offset)
+ for line_number in 1..=lines {
+ let line = line_number + offset;
+ writeln!(line_numbers, "{line}")
}
}
}
line_numbers.write_str("");
- let current_href = &context
- .href_from_span(clean::Span::new(file_span), false)
- .expect("only local crates should have sources emitted");
highlight::render_source_with_highlighting(
s,
buf,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 894499e5c4fc9..bbcce72666852 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -575,15 +575,16 @@ ul.block, .block li {
border-color: var(--example-line-numbers-border-color);
}
-.src-line-numbers span {
- cursor: pointer;
+.src-line-numbers a, .src-line-numbers span {
color: var(--src-line-numbers-span-color);
}
-.src-line-numbers .line-highlighted {
- background-color: var(--src-line-number-highlighted-background-color);
-}
.src-line-numbers :target {
background-color: transparent;
+ border-right: none;
+ padding-right: 0;
+}
+.src-line-numbers .line-highlighted {
+ background-color: var(--src-line-number-highlighted-background-color);
}
.search-loading {
@@ -2060,6 +2061,7 @@ in storage.js
padding: 14px 0;
}
+.scraped-example .code-wrapper .src-line-numbers a,
.scraped-example .code-wrapper .src-line-numbers span {
padding: 0 14px;
}
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index 0b9368dd89948..5db768c1c5753 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -157,7 +157,7 @@ function highlightSourceLines(match) {
x.scrollIntoView();
}
onEachLazy(document.getElementsByClassName("src-line-numbers"), e => {
- onEachLazy(e.getElementsByTagName("span"), i_e => {
+ onEachLazy(e.getElementsByTagName("a"), i_e => {
removeClass(i_e, "line-highlighted");
});
});
@@ -188,8 +188,13 @@ const handleSourceHighlight = (function() {
return ev => {
let cur_line_id = parseInt(ev.target.id, 10);
- // It can happen when clicking not on a line number span.
- if (isNaN(cur_line_id)) {
+ // This event handler is attached to the entire line number column, but it should only
+ // be run if one of the anchors is clicked. It also shouldn't do anything if the anchor
+ // is clicked with a modifier key (to open a new browser tab).
+ if (isNaN(cur_line_id) ||
+ ev.ctrlKey ||
+ ev.altKey ||
+ ev.metaKey) {
return;
}
ev.preventDefault();
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index a2dac2aa681d5..c71a3d64d0c8a 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -2,17 +2,22 @@
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
show-text: true
// Check that we can click on the line number.
-click: ".src-line-numbers > span:nth-child(4)" // This is the span for line 4.
+click: ".src-line-numbers > a:nth-child(4)" // This is the anchor for line 4.
// Ensure that the page URL was updated.
assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH)
assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"})
-// We now check that the good spans are highlighted
+// Ensure that the default style, with the right border, isn't used.
+assert-css: ("//*[@id='4']", {"border-right-width": "0px"})
+reload:
+assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"})
+assert-css: ("//*[@id='4']", {"border-right-width": "0px"})
+// We now check that the good anchors are highlighted
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4-6"
-assert-attribute-false: (".src-line-numbers > span:nth-child(3)", {"class": "line-highlighted"})
-assert-attribute: (".src-line-numbers > span:nth-child(4)", {"class": "line-highlighted"})
-assert-attribute: (".src-line-numbers > span:nth-child(5)", {"class": "line-highlighted"})
-assert-attribute: (".src-line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
-assert-attribute-false: (".src-line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
+assert-attribute-false: (".src-line-numbers > a:nth-child(3)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > a:nth-child(4)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > a:nth-child(5)", {"class": "line-highlighted"})
+assert-attribute: (".src-line-numbers > a:nth-child(6)", {"class": "line-highlighted"})
+assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-highlighted"})
define-function: (
"check-colors",
@@ -21,12 +26,12 @@ define-function: (
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
("reload"),
("assert-css", (
- ".src-line-numbers > span:not(.line-highlighted)",
+ ".src-line-numbers > a:not(.line-highlighted)",
{"color": |color|, "background-color": |background_color|},
ALL,
)),
("assert-css", (
- ".src-line-numbers > span.line-highlighted",
+ ".src-line-numbers > a.line-highlighted",
{"color": |highlight_color|, "background-color": |highlight_background_color|},
ALL,
)),
@@ -57,6 +62,25 @@ call-function: ("check-colors", {
// This is to ensure that the content is correctly align with the line numbers.
compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))
+// Check the `href` property so that users can treat anchors as links.
+assert-property: (".src-line-numbers > a:nth-child(1)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#1"
+})
+assert-property: (".src-line-numbers > a:nth-child(2)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#2"
+})
+assert-property: (".src-line-numbers > a:nth-child(3)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#3"
+})
+assert-property: (".src-line-numbers > a:nth-child(4)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4"
+})
+assert-property: (".src-line-numbers > a:nth-child(5)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#5"
+})
+assert-property: (".src-line-numbers > a:nth-child(6)", {
+ "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#6"
+})
// Assert that the line numbers text is aligned to the right.
assert-css: (".src-line-numbers", {"text-align": "right"})
@@ -66,7 +90,7 @@ assert-css: (".src-line-numbers", {"text-align": "right"})
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
// We use this assert-position to know where we will click.
assert-position: ("//*[@id='1']", {"x": 104, "y": 112})
-// We click on the left of the "1" span but still in the "src-line-number" ``.
+// We click on the left of the "1" anchor but still in the "src-line-number" ``.
click: (103, 103)
assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs
index d00a3e3551991..5959f9c7c5992 100644
--- a/src/test/rustdoc/check-source-code-urls-to-def.rs
+++ b/src/test/rustdoc/check-source-code-urls-to-def.rs
@@ -10,14 +10,14 @@ extern crate source_code;
// @has 'src/foo/check-source-code-urls-to-def.rs.html'
-// @has - '//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#1-17"]' 'bar'
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#1-17"]' 'bar'
#[path = "auxiliary/source-code-bar.rs"]
pub mod bar;
-// @count - '//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#5"]' 4
+// @count - '//pre[@class="rust"]//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#5"]' 4
use bar::Bar;
-// @has - '//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#13"]' 'self'
-// @has - '//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#14"]' 'Trait'
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#13"]' 'self'
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#14"]' 'Trait'
use bar::sub::{self, Trait};
pub struct Foo;
@@ -28,29 +28,29 @@ impl Foo {
fn babar() {}
-// @has - '//a/@href' '/struct.String.html'
-// @has - '//a/@href' '/primitive.u32.html'
-// @has - '//a/@href' '/primitive.str.html'
-// @count - '//a[@href="#23"]' 5
-// @has - '//a[@href="https://github.com/source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
+// @has - '//pre[@class="rust"]//a/@href' '/struct.String.html'
+// @has - '//pre[@class="rust"]//a/@href' '/primitive.u32.html'
+// @has - '//pre[@class="rust"]//a/@href' '/primitive.str.html'
+// @count - '//pre[@class="rust"]//a[@href="#23"]' 5
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/source_code/struct.SourceCode.html"]' 'source_code::SourceCode'
pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) {
let x = 12;
let y: Foo = Foo;
let z: Bar = bar::Bar { field: Foo };
babar();
- // @has - '//a[@href="#26"]' 'hello'
+ // @has - '//pre[@class="rust"]//a[@href="#26"]' 'hello'
y.hello();
}
-// @has - '//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait'
-// @has - '//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#14"]' 'Trait'
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait'
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/auxiliary/source-code-bar.rs.html#14"]' 'Trait'
pub fn foo2(t: &T, v: &V, b: bool) {}
pub trait AnotherTrait {}
pub trait WhyNot {}
-// @has - '//a[@href="#49"]' 'AnotherTrait'
-// @has - '//a[@href="#50"]' 'WhyNot'
+// @has - '//pre[@class="rust"]//a[@href="#49"]' 'AnotherTrait'
+// @has - '//pre[@class="rust"]//a[@href="#50"]' 'WhyNot'
pub fn foo3(t: &T, v: &V)
where
T: AnotherTrait,
@@ -59,11 +59,11 @@ where
pub trait AnotherTrait2 {}
-// @has - '//a[@href="#60"]' 'AnotherTrait2'
+// @has - '//pre[@class="rust"]//a[@href="#60"]' 'AnotherTrait2'
pub fn foo4() {
let x: Vec = Vec::new();
}
-// @has - '//a[@href="https://github.com/foo/primitive.bool.html"]' 'bool'
+// @has - '//pre[@class="rust"]//a[@href="https://github.com/foo/primitive.bool.html"]' 'bool'
#[doc(primitive = "bool")]
mod whatever {}