From ba3099f60b25437b7a871a3dfe7aa71bf867cd90 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 14 Feb 2025 17:34:29 +0100 Subject: Add support for macro expansion in rustdoc source code pages --- src/librustdoc/html/static/css/rustdoc.css | 57 +++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'src/librustdoc/html/static/css/rustdoc.css') diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index dc27d7943d9..9403701d454 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -956,14 +956,55 @@ rustdoc-topbar { .example-wrap.digits-8 { --example-wrap-digits-count: 8ch; } .example-wrap.digits-9 { --example-wrap-digits-count: 9ch; } -.example-wrap [data-nosnippet] { +.example-wrap .expansion { + position: relative; + display: inline; +} +.example-wrap .expansion > input { + display: none; +} +.example-wrap .expansion > label { + position: absolute; + left: -20px; + top: 0; + border: 1px solid var(--border-color); + border-radius: 4px; + cursor: pointer; + color: var(--main-color); + padding: 0 2px; + line-height: 20px; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + +} +.example-wrap .expansion .expanded { + display: none; + color: var(--main-color); +} +.example-wrap .expansion > input:checked ~ .expanded, +.example-wrap .expansion > input:checked ~ * .expanded { + display: inherit; +} +.example-wrap .expansion > input:checked ~ .original, +.example-wrap .expansion > input:checked ~ * .original { + display: none; +} + +.src .example-wrap [data-nosnippet] { width: calc(var(--example-wrap-digits-count) + var(--line-number-padding) * 2); } -.example-wrap pre > code { +.src .example-wrap pre > code { padding-left: calc( var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + var(--line-number-right-margin)); } +.src .example-wrap .expansion [data-nosnippet] { + left: calc(( + var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + + var(--line-number-right-margin)) * -1); +} .example-wrap [data-nosnippet] { color: var(--src-line-numbers-span-color); @@ -978,23 +1019,21 @@ rustdoc-topbar { position: absolute; left: 0; } -.example-wrap .line-highlighted[data-nosnippet] { - background-color: var(--src-line-number-highlighted-background-color); -} .example-wrap pre > code { position: relative; - display: block; -} -:root.word-wrap-source-code .example-wrap pre > code { word-break: break-all; + display: block; white-space: pre-wrap; } -:root.word-wrap-source-code .example-wrap pre > code * { +.example-wrap pre > code * { word-break: break-all; } .example-wrap [data-nosnippet]:target { border-right: none; } +.example-wrap .line-highlighted[data-nosnippet] { + background-color: var(--src-line-number-highlighted-background-color); +} .example-wrap.hide-lines [data-nosnippet] { display: none; } -- cgit 1.4.1-3-g733a5 From 6c1b481e7bc6cdce1646c53beaa9112d2f7b1d9f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 24 Feb 2025 18:13:50 +0100 Subject: Correctly handle multiple macro expansions on a same line --- src/librustdoc/html/highlight.rs | 57 ++++++++++++++++++++++-------- src/librustdoc/html/static/css/rustdoc.css | 10 +++--- 2 files changed, 49 insertions(+), 18 deletions(-) (limited to 'src/librustdoc/html/static/css/rustdoc.css') diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 7e362791af9..39fec2cbe69 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -272,14 +272,25 @@ fn empty_line_number(out: &mut impl Write, _: u32, extra: &'static str) { out.write_str(extra).unwrap(); } +fn get_next_expansion<'a>( + expanded_codes: Option<&'a Vec>, + line: u32, + span: Span, +) -> Option<&'a ExpandedCode> { + if let Some(expanded_codes) = expanded_codes { + expanded_codes.iter().find(|code| code.start_line == line && code.span.lo() >= span.lo()) + } else { + None + } +} + fn get_expansion<'a, W: Write>( token_handler: &mut TokenHandler<'_, '_, W>, expanded_codes: Option<&'a Vec>, line: u32, + span: Span, ) -> Option<&'a ExpandedCode> { - if let Some(expanded_codes) = expanded_codes - && let Some(expanded_code) = expanded_codes.iter().find(|code| code.start_line == line) - { + if let Some(expanded_code) = get_next_expansion(expanded_codes, line, span) { let (closing, reopening) = if let Some(current_class) = token_handler.current_class && let class = current_class.as_html() && !class.is_empty() @@ -314,10 +325,21 @@ fn start_expansion(out: &mut Vec<(Cow<'_, str>, Option)>, expanded_code: )); } -fn end_expansion(token_handler: &mut TokenHandler<'_, '_, W>, level: usize) { +fn end_expansion<'a, W: Write>( + token_handler: &mut TokenHandler<'_, '_, W>, + expanded_codes: Option<&'a Vec>, + level: usize, + line: u32, + span: Span, +) -> Option<&'a ExpandedCode> { + if let Some(expanded_code) = get_next_expansion(expanded_codes, line, span) { + // We close the current "original" content. + token_handler.pending_elems.push((Cow::Borrowed(""), Some(Class::Expansion))); + return Some(expanded_code); + } if level == 0 { token_handler.pending_elems.push((Cow::Borrowed(""), Some(Class::Expansion))); - return; + return None; } let mut out = String::new(); let mut end = String::new(); @@ -330,6 +352,7 @@ fn end_expansion(token_handler: &mut TokenHandler<'_, '_, W>, level: u token_handler .pending_elems .push((Cow::Owned(format!("{out}{end}")), Some(Class::Expansion))); + None } #[derive(Clone, Copy)] @@ -399,11 +422,14 @@ pub(super) fn write_code( (0, u32::MAX) }; - let expanded_codes = token_handler - .href_context - .as_ref() - .and_then(|c| c.context.shared.expanded_codes.get(&c.file_span.lo())); - let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, line); + let (expanded_codes, file_span) = match token_handler.href_context.as_ref().and_then(|c| { + let expanded_codes = c.context.shared.expanded_codes.get(&c.file_span.lo())?; + Some((expanded_codes, c.file_span)) + }) { + Some((expanded_codes, file_span)) => (Some(expanded_codes), file_span), + None => (None, DUMMY_SP), + }; + let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, line, file_span); token_handler.write_pending_elems(None); let mut level = 0; @@ -443,7 +469,8 @@ pub(super) fn write_code( .push((Cow::Borrowed(text), Some(Class::Backline(line)))); } if current_expansion.is_none() { - current_expansion = get_expansion(&mut token_handler, expanded_codes, line); + current_expansion = + get_expansion(&mut token_handler, expanded_codes, line, span); } } else { token_handler.pending_elems.push((Cow::Borrowed(text), class)); @@ -459,9 +486,11 @@ pub(super) fn write_code( } } if need_end { - end_expansion(&mut token_handler, level); - current_expansion = None; - level = 0; + current_expansion = + end_expansion(&mut token_handler, expanded_codes, level, line, span); + if current_expansion.is_none() { + level = 0; + } } } } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9403701d454..f3dafffbb6b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -992,10 +992,10 @@ rustdoc-topbar { display: none; } -.src .example-wrap [data-nosnippet] { +.example-wrap [data-nosnippet] { width: calc(var(--example-wrap-digits-count) + var(--line-number-padding) * 2); } -.src .example-wrap pre > code { +.example-wrap pre > code { padding-left: calc( var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + var(--line-number-right-margin)); @@ -1021,11 +1021,13 @@ rustdoc-topbar { } .example-wrap pre > code { position: relative; - word-break: break-all; display: block; +} +:root.word-wrap-source-code .example-wrap pre > code { + word-break: break-all; white-space: pre-wrap; } -.example-wrap pre > code * { +:root.word-wrap-source-code .example-wrap pre > code * { word-break: break-all; } .example-wrap [data-nosnippet]:target { -- cgit 1.4.1-3-g733a5 From 3de3b279f0e2490ed1a76f4a9abe75656a1c0dab Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 May 2025 14:07:23 +0200 Subject: Go around firefox bug --- src/librustdoc/html/static/css/rustdoc.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/librustdoc/html/static/css/rustdoc.css') diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index f3dafffbb6b..0b7a8abdf09 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1001,7 +1001,13 @@ rustdoc-topbar { + var(--line-number-right-margin)); } .src .example-wrap .expansion [data-nosnippet] { - left: calc(( + /* FIXME: Once is solved, uncomment + next line and remove the two other rules. */ + /*left: calc(( + var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + + var(--line-number-right-margin)) * -1);*/ + position: initial; + margin-left: calc(( var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + var(--line-number-right-margin)) * -1); } -- cgit 1.4.1-3-g733a5 From b968ef8d198046bce1c77381a8069d2f837a2455 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 26 May 2025 15:04:48 +0200 Subject: Make macro expansion feature buttons accessible --- src/librustdoc/html/highlight.rs | 7 +++-- src/librustdoc/html/static/css/rustdoc.css | 14 ++++----- tests/rustdoc-gui/macro-expansion.goml | 49 +++++++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 15 deletions(-) (limited to 'src/librustdoc/html/static/css/rustdoc.css') diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 5a25d659b0f..40530f67d6e 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -332,8 +332,11 @@ fn get_expansion<'a, W: Write>( Cow::Owned(format!( "{closing}\ \ - \ - {reopening}", + {reopening}", )), Some(Class::Expansion), )); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 0b7a8abdf09..86f1a42bc01 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -961,10 +961,10 @@ rustdoc-topbar { display: inline; } .example-wrap .expansion > input { - display: none; -} -.example-wrap .expansion > label { + display: block; position: absolute; + appearance: none; + content: '↕'; left: -20px; top: 0; border: 1px solid var(--border-color); @@ -973,11 +973,9 @@ rustdoc-topbar { color: var(--main-color); padding: 0 2px; line-height: 20px; - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - +} +.example-wrap .expansion > input::after { + content: "↕"; } .example-wrap .expansion .expanded { display: none; diff --git a/tests/rustdoc-gui/macro-expansion.goml b/tests/rustdoc-gui/macro-expansion.goml index c398c58adac..5e9a3049405 100644 --- a/tests/rustdoc-gui/macro-expansion.goml +++ b/tests/rustdoc-gui/macro-expansion.goml @@ -12,14 +12,14 @@ define-function: ( assert-css: ("a[id='" + |line| + "'] + .expansion .expanded", {"display": "none"}) // We "expand" the macro. - click: "a[id='" + |line| + "'] + .expansion label" + click: "a[id='" + |line| + "'] + .expansion input[type=checkbox]" // The "original" content is hidden. assert-css: ("a[id='" + |line| + "'] + .expansion .original", {"display": "none"}) // The expanded macro is visible. assert-css: ("a[id='" + |line| + "'] + .expansion .expanded", {"display": "inline"}) // We collapse the macro. - click: "a[id='" + |line| + "'] + .expansion label" + click: "a[id='" + |line| + "'] + .expansion input[type=checkbox]" // The "original" content is expanded. assert-css: ("a[id='" + |line| + "'] + .expansion .original", {"display": "inline"}) // The expanded macro is hidden. @@ -31,7 +31,7 @@ define-function: ( call-function: ("check-expansion", {"line": 33, "original_content": "Debug"}) // Then we check the `bar` macro expansion at line 41. call-function: ("check-expansion", {"line": 41, "original_content": "bar!(y)"}) -// Then we check the `println` macro expansion at line 23-25. +// Then we check the `println` macro expansion at line 42-44. call-function: ("check-expansion", {"line": 42, "original_content": 'println!(" 43 {y} 44 ")'}) @@ -56,7 +56,7 @@ assert-css: ('//*[@id="expand-50"]' + |repeat_e| + |repeat_e|, {"display": "none // We "expand" the macro (because the line starts with a string, the label is not at the "top // level" of the ``, so we need to use a different selector). -click: ".expansion label[for='expand-50']" +click: "#expand-50" // The "original" content is hidden. assert-css: ('//*[@id="expand-50"]' + |repeat_o|, {"display": "none"}) assert-css: ('//*[@id="expand-50"]' + |repeat_o| + |repeat_o|, {"display": "none"}) @@ -65,10 +65,49 @@ assert-css: ('//*[@id="expand-50"]' + |repeat_e|, {"display": "inline"}) assert-css: ('//*[@id="expand-50"]' + |repeat_e| + |repeat_e|, {"display": "inline"}) // We collapse the macro. -click: ".expansion label[for='expand-50']" +click: "#expand-50" // The "original" content is expanded. assert-css: ('//*[@id="expand-50"]' + |repeat_o|, {"display": "inline"}) assert-css: ('//*[@id="expand-50"]' + |repeat_o| + |repeat_o|, {"display": "inline"}) // The expanded macro is hidden. assert-css: ('//*[@id="expand-50"]' + |repeat_e|, {"display": "none"}) assert-css: ('//*[@id="expand-50"]' + |repeat_e| + |repeat_e|, {"display": "none"}) + +// Checking the line 46 `println` which needs to be handled differently because the line number is +// inside a "comment" span. +assert-text: ("#expand-46 ~ .original", 'println!(" +47 {y} +48 ")') +// The "original" content should be expanded. +assert-css: ("#expand-46 ~ .original", {"display": "inline"}) +// The expanded macro should be hidden. +assert-css: ("#expand-46 ~ .expanded", {"display": "none"}) + +// We "expand" the macro. +click: "#expand-46" +// The "original" content is hidden. +assert-css: ("#expand-46 ~ .original", {"display": "none"}) +// The expanded macro is visible. +assert-css: ("#expand-46 ~ .expanded", {"display": "inline"}) + +// We collapse the macro. +click: "#expand-46" +// The "original" content is expanded. +assert-css: ("#expand-46 ~ .original", {"display": "inline"}) +// The expanded macro is hidden. +assert-css: ("#expand-46 ~ .expanded", {"display": "none"}) + +// Ensure that the toggles are focusable and can be interacted with keyboard. +focus: "//a[@id='27']" +press-key: "Tab" +assert: "#expand-27:focus" +assert-css: ("#expand-27 ~ .expanded", {"display": "none"}) +assert-css: ("#expand-27 ~ .original", {"display": "inline"}) +// We now expand the macro. +press-key: "Space" +assert-css: ("#expand-27 ~ .expanded", {"display": "inline"}) +assert-css: ("#expand-27 ~ .original", {"display": "none"}) +// We collapse the macro. +press-key: "Space" +assert-css: ("#expand-27 ~ .expanded", {"display": "none"}) +assert-css: ("#expand-27 ~ .original", {"display": "inline"}) -- cgit 1.4.1-3-g733a5