Skip to content

Commit c607f78

Browse files
authored
Fix expand/collapse all on site, make highlightjs lazier (#14038)
This fixes the buttons that expand/collapse all the lints in the list, it also makes code block syntax highlighting only happen when the specific lint enters the viewport since highlighting them all at once was fairly heavy There's also a few miscellaneous inline event handler removals `script.js` and highlightjs are now loaded with `defer` so that the download can start earlier Also fixes #14048, we were calling highlight on the `pre` in `<pre><code>...</code></pre>` but highlightjs wants us to call it on the `code` element changelog: none
2 parents 7e5cfbe + 33bb8af commit c607f78

File tree

4 files changed

+81
-46
lines changed

4 files changed

+81
-46
lines changed

util/gh-pages/index_template.html

+11-12
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,29 @@
2424
<link id="styleNight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/tomorrow-night.css" disabled="true"> {# #}
2525
<link id="styleAyu" rel="stylesheet" href="https://rust-lang.github.io/mdBook/ayu-highlight.css" disabled="true"> {# #}
2626
<link rel="stylesheet" href="style.css"> {# #}
27+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js" defer></script> {# #}
28+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js" defer></script> {# #}
29+
<script src="script.js" defer></script> {# #}
2730
</head> {# #}
2831
<body> {# #}
29-
<script src="theme.js"></script> {# #}
3032
<div id="settings-dropdown"> {# #}
3133
<button class="settings-icon" tabindex="-1"></button> {# #}
3234
<div class="settings-menu" tabindex="-1"> {# #}
3335
<div class="setting-radio-name">Theme</div> {# #}
34-
<select id="theme-choice" onchange="setTheme(this.value, true)"> {# #}
36+
<select id="theme-choice"> {# #}
3537
<option value="ayu">Ayu</option> {# #}
3638
<option value="coal">Coal</option> {# #}
3739
<option value="light">Light</option> {# #}
3840
<option value="navy">Navy</option> {# #}
3941
<option value="rust">Rust</option> {# #}
4042
</select> {# #}
4143
<label> {# #}
42-
<input type="checkbox" id="disable-shortcuts" onchange="changeSetting(this)"> {#+ #}
44+
<input type="checkbox" id="disable-shortcuts"> {#+ #}
4345
<span>Disable keyboard shortcuts</span> {# #}
4446
</label> {# #}
4547
</div> {# #}
4648
</div> {# #}
49+
<script src="theme.js"></script> {# #}
4750

4851
<div class="container"> {# #}
4952
<div class="page-header"> {# #}
@@ -133,10 +136,10 @@ <h1>Clippy Lints</h1> {# #}
133136
</div> {# #}
134137
</div> {# #}
135138
<div class="col-12 col-md-2 btn-group expansion-group"> {# #}
136-
<button title="Collapse All" class="btn btn-default expansion-control" type="button" onclick="toggleExpansion(false)"> {# #}
139+
<button title="Collapse All" class="btn btn-default expansion-control" type="button" id="collapse-all"> {# #}
137140
<span class="glyphicon glyphicon-collapse-up"></span> {# #}
138141
</button> {# #}
139-
<button title="Expand All" class="btn btn-default expansion-control" type="button" onclick="toggleExpansion(true)"> {# #}
142+
<button title="Expand All" class="btn btn-default expansion-control" type="button" id="expand-all"> {# #}
140143
<span class="glyphicon glyphicon-collapse-down"></span> {# #}
141144
</button> {# #}
142145
</div> {# #}
@@ -145,13 +148,13 @@ <h1>Clippy Lints</h1> {# #}
145148
{% for lint in lints %}
146149
<article class="panel panel-default" id="{{lint.id}}"> {# #}
147150
<input id="label-{{lint.id}}" type="checkbox"> {# #}
148-
<label for="label-{{lint.id}}" onclick="highlightIfNeeded('{{lint.id}}')"> {# #}
151+
<label for="label-{{lint.id}}"> {# #}
149152
<header class="panel-heading"> {# #}
150153
<h2 class="panel-title"> {# #}
151154
<div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
152155
<span>{{lint.id}}</span> {#+ #}
153-
<a href="#{{lint.id}}" onclick="lintAnchor(event)" class="anchor label label-default">&para;</a> {#+ #}
154-
<a href="" class="anchor label label-default" onclick="copyToClipboard(event)"> {# #}
156+
<a href="#{{lint.id}}" class="lint-anchor anchor label label-default">&para;</a> {#+ #}
157+
<a href="" class="copy-to-clipboard anchor label label-default"> {# #}
155158
&#128203; {# #}
156159
</a> {# #}
157160
</div> {# #}
@@ -227,9 +230,5 @@ <h2 class="panel-title"> {# #}
227230
></path> {# #}
228231
</svg> {# #}
229232
</a> {# #}
230-
231-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script> {# #}
232-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js"></script> {# #}
233-
<script src="script.js"></script> {# #}
234233
</body> {# #}
235234
</html> {# #}

util/gh-pages/script.js

+59-28
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"use strict";
2+
13
window.searchState = {
24
timeout: null,
35
inputElem: document.getElementById("search-input"),
@@ -124,31 +126,16 @@ function toggleElements(filter, value) {
124126
}
125127
}
126128

127-
function changeSetting(elem) {
128-
if (elem.id === "disable-shortcuts") {
129-
disableShortcuts = elem.checked;
130-
storeValue(elem.id, elem.checked);
131-
}
132-
}
133-
134129
function onEachLazy(lazyArray, func) {
135130
const arr = Array.prototype.slice.call(lazyArray);
136131
for (const el of arr) {
137132
func(el);
138133
}
139134
}
140135

141-
function highlightIfNeeded(lintId) {
142-
onEachLazy(document.querySelectorAll(`#${lintId} pre > code:not(.hljs)`), el => {
143-
hljs.highlightElement(el.parentElement)
144-
el.classList.add("highlighted");
145-
});
146-
}
147-
148136
function expandLint(lintId) {
149137
const elem = document.querySelector(`#${lintId} > input[type="checkbox"]`);
150138
elem.checked = true;
151-
highlightIfNeeded(lintId);
152139
}
153140

154141
function lintAnchor(event) {
@@ -194,13 +181,9 @@ function handleBlur(event, elementId) {
194181
}
195182

196183
function toggleExpansion(expand) {
197-
onEachLazy(
198-
document.querySelectorAll("article"),
199-
expand ? el => {
200-
el.classList.remove("collapsed");
201-
highlightIfNeeded(el);
202-
} : el => el.classList.add("collapsed"),
203-
);
184+
for (const checkbox of document.querySelectorAll("article input[type=checkbox]")) {
185+
checkbox.checked = expand;
186+
}
204187
}
205188

206189
// Returns the current URL without any query parameter or hash.
@@ -535,7 +518,7 @@ function parseURLFilters() {
535518
for (const [corres_key, corres_value] of Object.entries(URL_PARAMS_CORRESPONDENCE)) {
536519
if (corres_value === key) {
537520
if (key !== "versions") {
538-
const settings = new Set(value.split(","));
521+
const settings = new Set(value.split(","));
539522
onEachLazy(document.querySelectorAll(`#lint-${key} ul input`), elem => {
540523
elem.checked = settings.has(elem.getAttribute("data-value"));
541524
updateFilter(elem, corres_key, true);
@@ -555,12 +538,60 @@ function parseURLFilters() {
555538
}
556539
}
557540

558-
document.getElementById(`theme-choice`).value = loadValue("theme");
559-
let disableShortcuts = loadValue('disable-shortcuts') === "true";
560-
document.getElementById("disable-shortcuts").checked = disableShortcuts;
541+
function addListeners() {
542+
disableShortcutsButton.addEventListener("change", () => {
543+
disableShortcuts = disableShortcutsButton.checked;
544+
storeValue("disable-shortcuts", disableShortcuts);
545+
});
546+
547+
document.getElementById("expand-all").addEventListener("click", () => toggleExpansion(true));
548+
document.getElementById("collapse-all").addEventListener("click", () => toggleExpansion(false));
549+
550+
// A delegated listener to avoid the upfront cost of >1000 listeners
551+
document.addEventListener("click", event => {
552+
if (!event.target instanceof HTMLAnchorElement) {
553+
return;
554+
}
555+
556+
if (event.target.classList.contains("lint-anchor")) {
557+
lintAnchor(event);
558+
} else if (event.target.classList.contains("copy-to-clipboard")) {
559+
copyToClipboard(event);
560+
}
561+
});
562+
563+
document.addEventListener("keypress", handleShortcut);
564+
document.addEventListener("keydown", handleShortcut);
565+
}
566+
567+
// Highlight code blocks only when they approach the viewport so that clicking the "Expand All"
568+
// button doesn't take a long time
569+
function highlightLazily() {
570+
if (!'IntersectionObserver' in window) {
571+
return;
572+
}
573+
const observer = new IntersectionObserver((entries) => {
574+
for (const entry of entries) {
575+
if (entry.isIntersecting) {
576+
observer.unobserve(entry.target);
577+
for (const code of entry.target.querySelectorAll("pre code")) {
578+
hljs.highlightElement(code);
579+
}
580+
}
581+
}
582+
});
583+
for (const docs of document.querySelectorAll(".lint-docs")) {
584+
observer.observe(docs);
585+
}
586+
}
587+
588+
let disableShortcuts = loadValue("disable-shortcuts") === "true";
589+
590+
const disableShortcutsButton = document.getElementById("disable-shortcuts");
591+
disableShortcutsButton.checked = disableShortcuts;
561592

562-
document.addEventListener("keypress", handleShortcut);
563-
document.addEventListener("keydown", handleShortcut);
593+
addListeners();
594+
highlightLazily();
564595

565596
generateSettings();
566597
generateSearch();

util/gh-pages/style.css

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
blockquote { font-size: 1em; }
22

3-
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
4-
display: none !important;
5-
}
6-
73
.dropdown-menu {
84
color: var(--fg);
95
background: var(--theme-popup-bg);
@@ -188,8 +184,8 @@ details {
188184
padding: .5em .5em 0;
189185
}
190186

191-
code {
192-
white-space: pre !important;
187+
pre {
188+
padding: 0;
193189
}
194190

195191
summary {

util/gh-pages/theme.js

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"use strict";
2+
13
function storeValue(settingName, value) {
24
try {
35
localStorage.setItem(`clippy-lint-list-${settingName}`, value);
@@ -57,4 +59,11 @@ function setTheme(theme, store) {
5759
} else {
5860
setTheme(theme, false);
5961
}
62+
63+
const themeChoice = document.getElementById("theme-choice");
64+
65+
themeChoice.value = loadValue("theme");
66+
document.getElementById("theme-choice").addEventListener("change", (e) => {
67+
setTheme(themeChoice.value, true);
68+
});
6069
})();

0 commit comments

Comments
 (0)