Skip to content

Commit 5745174

Browse files
committed
Introduce warning topbar menu, allow following crates to see warnings for
1 parent d8ea483 commit 5745174

File tree

6 files changed

+152
-0
lines changed

6 files changed

+152
-0
lines changed

static/warnings.js

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
(function() {
2+
function load(key, def = null) {
3+
const value = window.localStorage.getItem(key);
4+
if (value) {
5+
try {
6+
return JSON.parse(value);
7+
} catch (ex) {
8+
console.error(`Failed loading ${key} from local storage`, ex);
9+
return def;
10+
}
11+
} else {
12+
return def;
13+
}
14+
}
15+
16+
function store(key, value) {
17+
window.localStorage.setItem(key, JSON.stringify(value));
18+
}
19+
20+
function create(tagName, attrs = {}, children = [], listeners = {}) {
21+
const el = document.createElement(tagName);
22+
for (const key of Object.keys(attrs)) {
23+
if (typeof attrs[key] === "object") {
24+
for (const subkey of Object.keys(attrs[key])) {
25+
el[key].setProperty(subkey, attrs[key][subkey]);
26+
}
27+
} else {
28+
el.setAttribute(key, attrs[key]);
29+
}
30+
}
31+
el.append(...children);
32+
for (const key of Object.keys(listeners)) {
33+
el.addEventListener(key, listeners[key]);
34+
}
35+
return el;
36+
}
37+
38+
39+
if (!load("docs-rs-warnings-enabled", false)) {
40+
return;
41+
}
42+
43+
const parentEl = document.getElementById("warnings-menu-parent");
44+
parentEl.removeAttribute("hidden");
45+
46+
const current = JSON.parse(document.getElementById("crate-metadata")?.innerText || null);
47+
48+
const menuEl = document.getElementById("warnings-menu");
49+
50+
const followed = load("docs-rs-warnings-followed", []);
51+
52+
function update() {
53+
const children = [];
54+
55+
if (followed.length > 0) {
56+
children.push(
57+
create("div", { class: "pure-g" }, [
58+
create("div", { class: "pure-u-1" }, [
59+
create("ul", { class: "pure-menu-list", style: { width: "100%" } }, [
60+
create("li", { class: "pure-menu-heading" }, [
61+
create("b", {}, ["Followed crates"]),
62+
]),
63+
...followed.map(name => (
64+
create("li", { class: "pure-menu-item followed" }, [
65+
create("a", { class: "pure-menu-link", href: `/${name}` }, [
66+
name,
67+
]),
68+
create(
69+
"a",
70+
{ class: "pure-menu-link remove", href: "#" },
71+
["🗙"],
72+
{
73+
click: _ => {
74+
const index = followed.indexOf(name);
75+
followed.splice(index, 1);
76+
store("docs-rs-warnings-followed", followed);
77+
update();
78+
},
79+
},
80+
),
81+
])
82+
)),
83+
]),
84+
]),
85+
]),
86+
);
87+
}
88+
89+
if (current && !followed.includes(current.name)) {
90+
children.push(
91+
create("div", { class: "pure-g" }, [
92+
create("div", { class: "pure-u-1" }, [
93+
create("ul", { class: "pure-menu-list", style: { width: "100%" } }, [
94+
create("li", { class: "pure-menu-item" }, [
95+
create("a", { class: "pure-menu-link", href: "#" }, [
96+
"Follow ",
97+
create("b", {}, [current.name]),
98+
], {
99+
click: () => {
100+
const i = followed.findIndex(name => name > current.name);
101+
if (i >= 0) {
102+
followed.splice(i, 0, current.name);
103+
} else {
104+
followed.push(current.name);
105+
}
106+
store("docs-rs-warnings-followed", followed);
107+
update();
108+
},
109+
}),
110+
]),
111+
]),
112+
]),
113+
]),
114+
);
115+
}
116+
117+
for (const child of children.slice(0, -1)) {
118+
child.classList.add("menu-item-divided");
119+
}
120+
121+
menuEl.replaceChildren(...children);
122+
}
123+
124+
update();
125+
})();

templates/base.html

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
<script defer type="text/javascript" nonce="{{ csp_nonce }}" src="/-/static/menu.js?{{ build_slug }}"></script>
2626
<script defer type="text/javascript" nonce="{{ csp_nonce }}" src="/-/static/index.js?{{ build_slug }}"></script>
27+
<script defer type="text/javascript" nonce="{{ csp_nonce }}" src="/-/static/warnings.js?{{ build_slug }}"></script>
2728
</head>
2829

2930
<body class="{% block body_classes %}{% endblock body_classes %}">

templates/header/topbar_end.html

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
{# The global alert, if there is one #}
55
{% include "header/global_alert.html" -%}
66

7+
{% include "header/warnings.html" -%}
8+
79
<ul class="pure-menu-list">
810
{#
911
The Rust dropdown menu

templates/header/warnings.html

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<ul id="warnings-menu-parent" class="pure-menu-list" hidden>
2+
<li class="pure-menu-item pure-menu-has-children">
3+
<a href="#" class="pure-menu-link" aria-label="Warnings">Warnings <span id="warnings-count"></span></a>
4+
<div id="warnings-menu" class="pure-menu-children">
5+
</div>
6+
</li>
7+
</ul>

templates/rustdoc/body.html

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{%- set build_slug = slug::slugify(crate::BUILD_VERSION) -%}
22
<script async src="/-/static/menu.js?{{ build_slug }}"></script>
33
<script async src="/-/static/index.js?{{ build_slug }}"></script>
4+
<script async src="/-/static/warnings.js?{{ build_slug }}"></script>
45
{# see comment in ../storage-change-detection.html for details #}
56
<iframe src="/-/storage-change-detection.html" width="0" height="0" style="display: none"></iframe>

templates/style/_navbar.scss

+16
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,22 @@ div.nav-container {
362362
}
363363
}
364364
}
365+
366+
#warnings-menu {
367+
.followed {
368+
display: flex;
369+
align-items: center;
370+
:first-child {
371+
flex: auto;
372+
}
373+
}
374+
.remove {
375+
padding: 0 .5em;
376+
&:hover {
377+
color: var(--color-error);
378+
}
379+
}
380+
}
365381
}
366382

367383
#nav-search, #nav-sort {

0 commit comments

Comments
 (0)