PageSourceSearch

https://docs.rs/-/static/keyboard.js?0-0-0-6b0955898af88db642c5ce7420d9dbef2c65d5d9-2026-09-30

js docs.rs collected 2026-10-01 08:32:05 UTC 4,272 bytes, 127 lines download raw bytes

1(function() {
2    function focusSearchInput() {
3        // On the index page, we have a "#search" input. If we are on this page, we want to go back
4        // to this one and not the one in the header navbar.
5        const searchInput = document.getElementById("search");
6        if (searchInput) {
7            searchInput.focus();
8        } else {
9            document.getElementById("nav-search").focus();
10        }
11    }
12
13    function focusFirstSearchResult() {
14        const elem = document.querySelector(".recent-releases-container a.release");
15        if (elem) {
16            elem.focus();
17        }
18    }
19
20    function getWrappingLi(elem) {
21        while (elem && elem.tagName !== "LI" && elem.tagName !== "BODY") {
22            elem = elem.parentElement;
23        }
24        if (elem.tagName === "BODY") {
25            return null;
26        }
27        return elem;
28    }
29
30    function focusOnLi(li) {
31        const elem = li.querySelector(".release");
32        if (elem) {
33            elem.focus();
34        }
35    }
36
37    function getKey(ev) {
38        if ("key" in ev && typeof ev.key !== "undefined") {
39            return ev.key;
40        }
41        return String.fromCharCode(ev.charCode || ev.keyCode);
42    }
43
44    function checkIfHasParent(elem, className) {
45        while (elem && elem.tagName !== "BODY") {
46            elem = elem.parentElement;
47            if (elem.classList.contains(className)) {
48                return true;
49            }
50        }
51        return false;
52    }
53
54    function handleKey(ev) {
55        if (ev.ctrlKey || ev.altKey || ev.metaKey) {
56            return;
57        }
58        if (ev.which === 27) { // Escape
59            document.activeElement.blur();
60            return;
61        }
62        const tagName = document.activeElement.tagName;
63        // We want to check two things here: if an input or an element of the docs.rs topbar
64        // has the focus. If so, then we do nothing and simply return.
65        if (tagName === "INPUT" ||
66            (tagName === "A" &&
67                checkIfHasParent(document.activeElement, "nav-container"))) {
68            return;
69        }
70
71        if (ev.which === 40) { // Down arrow
72            ev.preventDefault();
73            if (tagName === "BODY") {
74                focusFirstSearchResult();
75            } else {
76                const wrappingLi = getWrappingLi(document.activeElement);
77                if (!wrappingLi) {
78                    // Doesn't seem like we are in the crates list, let's focus the first element
79                    // of the list then!
80                    focusFirstSearchResult();
81                } else if (wrappingLi.nextElementSibling) {
82                    focusOnLi(wrappingLi.nextElementSibling);
83                }
84            }
85        } else if (ev.which === 38) { // Up arrow
86            ev.preventDefault();
87            if (tagName === "A") {
88                const wrappingLi = getWrappingLi(document.activeElement);
89                if (!wrappingLi) {
90                    // Doesn't seem like we are in the crates list, let's focus the first element
91                    // of the list then!
92                    focusFirstSearchResult();
93                } else if (wrappingLi.previousElementSibling) {
94                    focusOnLi(wrappingLi.previousElementSibling);
95                } else {
96                    focusSearchInput();
97                }
98            } else if (tagName === "BODY") {
99                focusFirstSearchResult();
100            }
101        } else if (tagName !== "INPUT") {
102            switch (getKey(ev)) {
103                case "s":
104                case "S":
105                case "/":
106                    ev.preventDefault();
107                    focusSearchInput();
108                    break;
109            }
110        }
111    }
112
113    function handleSortByChange() {
114        const inputSearch = document.getElementById("nav-search");
115        const searchForm = document.getElementById("nav-search-form");
116        if (inputSearch.value && searchForm) {
117            searchForm.submit();
118        }
119    }
120    const searchSortBySel = document.getElementById("nav-sort");
121    if (searchSortBySel) {
122        searchSortBySel.addEventListener("change", handleSortByChange);
123    }
124
125    document.onkeypress = handleKey;
126    document.onkeydown = handleKey;
127})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.