]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/html/static/js/scrape-examples.js
Auto merge of #96551 - ferrocene:pa-ignore-paths-when-abbreviating, r=Mark-Simulacrum
[rust.git] / src / librustdoc / html / static / js / scrape-examples.js
1 /* global addClass, hasClass, removeClass, onEachLazy */
2
3 "use strict";
4
5 (function() {
6     // Number of lines shown when code viewer is not expanded
7     const MAX_LINES = 10;
8
9     // Scroll code block to the given code location
10     function scrollToLoc(elt, loc) {
11         const lines = elt.querySelector(".line-numbers");
12         let scrollOffset;
13
14         // If the block is greater than the size of the viewer,
15         // then scroll to the top of the block. Otherwise scroll
16         // to the middle of the block.
17         if (loc[1] - loc[0] > MAX_LINES) {
18             const line = Math.max(0, loc[0] - 1);
19             scrollOffset = lines.children[line].offsetTop;
20         } else {
21             const wrapper = elt.querySelector(".code-wrapper");
22             const halfHeight = wrapper.offsetHeight / 2;
23             const offsetMid = (lines.children[loc[0]].offsetTop
24                              + lines.children[loc[1]].offsetTop) / 2;
25             scrollOffset = offsetMid - halfHeight;
26         }
27
28         lines.scrollTo(0, scrollOffset);
29         elt.querySelector(".rust").scrollTo(0, scrollOffset);
30     }
31
32     function updateScrapedExample(example) {
33         const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
34         let locIndex = 0;
35         const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight"));
36         const link = example.querySelector(".scraped-example-title a");
37
38         if (locs.length > 1) {
39             // Toggle through list of examples in a given file
40             const onChangeLoc = changeIndex => {
41                 removeClass(highlights[locIndex], "focus");
42                 changeIndex();
43                 scrollToLoc(example, locs[locIndex][0]);
44                 addClass(highlights[locIndex], "focus");
45
46                 const url = locs[locIndex][1];
47                 const title = locs[locIndex][2];
48
49                 link.href = url;
50                 link.innerHTML = title;
51             };
52
53             example.querySelector(".prev")
54                 .addEventListener("click", () => {
55                     onChangeLoc(() => {
56                         locIndex = (locIndex - 1 + locs.length) % locs.length;
57                     });
58                 });
59
60             example.querySelector("next")
61                 .addEventListener("click", () => {
62                     onChangeLoc(() => {
63                         locIndex = (locIndex + 1) % locs.length;
64                     });
65                 });
66         }
67
68         const expandButton = example.querySelector(".expand");
69         if (expandButton) {
70             expandButton.addEventListener("click", () => {
71                 if (hasClass(example, "expanded")) {
72                     removeClass(example, "expanded");
73                     scrollToLoc(example, locs[0][0]);
74                 } else {
75                     addClass(example, "expanded");
76                 }
77             });
78         }
79
80         // Start with the first example in view
81         scrollToLoc(example, locs[0][0]);
82     }
83
84     const firstExamples = document.querySelectorAll(".scraped-example-list > .scraped-example");
85     onEachLazy(firstExamples, updateScrapedExample);
86     onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => {
87         // Allow users to click the left border of the <details> section to close it,
88         // since the section can be large and finding the [+] button is annoying.
89         onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"), button => {
90             button.addEventListener("click", () => {
91                 toggle.open = false;
92             });
93         });
94
95         const moreExamples = toggle.querySelectorAll(".scraped-example");
96         toggle.querySelector("summary").addEventListener("click", () => {
97             // Wrapping in setTimeout ensures the update happens after the elements are actually
98             // visible. This is necessary since updateScrapedExample calls scrollToLoc which
99             // depends on offsetHeight, a property that requires an element to be visible to
100             // compute correctly.
101             setTimeout(() => {
102                 onEachLazy(moreExamples, updateScrapedExample);
103             });
104         }, {once: true});
105     });
106 })();