From 552609754ec0f4750219572831c5b227e99ff171 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Wed, 17 Jul 2024 22:58:33 +0200 Subject: [PATCH 1/2] Add line numbers to `crate/**/source/` --- static/source.js | 91 +++++++++++++++++++++++++++++ templates/crate/source.html | 11 +++- templates/style/_syntax-themes.scss | 6 ++ templates/style/_syntax.scss | 8 +++ templates/style/style.scss | 43 +++++++++----- 5 files changed, 144 insertions(+), 15 deletions(-) diff --git a/static/source.js b/static/source.js index 89a86a8ee..c084d471b 100644 --- a/static/source.js +++ b/static/source.js @@ -38,4 +38,95 @@ toggleSource(toggleSourceButton); }); }); + + // This code has been adapted from the rustdoc implementation here: + // https://github.com/rust-lang/rust/blob/5c848860/src/librustdoc/html/static/js/src-script.js#L152-L204 + function highlightLineNumbers() { + const match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); + if (!match) { + return; + } + let from = parseInt(match[1], 10); + let to = from; + if (typeof match[2] !== "undefined") { + to = parseInt(match[2], 10); + } + if (to < from) { + const tmp = to; + to = from; + from = tmp; + } + let elem = document.getElementById(from); + if (!elem) { + return; + } + const x = document.getElementById(from); + if (x) { + x.scrollIntoView(); + } + Array.from(document.getElementsByClassName("line-number-highlighted")).forEach(e => { + e.classList.remove("line-number-highlighted"); + }); + for (let i = from; i <= to; ++i) { + elem = document.getElementById(i); + if (!elem) { + break; + } + elem.classList.add("line-number-highlighted"); + } + } + + const handleLineNumbers = (function () { + let prev_line_id = 0; + + const set_fragment = name => { + const x = window.scrollX, + y = window.scrollY; + if (window.history && typeof window.history.pushState === "function") { + history.replaceState(null, null, "#" + name); + highlightLineNumbers(); + } else { + location.replace("#" + name); + } + // Prevent jumps when selecting one or many lines + window.scrollTo(x, y); + }; + + return ev => { + let cur_line_id = parseInt(ev.target.id, 10); + // 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(); + + if (ev.shiftKey && prev_line_id) { + // Swap selection if needed + if (prev_line_id > cur_line_id) { + const tmp = prev_line_id; + prev_line_id = cur_line_id; + cur_line_id = tmp; + } + + set_fragment(prev_line_id + "-" + cur_line_id); + } else { + prev_line_id = cur_line_id; + + set_fragment(cur_line_id); + } + }; + }()); + + window.addEventListener("hashchange", highlightLineNumbers) + + Array.from(document.getElementById("line-numbers").children[0].children).forEach(el => { + el.addEventListener("click", handleLineNumbers); + }); + + highlightLineNumbers(); })(); diff --git a/templates/crate/source.html b/templates/crate/source.html index 87be64217..58f6d17f4 100644 --- a/templates/crate/source.html +++ b/templates/crate/source.html @@ -127,8 +127,15 @@ {% else %} {% set file_name = "" %} {% endif %} -
- {{- file_content|highlight(file_name)|safe -}} +
+

+                        {%- for line in 1..=file_content.lines().count() -%}
+                            {{line|safe}}
+                        {%~ endfor -%}
+                    
+
+ {{- file_content|highlight(file_name)|safe -}} +
{%- endif -%}
diff --git a/templates/style/_syntax-themes.scss b/templates/style/_syntax-themes.scss index 039769de2..072a647bd 100644 --- a/templates/style/_syntax-themes.scss +++ b/templates/style/_syntax-themes.scss @@ -15,6 +15,8 @@ html { --color-syntax-question-mark: #ff9011; --color-syntax-self: #c82829; --color-syntax-string: #718c00; + --color-line-number: #c67e2d; + --color-line-number-highlighted: #fdffd3; } // To add a new theme, copy the above theme into a new `html[data-docs-rs-theme="name"]` @@ -37,6 +39,8 @@ html[data-docs-rs-theme="dark"] { --color-syntax-question-mark: #ff9011; --color-syntax-self: #ee6868; --color-syntax-string: #83a300; + --color-line-number: #3b91e2; + --color-line-number-highlighted: #0a042f; } html[data-docs-rs-theme="ayu"] { @@ -56,4 +60,6 @@ html[data-docs-rs-theme="ayu"] { --color-syntax-question-mark: #ff9011; --color-syntax-self: #36a3d9; --color-syntax-string: #b8cc52; + --color-line-number: #708090; + --color-line-number-highlighted: #272b2e; } diff --git a/templates/style/_syntax.scss b/templates/style/_syntax.scss index 735aec8cd..2b5fe9fdf 100644 --- a/templates/style/_syntax.scss +++ b/templates/style/_syntax.scss @@ -1,5 +1,13 @@ @import "syntax-themes"; +#line-numbers > code > a, #line-numbers > code > a:visited { + color: var(--color-line-number); +} + +.line-number-highlighted { + background-color: var(--color-line-number-highlighted); +} + pre > code { color: var(--color-syntax-foreground); background-color: var(--color-syntax-background); diff --git a/templates/style/style.scss b/templates/style/style.scss index 80d39b907..d5c1a7841 100644 --- a/templates/style/style.scss +++ b/templates/style/style.scss @@ -886,23 +886,40 @@ ul.pure-menu-list { } } - #source-code { - pre { - margin-top: 0; - margin-bottom: 0; - height: 100%; + #source-warning { + height: 100%; + } +} - code { - height: 100%; - } - } +#source-code-container { + display: inline-flex; + overflow: scroll; +} +#line-numbers { + text-align: right; + letter-spacing: normal; +} +#line-numbers > code > a { + padding: 0 8px; +} +// This class is used to the source code and the line number container in the +// `crate/**/source/*` view +.source-code { + pre { + margin-top: 0; + margin-bottom: 0; + height: 100%; - &.expanded { - width: calc(100% - 46px); + code { + height: 100%; } } - #source-warning { - height: 100%; + &.expanded { + width: calc(100% - 46px); } } +#source-code { + overflow: scroll; + width: 100%; +} From ef58ec2fb13c7e7602bc4c06adadd2585d9b87a2 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Thu, 18 Jul 2024 18:57:02 +0200 Subject: [PATCH 2/2] Address PR comments <3 --- static/source.js | 7 +++---- templates/crate/source.html | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/static/source.js b/static/source.js index c084d471b..0801441c4 100644 --- a/static/source.js +++ b/static/source.js @@ -39,8 +39,7 @@ }); }); - // This code has been adapted from the rustdoc implementation here: - // https://github.com/rust-lang/rust/blob/5c848860/src/librustdoc/html/static/js/src-script.js#L152-L204 + // This code has been adapted from the rustdoc implementation function highlightLineNumbers() { const match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); if (!match) { @@ -76,7 +75,7 @@ } } - const handleLineNumbers = (function () { + const handleLineNumbers = (function() { let prev_line_id = 0; const set_fragment = name => { @@ -122,7 +121,7 @@ }; }()); - window.addEventListener("hashchange", highlightLineNumbers) + window.addEventListener("hashchange", highlightLineNumbers); Array.from(document.getElementById("line-numbers").children[0].children).forEach(el => { el.addEventListener("click", handleLineNumbers); diff --git a/templates/crate/source.html b/templates/crate/source.html index 58f6d17f4..57523c023 100644 --- a/templates/crate/source.html +++ b/templates/crate/source.html @@ -130,7 +130,7 @@

                         {%- for line in 1..=file_content.lines().count() -%}
-                            {{line|safe}}
+                            {{line}}
                         {%~ endfor -%}