Skip to content

Commit 5acd5ef

Browse files
Merge pull request #1448 from GuillaumeGomez/move-keyboard-js
Move keyboard interactions handling out of the template inside a JS file
2 parents 503fa4d + dda792d commit 5acd5ef

File tree

4 files changed

+83
-63
lines changed

4 files changed

+83
-63
lines changed

src/web/metrics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ mod tests {
120120
("/crate/rcc/0.0.0", "/crate/:name/:version"),
121121
("/-/static/index.js", "static resource"),
122122
("/-/static/menu.js", "static resource"),
123+
("/-/static/keyboard.js", "static resource"),
123124
("/-/static/opensearch.xml", "static resource"),
124125
("/releases", "/releases"),
125126
("/releases/feed", "static resource"),

src/web/statics.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,24 @@ mod tests {
210210
});
211211
}
212212

213+
#[test]
214+
fn keyboard_js() {
215+
wrapper(|env| {
216+
let web = env.frontend();
217+
218+
let resp = web.get("/-/static/keyboard.js").send()?;
219+
assert!(resp.status().is_success());
220+
assert_eq!(
221+
resp.headers().get("Content-Type"),
222+
Some(&"application/javascript".parse().unwrap()),
223+
);
224+
assert!(resp.content_length().unwrap() > 10);
225+
assert!(resp.text()?.contains("handleKey"));
226+
227+
Ok(())
228+
});
229+
}
230+
213231
#[test]
214232
fn static_files() {
215233
wrapper(|env| {

static/keyboard.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
(function() {
2+
function getKey(ev) {
3+
if ("key" in ev && typeof ev.key != "undefined") {
4+
return ev.key;
5+
}
6+
return String.fromCharCode(ev.charCode || ev.keyCode);
7+
}
8+
9+
var active = null;
10+
function handleKey(ev) {
11+
if (ev.ctrlKey || ev.altKey || ev.metaKey || document.activeElement.tagName === "INPUT") {
12+
return;
13+
}
14+
15+
if (ev.which === 40) { // Down arrow
16+
ev.preventDefault();
17+
if (active === null) {
18+
active = document.getElementsByClassName("recent-releases-container")[0].getElementsByTagName("li")[0];
19+
} else if (active.nextElementSibling) {
20+
active.classList.remove("selected");
21+
active = active.nextElementSibling;
22+
}
23+
active.classList.add("selected");
24+
} else if (ev.which === 38) { // Up arrow
25+
ev.preventDefault();
26+
if (active === null) {
27+
active = document.getElementsByClassName("recent-releases-container")[0].getElementsByTagName("li")[0];
28+
} else if (active.previousElementSibling) {
29+
active.classList.remove("selected");
30+
active = active.previousElementSibling;
31+
}
32+
active.classList.add("selected");
33+
active.focus();
34+
} else if (ev.which === 13) { // Return
35+
if (active !== null) {
36+
document.location.href = active.getElementsByTagName("a")[0].href;
37+
}
38+
} else {
39+
switch (getKey(ev)) {
40+
case "s":
41+
case "S":
42+
ev.preventDefault();
43+
document.getElementsByClassName("search-input-nav")[0].focus();
44+
break;
45+
}
46+
}
47+
}
48+
49+
document.onkeypress = handleKey;
50+
document.onkeydown = handleKey;
51+
52+
var crates = Array.prototype.slice.call(document.getElementsByClassName("recent-releases-container")[0].getElementsByTagName("li"));
53+
for (var i = 0; i < crates.length; ++i) {
54+
crates[i].addEventListener("mouseover", function (event) {
55+
this.classList.remove("selected");
56+
active = null;
57+
});
58+
crates[i].addEventListener("mouseout", function (event) {
59+
this.classList.remove("selected");
60+
active = null;
61+
});
62+
}
63+
})();

templates/releases/releases.html

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -83,67 +83,5 @@
8383
{%- endblock body -%}
8484

8585
{%- block javascript -%}
86-
<script nonce="{{ csp_nonce }}" type="text/javascript" charset="utf-8">
87-
function getKey(ev) {
88-
if ("key" in ev && typeof ev.key != "undefined") {
89-
return ev.key;
90-
}
91-
return String.fromCharCode(ev.charCode || ev.keyCode);
92-
}
93-
94-
var active = null;
95-
function handleKey(ev) {
96-
if (ev.ctrlKey || ev.altKey || ev.metaKey || document.activeElement.tagName === "INPUT") {
97-
return;
98-
}
99-
100-
if (ev.which === 40) { // Down arrow
101-
ev.preventDefault();
102-
if (active === null) {
103-
active = document.getElementsByClassName("recent-releases-container")[0].getElementsByTagName("li")[0];
104-
} else if (active.nextElementSibling) {
105-
active.classList.remove("selected");
106-
active = active.nextElementSibling;
107-
}
108-
active.classList.add("selected");
109-
} else if (ev.which === 38) { // Up arrow
110-
ev.preventDefault();
111-
if (active === null) {
112-
active = document.getElementsByClassName("recent-releases-container")[0].getElementsByTagName("li")[0];
113-
} else if (active.previousElementSibling) {
114-
active.classList.remove("selected");
115-
active = active.previousElementSibling;
116-
}
117-
active.classList.add("selected");
118-
active.focus();
119-
} else if (ev.which === 13) { // Return
120-
if (active !== null) {
121-
document.location.href = active.getElementsByTagName("a")[0].href;
122-
}
123-
} else {
124-
switch (getKey(ev)) {
125-
case "s":
126-
case "S":
127-
ev.preventDefault();
128-
document.getElementsByClassName("search-input-nav")[0].focus();
129-
break;
130-
}
131-
}
132-
}
133-
134-
document.onkeypress = handleKey;
135-
document.onkeydown = handleKey;
136-
137-
var crates = Array.prototype.slice.call(document.getElementsByClassName("recent-releases-container")[0].getElementsByTagName("li"));
138-
for (var i = 0; i < crates.length; ++i) {
139-
crates[i].addEventListener("mouseover", function (event) {
140-
this.classList.remove("selected");
141-
active = null;
142-
});
143-
crates[i].addEventListener("mouseout", function (event) {
144-
this.classList.remove("selected");
145-
active = null;
146-
});
147-
}
148-
</script>
86+
<script nonce="{{ csp_nonce }}" type="text/javascript" src="/-/static/keyboard.js?{{ docsrs_version() | slugify }}"></script>
14987
{%- endblock javascript -%}

0 commit comments

Comments
 (0)