about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Macleod <alex@macleod.io>2025-01-19 22:53:56 +0000
committerAlex Macleod <alex@macleod.io>2025-01-30 18:01:05 +0000
commit33bb8afd088f4c23a8706c8f2a84aedb8bf5e248 (patch)
tree8e6ad1524ae24272766a8f9f2611120816e85d8c
parente692cd4b304a954829d5c855eb6a5bbd4ece51f2 (diff)
downloadrust-33bb8afd088f4c23a8706c8f2a84aedb8bf5e248.tar.gz
rust-33bb8afd088f4c23a8706c8f2a84aedb8bf5e248.zip
Fix expand/collapse all on site, make highlightjs lazier
-rw-r--r--util/gh-pages/index_template.html23
-rw-r--r--util/gh-pages/script.js87
-rw-r--r--util/gh-pages/style.css8
-rw-r--r--util/gh-pages/theme.js9
4 files changed, 81 insertions, 46 deletions
diff --git a/util/gh-pages/index_template.html b/util/gh-pages/index_template.html
index deb0ef0b499..a9b64628003 100644
--- a/util/gh-pages/index_template.html
+++ b/util/gh-pages/index_template.html
@@ -24,14 +24,16 @@ Otherwise, have a great day =^.^=
     <link id="styleNight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/tomorrow-night.css" disabled="true"> {# #}
     <link id="styleAyu" rel="stylesheet" href="https://rust-lang.github.io/mdBook/ayu-highlight.css" disabled="true"> {# #}
     <link rel="stylesheet" href="style.css"> {# #}
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js" defer></script> {# #}
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js" defer></script> {# #}
+    <script src="script.js" defer></script> {# #}
 </head> {# #}
 <body> {# #}
-    <script src="theme.js"></script> {# #}
     <div id="settings-dropdown"> {# #}
         <button class="settings-icon" tabindex="-1"></button> {# #}
         <div class="settings-menu" tabindex="-1"> {# #}
             <div class="setting-radio-name">Theme</div> {# #}
-            <select id="theme-choice" onchange="setTheme(this.value, true)"> {# #}
+            <select id="theme-choice"> {# #}
                 <option value="ayu">Ayu</option> {# #}
                 <option value="coal">Coal</option> {# #}
                 <option value="light">Light</option> {# #}
@@ -39,11 +41,12 @@ Otherwise, have a great day =^.^=
                 <option value="rust">Rust</option> {# #}
             </select> {# #}
             <label> {# #}
-                <input type="checkbox" id="disable-shortcuts" onchange="changeSetting(this)"> {#+ #}
+                <input type="checkbox" id="disable-shortcuts"> {#+ #}
                 <span>Disable keyboard shortcuts</span> {# #}
             </label> {# #}
         </div> {# #}
     </div> {# #}
+    <script src="theme.js"></script> {# #}
 
     <div class="container"> {# #}
         <div class="page-header"> {# #}
@@ -133,10 +136,10 @@ Otherwise, have a great day =^.^=
                         </div> {# #}
                     </div> {# #}
                     <div class="col-12 col-md-2 btn-group expansion-group"> {# #}
-                        <button title="Collapse All" class="btn btn-default expansion-control" type="button" onclick="toggleExpansion(false)"> {# #}
+                        <button title="Collapse All" class="btn btn-default expansion-control" type="button" id="collapse-all"> {# #}
                             <span class="glyphicon glyphicon-collapse-up"></span> {# #}
                         </button> {# #}
-                        <button title="Expand All" class="btn btn-default expansion-control" type="button" onclick="toggleExpansion(true)"> {# #}
+                        <button title="Expand All" class="btn btn-default expansion-control" type="button" id="expand-all"> {# #}
                             <span class="glyphicon glyphicon-collapse-down"></span> {# #}
                         </button> {# #}
                     </div> {# #}
@@ -145,13 +148,13 @@ Otherwise, have a great day =^.^=
             {% for lint in lints %}
                 <article class="panel panel-default" id="{{lint.id}}"> {# #}
                     <input id="label-{{lint.id}}" type="checkbox"> {# #}
-                    <label for="label-{{lint.id}}" onclick="highlightIfNeeded('{{lint.id}}')"> {# #}
+                    <label for="label-{{lint.id}}"> {# #}
                         <header class="panel-heading"> {# #}
                             <h2 class="panel-title"> {# #}
                                 <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
                                     <span>{{lint.id}}</span> {#+ #}
-                                    <a href="#{{lint.id}}" onclick="lintAnchor(event)" class="anchor label label-default">&para;</a> {#+ #}
-                                    <a href="" class="anchor label label-default" onclick="copyToClipboard(event)"> {# #}
+                                    <a href="#{{lint.id}}" class="lint-anchor anchor label label-default">&para;</a> {#+ #}
+                                    <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
                                         &#128203; {# #}
                                     </a> {# #}
                                 </div> {# #}
@@ -227,9 +230,5 @@ Otherwise, have a great day =^.^=
             ></path> {# #}
         </svg> {# #}
     </a> {# #}
-
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script> {# #}
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js"></script> {# #}
-    <script src="script.js"></script> {# #}
 </body> {# #}
 </html> {# #}
diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js
index 34d76ad642e..c942a6a05a1 100644
--- a/util/gh-pages/script.js
+++ b/util/gh-pages/script.js
@@ -1,3 +1,5 @@
+"use strict";
+
 window.searchState = {
     timeout: null,
     inputElem: document.getElementById("search-input"),
@@ -124,13 +126,6 @@ function toggleElements(filter, value) {
     }
 }
 
-function changeSetting(elem) {
-    if (elem.id === "disable-shortcuts") {
-        disableShortcuts = elem.checked;
-        storeValue(elem.id, elem.checked);
-    }
-}
-
 function onEachLazy(lazyArray, func) {
     const arr = Array.prototype.slice.call(lazyArray);
     for (const el of arr) {
@@ -138,17 +133,9 @@ function onEachLazy(lazyArray, func) {
     }
 }
 
-function highlightIfNeeded(lintId) {
-    onEachLazy(document.querySelectorAll(`#${lintId} pre > code:not(.hljs)`), el => {
-        hljs.highlightElement(el.parentElement)
-        el.classList.add("highlighted");
-    });
-}
-
 function expandLint(lintId) {
     const elem = document.querySelector(`#${lintId} > input[type="checkbox"]`);
     elem.checked = true;
-    highlightIfNeeded(lintId);
 }
 
 function lintAnchor(event) {
@@ -194,13 +181,9 @@ function handleBlur(event, elementId) {
 }
 
 function toggleExpansion(expand) {
-    onEachLazy(
-        document.querySelectorAll("article"),
-        expand ? el => {
-            el.classList.remove("collapsed");
-            highlightIfNeeded(el);
-        } : el => el.classList.add("collapsed"),
-    );
+    for (const checkbox of document.querySelectorAll("article input[type=checkbox]")) {
+        checkbox.checked = expand;
+    }
 }
 
 // Returns the current URL without any query parameter or hash.
@@ -535,7 +518,7 @@ function parseURLFilters() {
         for (const [corres_key, corres_value] of Object.entries(URL_PARAMS_CORRESPONDENCE)) {
             if (corres_value === key) {
                 if (key !== "versions") {
-                    const settings  = new Set(value.split(","));
+                    const settings = new Set(value.split(","));
                     onEachLazy(document.querySelectorAll(`#lint-${key} ul input`), elem => {
                         elem.checked = settings.has(elem.getAttribute("data-value"));
                         updateFilter(elem, corres_key, true);
@@ -555,12 +538,60 @@ function parseURLFilters() {
     }
 }
 
-document.getElementById(`theme-choice`).value = loadValue("theme");
-let disableShortcuts = loadValue('disable-shortcuts') === "true";
-document.getElementById("disable-shortcuts").checked = disableShortcuts;
+function addListeners() {
+    disableShortcutsButton.addEventListener("change", () => {
+        disableShortcuts = disableShortcutsButton.checked;
+        storeValue("disable-shortcuts", disableShortcuts);
+    });
+
+    document.getElementById("expand-all").addEventListener("click", () => toggleExpansion(true));
+    document.getElementById("collapse-all").addEventListener("click", () => toggleExpansion(false));
+
+    // A delegated listener to avoid the upfront cost of >1000 listeners
+    document.addEventListener("click", event => {
+        if (!event.target instanceof HTMLAnchorElement) {
+            return;
+        }
+
+        if (event.target.classList.contains("lint-anchor")) {
+            lintAnchor(event);
+        } else if (event.target.classList.contains("copy-to-clipboard")) {
+            copyToClipboard(event);
+        }
+    });
+
+    document.addEventListener("keypress", handleShortcut);
+    document.addEventListener("keydown", handleShortcut);
+}
+
+// Highlight code blocks only when they approach the viewport so that clicking the "Expand All"
+// button doesn't take a long time
+function highlightLazily() {
+    if (!'IntersectionObserver' in window) {
+        return;
+    }
+    const observer = new IntersectionObserver((entries) => {
+        for (const entry of entries) {
+            if (entry.isIntersecting) {
+                observer.unobserve(entry.target);
+                for (const code of entry.target.querySelectorAll("pre code")) {
+                    hljs.highlightElement(code);
+                }
+            }
+        }
+    });
+    for (const docs of document.querySelectorAll(".lint-docs")) {
+        observer.observe(docs);
+    }
+}
+
+let disableShortcuts = loadValue("disable-shortcuts") === "true";
+
+const disableShortcutsButton = document.getElementById("disable-shortcuts");
+disableShortcutsButton.checked = disableShortcuts;
 
-document.addEventListener("keypress", handleShortcut);
-document.addEventListener("keydown", handleShortcut);
+addListeners();
+highlightLazily();
 
 generateSettings();
 generateSearch();
diff --git a/util/gh-pages/style.css b/util/gh-pages/style.css
index 896f2fdac76..3cc7a919c23 100644
--- a/util/gh-pages/style.css
+++ b/util/gh-pages/style.css
@@ -1,9 +1,5 @@
 blockquote { font-size: 1em; }
 
-[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
-    display: none !important;
-}
-
 .dropdown-menu {
     color: var(--fg);
     background: var(--theme-popup-bg);
@@ -188,8 +184,8 @@ details {
     padding: .5em .5em 0;
 }
 
-code {
-    white-space: pre !important;
+pre {
+    padding: 0;
 }
 
 summary {
diff --git a/util/gh-pages/theme.js b/util/gh-pages/theme.js
index 90f57d4469d..a5dfeed9e8c 100644
--- a/util/gh-pages/theme.js
+++ b/util/gh-pages/theme.js
@@ -1,3 +1,5 @@
+"use strict";
+
 function storeValue(settingName, value) {
     try {
         localStorage.setItem(`clippy-lint-list-${settingName}`, value);
@@ -57,4 +59,11 @@ function setTheme(theme, store) {
     } else {
         setTheme(theme, false);
     }
+
+    const themeChoice = document.getElementById("theme-choice");
+
+    themeChoice.value = loadValue("theme");
+    document.getElementById("theme-choice").addEventListener("change", (e) => {
+        setTheme(themeChoice.value, true);
+    });
 })();