doctools.js - sphere - GPU-based 3D discrete element method algorithm with optional fluid coupling
HTML git clone git://src.adamsgaard.dk/sphere
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
doctools.js (4332B)
---
1 /*
2 * Base JavaScript utilities for all Sphinx HTML documentation.
3 */
4 "use strict";
5
6 const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
7 "TEXTAREA",
8 "INPUT",
9 "SELECT",
10 "BUTTON",
11 ]);
12
13 const _ready = (callback) => {
14 if (document.readyState !== "loading") {
15 callback();
16 } else {
17 document.addEventListener("DOMContentLoaded", callback);
18 }
19 };
20
21 /**
22 * Small JavaScript module for the documentation.
23 */
24 const Documentation = {
25 init: () => {
26 Documentation.initDomainIndexTable();
27 Documentation.initOnKeyListeners();
28 },
29
30 /**
31 * i18n support
32 */
33 TRANSLATIONS: {},
34 PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
35 LOCALE: "unknown",
36
37 // gettext and ngettext don't access this so that the functions
38 // can safely bound to a different name (_ = Documentation.gettext)
39 gettext: (string) => {
40 const translated = Documentation.TRANSLATIONS[string];
41 switch (typeof translated) {
42 case "undefined":
43 return string; // no translation
44 case "string":
45 return translated; // translation exists
46 default:
47 return translated[0]; // (singular, plural) translation tuple exists
48 }
49 },
50
51 ngettext: (singular, plural, n) => {
52 const translated = Documentation.TRANSLATIONS[singular];
53 if (typeof translated !== "undefined")
54 return translated[Documentation.PLURAL_EXPR(n)];
55 return n === 1 ? singular : plural;
56 },
57
58 addTranslations: (catalog) => {
59 Object.assign(Documentation.TRANSLATIONS, catalog.messages);
60 Documentation.PLURAL_EXPR = new Function(
61 "n",
62 `return (${catalog.plural_expr})`,
63 );
64 Documentation.LOCALE = catalog.locale;
65 },
66
67 /**
68 * helper function to focus on search bar
69 */
70 focusSearchBar: () => {
71 document.querySelectorAll("input[name=q]")[0]?.focus();
72 },
73
74 /**
75 * Initialise the domain index toggle buttons
76 */
77 initDomainIndexTable: () => {
78 const toggler = (el) => {
79 const idNumber = el.id.substr(7);
80 const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
81 if (el.src.substr(-9) === "minus.png") {
82 el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
83 toggledRows.forEach((el) => (el.style.display = "none"));
84 } else {
85 el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
86 toggledRows.forEach((el) => (el.style.display = ""));
87 }
88 };
89
90 const togglerElements = document.querySelectorAll("img.toggler");
91 togglerElements.forEach((el) =>
92 el.addEventListener("click", (event) => toggler(event.currentTarget)),
93 );
94 togglerElements.forEach((el) => (el.style.display = ""));
95 if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
96 },
97
98 initOnKeyListeners: () => {
99 // only install a listener if it is really needed
100 if (
101 !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS
102 && !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
103 )
104 return;
105
106 document.addEventListener("keydown", (event) => {
107 // bail for input elements
108 if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName))
109 return;
110 // bail with special keys
111 if (event.altKey || event.ctrlKey || event.metaKey) return;
112
113 if (!event.shiftKey) {
114 switch (event.key) {
115 case "ArrowLeft":
116 if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
117
118 const prevLink = document.querySelector('link[rel="prev"]');
119 if (prevLink && prevLink.href) {
120 window.location.href = prevLink.href;
121 event.preventDefault();
122 }
123 break;
124 case "ArrowRight":
125 if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
126
127 const nextLink = document.querySelector('link[rel="next"]');
128 if (nextLink && nextLink.href) {
129 window.location.href = nextLink.href;
130 event.preventDefault();
131 }
132 break;
133 }
134 }
135
136 // some keyboard layouts may need Shift to get /
137 switch (event.key) {
138 case "/":
139 if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
140 Documentation.focusSearchBar();
141 event.preventDefault();
142 }
143 });
144 },
145 };
146
147 // quick alias for translations
148 const _ = Documentation.gettext;
149
150 _ready(Documentation.init);