diff options
Diffstat (limited to 'doc/script-files/script.js')
-rw-r--r-- | doc/script-files/script.js | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/doc/script-files/script.js b/doc/script-files/script.js new file mode 100644 index 0000000..b5b30fc --- /dev/null +++ b/doc/script-files/script.js | |||
@@ -0,0 +1,467 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. | ||
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
4 | * | ||
5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ | ||
6 | */ | ||
7 | |||
8 | var moduleSearchIndex; | ||
9 | var packageSearchIndex; | ||
10 | var typeSearchIndex; | ||
11 | var memberSearchIndex; | ||
12 | var tagSearchIndex; | ||
13 | |||
14 | var oddRowColor = "odd-row-color"; | ||
15 | var evenRowColor = "even-row-color"; | ||
16 | var sortAsc = "sort-asc"; | ||
17 | var sortDesc = "sort-desc"; | ||
18 | var tableTab = "table-tab"; | ||
19 | var activeTableTab = "active-table-tab"; | ||
20 | |||
21 | const linkIcon = "Link icon"; | ||
22 | const linkToSection = "Link to this section"; | ||
23 | |||
24 | function loadScripts(doc, tag) { | ||
25 | createElem(doc, tag, 'script-files/search.js'); | ||
26 | |||
27 | createElem(doc, tag, 'module-search-index.js'); | ||
28 | createElem(doc, tag, 'package-search-index.js'); | ||
29 | createElem(doc, tag, 'type-search-index.js'); | ||
30 | createElem(doc, tag, 'member-search-index.js'); | ||
31 | createElem(doc, tag, 'tag-search-index.js'); | ||
32 | } | ||
33 | |||
34 | function createElem(doc, tag, path) { | ||
35 | var script = doc.createElement(tag); | ||
36 | var scriptElement = doc.getElementsByTagName(tag)[0]; | ||
37 | script.src = pathtoroot + path; | ||
38 | scriptElement.parentNode.insertBefore(script, scriptElement); | ||
39 | } | ||
40 | |||
41 | // Helper for making content containing release names comparable lexicographically | ||
42 | function makeComparable(s) { | ||
43 | return s.toLowerCase().replace(/(\d+)/g, | ||
44 | function(n, m) { | ||
45 | return ("000" + m).slice(-4); | ||
46 | }); | ||
47 | } | ||
48 | |||
49 | // Switches between two styles depending on a condition | ||
50 | function toggleStyle(classList, condition, trueStyle, falseStyle) { | ||
51 | if (condition) { | ||
52 | classList.remove(falseStyle); | ||
53 | classList.add(trueStyle); | ||
54 | } else { | ||
55 | classList.remove(trueStyle); | ||
56 | classList.add(falseStyle); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | // Sorts the rows in a table lexicographically by the content of a specific column | ||
61 | function sortTable(header, columnIndex, columns) { | ||
62 | var container = header.parentElement; | ||
63 | var descending = header.classList.contains(sortAsc); | ||
64 | container.querySelectorAll("div.table-header").forEach( | ||
65 | function(header) { | ||
66 | header.classList.remove(sortAsc); | ||
67 | header.classList.remove(sortDesc); | ||
68 | } | ||
69 | ) | ||
70 | var cells = container.children; | ||
71 | var rows = []; | ||
72 | for (var i = columns; i < cells.length; i += columns) { | ||
73 | rows.push(Array.prototype.slice.call(cells, i, i + columns)); | ||
74 | } | ||
75 | var comparator = function(a, b) { | ||
76 | var ka = makeComparable(a[columnIndex].textContent); | ||
77 | var kb = makeComparable(b[columnIndex].textContent); | ||
78 | if (ka < kb) | ||
79 | return descending ? 1 : -1; | ||
80 | if (ka > kb) | ||
81 | return descending ? -1 : 1; | ||
82 | return 0; | ||
83 | }; | ||
84 | var sorted = rows.sort(comparator); | ||
85 | var visible = 0; | ||
86 | sorted.forEach(function(row) { | ||
87 | if (row[0].style.display !== 'none') { | ||
88 | var isEvenRow = visible++ % 2 === 0; | ||
89 | } | ||
90 | row.forEach(function(cell) { | ||
91 | toggleStyle(cell.classList, isEvenRow, evenRowColor, oddRowColor); | ||
92 | container.appendChild(cell); | ||
93 | }) | ||
94 | }); | ||
95 | toggleStyle(header.classList, descending, sortDesc, sortAsc); | ||
96 | } | ||
97 | |||
98 | // Toggles the visibility of a table category in all tables in a page | ||
99 | function toggleGlobal(checkbox, selected, columns) { | ||
100 | const display = checkbox.checked ? '' : 'none'; | ||
101 | const selectOther = selected === "other"; | ||
102 | const selectAll = selected === "all"; | ||
103 | if (selectAll) { | ||
104 | document.querySelectorAll('.checkboxes input[type="checkbox"]').forEach(c => { | ||
105 | c.checked = checkbox.checked; | ||
106 | }); | ||
107 | } | ||
108 | document.querySelectorAll("div.table-tabs").forEach(t => { | ||
109 | const id = t.parentElement.getAttribute("id"); | ||
110 | const selectedClass = id + "-tab" + (selectOther ? "" : selected); | ||
111 | var visible = 0; | ||
112 | t.parentElement.querySelectorAll('div.' + id) | ||
113 | .forEach(function(elem) { | ||
114 | if (selectAll | ||
115 | || (!selectOther && elem.classList.contains(selectedClass)) | ||
116 | || (selectOther && elem.className.indexOf(selectedClass) < 0)) { | ||
117 | elem.style.display = display; | ||
118 | } | ||
119 | if (elem.style.display === '') { | ||
120 | var isEvenRow = visible++ % (columns * 2) < columns; | ||
121 | toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); | ||
122 | } | ||
123 | }); | ||
124 | var displaySection = visible === 0 ? 'none' : ''; | ||
125 | t.parentElement.style.display = displaySection; | ||
126 | document.querySelector("li#contents-" + id).style.display = displaySection; | ||
127 | }) | ||
128 | } | ||
129 | |||
130 | // Shows the elements of a table belonging to a specific category | ||
131 | function show(tableId, selected, columns) { | ||
132 | if (tableId !== selected) { | ||
133 | document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') | ||
134 | .forEach(function(elem) { | ||
135 | elem.style.display = 'none'; | ||
136 | }); | ||
137 | } | ||
138 | document.querySelectorAll('div.' + selected) | ||
139 | .forEach(function(elem, index) { | ||
140 | elem.style.display = ''; | ||
141 | var isEvenRow = index % (columns * 2) < columns; | ||
142 | toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); | ||
143 | }); | ||
144 | updateTabs(tableId, selected); | ||
145 | } | ||
146 | |||
147 | function updateTabs(tableId, selected) { | ||
148 | document.getElementById(tableId + '.tabpanel') | ||
149 | .setAttribute('aria-labelledby', selected); | ||
150 | document.querySelectorAll('button[id^="' + tableId + '"]') | ||
151 | .forEach(function(tab, index) { | ||
152 | if (selected === tab.id || (tableId === selected && index === 0)) { | ||
153 | tab.className = activeTableTab; | ||
154 | tab.setAttribute('aria-selected', true); | ||
155 | tab.setAttribute('tabindex',0); | ||
156 | } else { | ||
157 | tab.className = tableTab; | ||
158 | tab.setAttribute('aria-selected', false); | ||
159 | tab.setAttribute('tabindex',-1); | ||
160 | } | ||
161 | }); | ||
162 | } | ||
163 | |||
164 | function switchTab(e) { | ||
165 | var selected = document.querySelector('[aria-selected=true]'); | ||
166 | if (selected) { | ||
167 | if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { | ||
168 | // left or up arrow key pressed: move focus to previous tab | ||
169 | selected.previousSibling.click(); | ||
170 | selected.previousSibling.focus(); | ||
171 | e.preventDefault(); | ||
172 | } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { | ||
173 | // right or down arrow key pressed: move focus to next tab | ||
174 | selected.nextSibling.click(); | ||
175 | selected.nextSibling.focus(); | ||
176 | e.preventDefault(); | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | |||
181 | var updateSearchResults = function() {}; | ||
182 | |||
183 | function indexFilesLoaded() { | ||
184 | return moduleSearchIndex | ||
185 | && packageSearchIndex | ||
186 | && typeSearchIndex | ||
187 | && memberSearchIndex | ||
188 | && tagSearchIndex; | ||
189 | } | ||
190 | // Copy the contents of the local snippet to the clipboard | ||
191 | function copySnippet(button) { | ||
192 | copyToClipboard(button.nextElementSibling.innerText); | ||
193 | switchCopyLabel(button, button.firstElementChild); | ||
194 | } | ||
195 | function copyToClipboard(content) { | ||
196 | var textarea = document.createElement("textarea"); | ||
197 | textarea.style.height = 0; | ||
198 | document.body.appendChild(textarea); | ||
199 | textarea.value = content; | ||
200 | textarea.select(); | ||
201 | document.execCommand("copy"); | ||
202 | document.body.removeChild(textarea); | ||
203 | } | ||
204 | function switchCopyLabel(button, span) { | ||
205 | var copied = span.getAttribute("data-copied"); | ||
206 | button.classList.add("visible"); | ||
207 | var initialLabel = span.innerHTML; | ||
208 | span.innerHTML = copied; | ||
209 | setTimeout(function() { | ||
210 | button.classList.remove("visible"); | ||
211 | setTimeout(function() { | ||
212 | if (initialLabel !== copied) { | ||
213 | span.innerHTML = initialLabel; | ||
214 | } | ||
215 | }, 100); | ||
216 | }, 1900); | ||
217 | } | ||
218 | function setTopMargin() { | ||
219 | // Dynamically set scroll margin to accomodate for draft header | ||
220 | var headerHeight = Math.ceil(document.querySelector("header").offsetHeight); | ||
221 | document.querySelector(":root") | ||
222 | .style.setProperty("--nav-height", headerHeight + "px"); | ||
223 | } | ||
224 | document.addEventListener("readystatechange", (e) => { | ||
225 | if (document.readyState === "interactive") { | ||
226 | setTopMargin(); | ||
227 | } | ||
228 | if (sessionStorage.getItem("sidebar") === "hidden") { | ||
229 | const sidebar = document.querySelector(".main-grid nav.toc"); | ||
230 | if (sidebar) sidebar.classList.add("hide-sidebar"); | ||
231 | } | ||
232 | }); | ||
233 | document.addEventListener("DOMContentLoaded", function(e) { | ||
234 | setTopMargin(); | ||
235 | // Make sure current element is visible in breadcrumb navigation on small displays | ||
236 | const subnav = document.querySelector("ol.sub-nav-list"); | ||
237 | if (subnav && subnav.lastElementChild) { | ||
238 | subnav.lastElementChild.scrollIntoView({ behavior: "instant", inline: "start", block: "nearest" }); | ||
239 | } | ||
240 | // Clone TOC sidebar to header for mobile navigation | ||
241 | const navbar = document.querySelector("div#navbar-top"); | ||
242 | const sidebar = document.querySelector(".main-grid nav.toc"); | ||
243 | const main = document.querySelector(".main-grid main"); | ||
244 | const mainnav = navbar.querySelector("ul.nav-list"); | ||
245 | const toggleButton = document.querySelector("button#navbar-toggle-button"); | ||
246 | const toc = sidebar ? sidebar.cloneNode(true) : null; | ||
247 | if (toc) { | ||
248 | navbar.appendChild(toc); | ||
249 | } | ||
250 | document.querySelectorAll("input.filter-input").forEach(function(input) { | ||
251 | input.removeAttribute("disabled"); | ||
252 | input.setAttribute("autocapitalize", "off"); | ||
253 | input.value = ""; | ||
254 | input.addEventListener("input", function(e) { | ||
255 | const pattern = input.value ? input.value.trim() | ||
256 | .replace(/[\[\]{}()*+?.\\^$|]/g, '\\$&') | ||
257 | .replace(/\s+/g, ".*") : ""; | ||
258 | input.nextElementSibling.style.display = pattern ? "inline" : "none"; | ||
259 | const filter = new RegExp(pattern, "i"); | ||
260 | input.parentNode.parentNode.querySelectorAll("ol.toc-list li").forEach((li) => { | ||
261 | if (filter.test(li.innerText)) { | ||
262 | li.removeAttribute("style"); | ||
263 | } else { | ||
264 | li.style.display = "none"; | ||
265 | } | ||
266 | }); | ||
267 | if (expanded) { | ||
268 | expand(); | ||
269 | } | ||
270 | }); | ||
271 | }); | ||
272 | document.querySelectorAll("input.reset-filter").forEach((button) => { | ||
273 | button.removeAttribute("disabled"); | ||
274 | button.addEventListener("click", (e) => { | ||
275 | const input = button.previousElementSibling; | ||
276 | input.value = ""; | ||
277 | input.dispatchEvent(new InputEvent("input")); | ||
278 | input.focus(); | ||
279 | if (expanded) { | ||
280 | expand(); | ||
281 | } else { | ||
282 | prevHash = null; | ||
283 | handleScroll(); | ||
284 | } | ||
285 | }) | ||
286 | }); | ||
287 | var expanded = false; | ||
288 | var windowWidth; | ||
289 | function collapse() { | ||
290 | if (expanded) { | ||
291 | mainnav.removeAttribute("style"); | ||
292 | if (toc) { | ||
293 | toc.removeAttribute("style"); | ||
294 | } | ||
295 | toggleButton.classList.remove("expanded") | ||
296 | toggleButton.setAttribute("aria-expanded", "false"); | ||
297 | expanded = false; | ||
298 | } | ||
299 | } | ||
300 | function expand() { | ||
301 | expanded = true; | ||
302 | mainnav.style.display = "block"; | ||
303 | mainnav.style.removeProperty("height"); | ||
304 | var maxHeight = window.innerHeight - subnav.offsetTop + 4; | ||
305 | var expandedHeight = Math.min(maxHeight, mainnav.scrollHeight + 10); | ||
306 | if (toc) { | ||
307 | toc.style.display = "flex"; | ||
308 | expandedHeight = Math.min(maxHeight, | ||
309 | Math.max(expandedHeight, toc.querySelector("div.toc-header").offsetHeight | ||
310 | + toc.querySelector("ol.toc-list").scrollHeight + 10)); | ||
311 | toc.style.height = expandedHeight + "px"; | ||
312 | } | ||
313 | mainnav.style.height = expandedHeight + "px"; | ||
314 | toggleButton.classList.add("expanded"); | ||
315 | toggleButton.setAttribute("aria-expanded", "true"); | ||
316 | windowWidth = window.innerWidth; | ||
317 | } | ||
318 | toggleButton.addEventListener("click", (e) => { | ||
319 | if (expanded) { | ||
320 | collapse(); | ||
321 | } else { | ||
322 | expand(); | ||
323 | } | ||
324 | }); | ||
325 | if (toc) { | ||
326 | toc.querySelectorAll("a").forEach((link) => { | ||
327 | link.addEventListener("click", collapse); | ||
328 | }); | ||
329 | } | ||
330 | document.addEventListener('keydown', (e) => { | ||
331 | if (e.key === "Escape") collapse(); | ||
332 | }); | ||
333 | document.querySelector("main").addEventListener("click", collapse); | ||
334 | const searchInput = document.getElementById("search-input"); | ||
335 | if (searchInput) searchInput.addEventListener("focus", collapse); | ||
336 | document.querySelectorAll("h1, h2, h3, h4, h5, h6") | ||
337 | .forEach((hdr, idx) => { | ||
338 | // Create anchor links for headers with an associated id attribute | ||
339 | var id = hdr.getAttribute("id") || hdr.parentElement.getAttribute("id") | ||
340 | || (hdr.querySelector("a") && hdr.querySelector("a").getAttribute("id")); | ||
341 | if (id) { | ||
342 | var template = document.createElement('template'); | ||
343 | template.innerHTML =" <a href='#" + encodeURI(id) + "' class='anchor-link' aria-label='" + linkToSection | ||
344 | + "'><img src='" + pathtoroot + "resource-files/link.svg' alt='" + linkIcon +"' tabindex='0'" | ||
345 | + " width='16' height='16'></a>"; | ||
346 | hdr.append(...template.content.childNodes); | ||
347 | } | ||
348 | }); | ||
349 | var sections; | ||
350 | var scrollTimeout; | ||
351 | var scrollTimeoutNeeded; | ||
352 | var prevHash; | ||
353 | function initSectionData() { | ||
354 | sections = [{ id: "", top: 0 }].concat(Array.from(main.querySelectorAll("section[id], h2[id], h2 a[id], div[id]")) | ||
355 | .filter((e) => { | ||
356 | return sidebar.querySelector("a[href=\"#" + encodeURI(e.getAttribute("id")) + "\"]") !== null | ||
357 | }).map((e) => { | ||
358 | return { | ||
359 | id: e.getAttribute("id"), | ||
360 | top: e.offsetTop | ||
361 | }; | ||
362 | })); | ||
363 | } | ||
364 | function setScrollTimeout() { | ||
365 | clearTimeout(scrollTimeout); | ||
366 | scrollTimeoutNeeded = false; | ||
367 | scrollTimeout = setTimeout(() => { | ||
368 | scrollTimeout = null; | ||
369 | handleScroll(); | ||
370 | }, 100); | ||
371 | } | ||
372 | function handleScroll() { | ||
373 | if (!sidebar || !sidebar.offsetParent || sidebar.classList.contains("hide-sidebar")) { | ||
374 | return; | ||
375 | } | ||
376 | if (scrollTimeout || scrollTimeoutNeeded) { | ||
377 | setScrollTimeout(); | ||
378 | return; | ||
379 | } | ||
380 | var scrollTop = document.documentElement.scrollTop; | ||
381 | var scrollHeight = document.documentElement.scrollHeight; | ||
382 | var currHash = null; | ||
383 | if (scrollHeight - scrollTop < window.innerHeight + 10) { | ||
384 | // Select last item if at bottom of the page | ||
385 | currHash = "#" + encodeURI(sections.at(-1).id); | ||
386 | } else { | ||
387 | for (var i = 0; i < sections.length; i++) { | ||
388 | var top = sections[i].top; | ||
389 | var bottom = sections[i + 1] ? sections[i + 1].top : scrollHeight; | ||
390 | if (top + ((bottom - top) / 2) > scrollTop || bottom > scrollTop + (window.innerHeight / 3)) { | ||
391 | currHash = "#" + encodeURI(sections[i].id); | ||
392 | break; | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | if (currHash !== prevHash) { | ||
397 | setSelected(currHash); | ||
398 | } | ||
399 | } | ||
400 | function setSelected(hash) { | ||
401 | var prev = sidebar.querySelector("a.current-selection"); | ||
402 | if (prev) | ||
403 | prev.classList.remove("current-selection"); | ||
404 | prevHash = hash; | ||
405 | if (hash) { | ||
406 | var curr = sidebar.querySelector("ol.toc-list a[href=\"" + hash + "\"]"); | ||
407 | if (curr) { | ||
408 | curr.classList.add("current-selection"); | ||
409 | curr.scrollIntoView({ behavior: "instant", block: "nearest" }); | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | if (sidebar) { | ||
414 | initSectionData(); | ||
415 | document.querySelectorAll("a[href^='#']").forEach((link) => { | ||
416 | link.addEventListener("click", (e) => { | ||
417 | scrollTimeoutNeeded = true; | ||
418 | setSelected(link.getAttribute("href")); | ||
419 | }) | ||
420 | }); | ||
421 | sidebar.querySelector("button.hide-sidebar").addEventListener("click", () => { | ||
422 | sidebar.classList.add("hide-sidebar"); | ||
423 | sessionStorage.setItem("sidebar", "hidden"); | ||
424 | }); | ||
425 | sidebar.querySelector("button.show-sidebar").addEventListener("click", () => { | ||
426 | sidebar.classList.remove("hide-sidebar"); | ||
427 | sessionStorage.removeItem("sidebar"); | ||
428 | initSectionData(); | ||
429 | handleScroll(); | ||
430 | }); | ||
431 | window.addEventListener("hashchange", (e) => { | ||
432 | scrollTimeoutNeeded = true; | ||
433 | }); | ||
434 | if (document.location.hash) { | ||
435 | scrollTimeoutNeeded = true; | ||
436 | setSelected(document.location.hash); | ||
437 | } else { | ||
438 | handleScroll(); | ||
439 | } | ||
440 | window.addEventListener("scroll", handleScroll); | ||
441 | window.addEventListener("scrollend", () => { | ||
442 | if (scrollTimeout) { | ||
443 | clearTimeout(scrollTimeout); | ||
444 | scrollTimeout = null; | ||
445 | handleScroll(); | ||
446 | } | ||
447 | }) | ||
448 | } | ||
449 | // Resize handler | ||
450 | function handleResize(e) { | ||
451 | if (expanded) { | ||
452 | if (windowWidth !== window.innerWidth) { | ||
453 | collapse(); | ||
454 | } else { | ||
455 | expand(); | ||
456 | } | ||
457 | } | ||
458 | if (sections) { | ||
459 | initSectionData(); | ||
460 | prevHash = null; | ||
461 | handleScroll(); | ||
462 | } | ||
463 | setTopMargin(); | ||
464 | } | ||
465 | window.addEventListener("orientationchange", handleResize); | ||
466 | window.addEventListener("resize", handleResize); | ||
467 | }); | ||