script.js (21563B)
1 /* 2 * Copyright (c) 2013, 2025, 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 if (typeof hljs !== "undefined") { 25 try { 26 hljs.highlightAll(); 27 } catch (err) { 28 console.error(err) 29 } 30 } 31 32 function loadScripts(doc, tag) { 33 createElem(doc, tag, 'script-files/search.js'); 34 35 createElem(doc, tag, 'module-search-index.js'); 36 createElem(doc, tag, 'package-search-index.js'); 37 createElem(doc, tag, 'type-search-index.js'); 38 createElem(doc, tag, 'member-search-index.js'); 39 createElem(doc, tag, 'tag-search-index.js'); 40 } 41 42 function createElem(doc, tag, path) { 43 var script = doc.createElement(tag); 44 var scriptElement = doc.getElementsByTagName(tag)[0]; 45 script.src = pathtoroot + path; 46 scriptElement.parentNode.insertBefore(script, scriptElement); 47 } 48 49 // Helper for making content containing release names comparable lexicographically 50 function makeComparable(s) { 51 return s.toLowerCase().replace(/(\d+)/g, 52 function(n, m) { 53 return ("000" + m).slice(-4); 54 }); 55 } 56 57 // Switches between two styles depending on a condition 58 function toggleStyle(classList, condition, trueStyle, falseStyle) { 59 if (condition) { 60 classList.remove(falseStyle); 61 classList.add(trueStyle); 62 } else { 63 classList.remove(trueStyle); 64 classList.add(falseStyle); 65 } 66 } 67 68 // Sorts the rows in a table lexicographically by the content of a specific column 69 function sortTable(header, columnIndex, columns) { 70 var container = header.parentElement; 71 var descending = header.classList.contains(sortAsc); 72 container.querySelectorAll("div.table-header").forEach( 73 function(header) { 74 header.classList.remove(sortAsc); 75 header.classList.remove(sortDesc); 76 } 77 ) 78 var cells = container.children; 79 var rows = []; 80 for (var i = columns; i < cells.length; i += columns) { 81 rows.push(Array.prototype.slice.call(cells, i, i + columns)); 82 } 83 var comparator = function(a, b) { 84 var ka = makeComparable(a[columnIndex].textContent); 85 var kb = makeComparable(b[columnIndex].textContent); 86 if (ka < kb) 87 return descending ? 1 : -1; 88 if (ka > kb) 89 return descending ? -1 : 1; 90 return 0; 91 }; 92 var sorted = rows.sort(comparator); 93 var visible = 0; 94 sorted.forEach(function(row) { 95 if (row[0].style.display !== 'none') { 96 var isEvenRow = visible++ % 2 === 0; 97 } 98 row.forEach(function(cell) { 99 toggleStyle(cell.classList, isEvenRow, evenRowColor, oddRowColor); 100 container.appendChild(cell); 101 }) 102 }); 103 toggleStyle(header.classList, descending, sortDesc, sortAsc); 104 } 105 106 // Toggles the visibility of a table category in all tables in a page 107 function toggleGlobal(checkbox, selected, columns) { 108 const display = checkbox.checked ? '' : 'none'; 109 const selectOther = selected === "other"; 110 const selectAll = selected === "all"; 111 if (selectAll) { 112 document.querySelectorAll('.checkboxes input[type="checkbox"]').forEach(c => { 113 c.checked = checkbox.checked; 114 }); 115 } 116 document.querySelectorAll("div.table-tabs").forEach(t => { 117 const id = t.parentElement.getAttribute("id"); 118 const selectedClass = id + "-tab" + (selectOther ? "" : selected); 119 var visible = 0; 120 t.parentElement.querySelectorAll('div.' + id) 121 .forEach(function(elem) { 122 if (selectAll 123 || (!selectOther && elem.classList.contains(selectedClass)) 124 || (selectOther && elem.className.indexOf(selectedClass) < 0)) { 125 elem.style.display = display; 126 } 127 if (elem.style.display === '') { 128 var isEvenRow = visible++ % (columns * 2) < columns; 129 toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); 130 } 131 }); 132 var displaySection = visible === 0 ? 'none' : ''; 133 t.parentElement.style.display = displaySection; 134 document.querySelector("li#contents-" + id).style.display = displaySection; 135 }) 136 } 137 138 // Shows the elements of a table belonging to a specific category 139 function show(tableId, selected, columns) { 140 if (tableId !== selected) { 141 document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') 142 .forEach(function(elem) { 143 elem.style.display = 'none'; 144 }); 145 } 146 document.querySelectorAll('div.' + selected) 147 .forEach(function(elem, index) { 148 elem.style.display = ''; 149 var isEvenRow = index % (columns * 2) < columns; 150 toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); 151 }); 152 updateTabs(tableId, selected); 153 } 154 155 function updateTabs(tableId, selected) { 156 document.getElementById(tableId + '.tabpanel') 157 .setAttribute('aria-labelledby', selected); 158 document.querySelectorAll('button[id^="' + tableId + '"]') 159 .forEach(function(tab, index) { 160 if (selected === tab.id || (tableId === selected && index === 0)) { 161 tab.className = activeTableTab; 162 tab.setAttribute('aria-selected', true); 163 tab.setAttribute('tabindex',0); 164 } else { 165 tab.className = tableTab; 166 tab.setAttribute('aria-selected', false); 167 tab.setAttribute('tabindex',-1); 168 } 169 }); 170 } 171 172 function switchTab(e) { 173 var selected = document.querySelector('[aria-selected=true]'); 174 if (selected) { 175 if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { 176 // left or up arrow key pressed: move focus to previous tab 177 selected.previousSibling.click(); 178 selected.previousSibling.focus(); 179 e.preventDefault(); 180 } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { 181 // right or down arrow key pressed: move focus to next tab 182 selected.nextSibling.click(); 183 selected.nextSibling.focus(); 184 e.preventDefault(); 185 } 186 } 187 } 188 189 var updateSearchResults = function() {}; 190 191 function indexFilesLoaded() { 192 return moduleSearchIndex 193 && packageSearchIndex 194 && typeSearchIndex 195 && memberSearchIndex 196 && tagSearchIndex; 197 } 198 // Copy the contents of the local snippet to the clipboard 199 function copySnippet(button) { 200 copyToClipboard(button.nextElementSibling.innerText); 201 switchCopyLabel(button, button.firstElementChild); 202 } 203 function copyToClipboard(content) { 204 var textarea = document.createElement("textarea"); 205 textarea.style.height = 0; 206 document.body.appendChild(textarea); 207 textarea.value = content; 208 textarea.select(); 209 document.execCommand("copy"); 210 document.body.removeChild(textarea); 211 } 212 function resetInput(input, event, blur) { 213 if (input.value) { 214 input.value = ""; 215 input.dispatchEvent(new InputEvent("input")); 216 } else if (blur) { 217 input.blur(); 218 } 219 event.preventDefault(); 220 } 221 function isInput(elem) { 222 return elem instanceof HTMLInputElement && elem.type === "text"; 223 } 224 function switchCopyLabel(button, span) { 225 var copied = span.getAttribute("data-copied"); 226 button.classList.add("visible"); 227 var initialLabel = span.innerHTML; 228 span.innerHTML = copied; 229 setTimeout(function() { 230 button.classList.remove("visible"); 231 setTimeout(function() { 232 if (initialLabel !== copied) { 233 span.innerHTML = initialLabel; 234 } 235 }, 100); 236 }, 1900); 237 } 238 function makeFilterWidget(sidebar, updateToc) { 239 if (!sidebar) { 240 return null; 241 } 242 const filterInput = sidebar.querySelector("input.filter-input"); 243 const resetInput = sidebar.querySelector("input.reset-filter"); 244 sidebar.addEventListener("keydown", e => { 245 if (e.ctrlKey || e.altKey || e.metaKey) { 246 return; 247 } 248 if (e.key === "ArrowUp" || e.key === "ArrowDown") { 249 handleTocFocus(e); 250 } else if (filterInput && e.target !== filterInput) { 251 if (e.key === "Enter" && isTocLink(sidebar, e.target)) { 252 filterInput.value = ""; 253 filterInput.dispatchEvent(new InputEvent("input")); 254 } else if (e.key.length === 1 || e.key === "Backspace") { 255 filterInput.focus(); 256 } 257 } 258 }); 259 if (filterInput) { 260 filterInput.removeAttribute("disabled"); 261 filterInput.setAttribute("autocapitalize", "off"); 262 filterInput.value = ""; 263 filterInput.addEventListener("input", function(e) { 264 resetInput.style.visibility = filterInput.value ? "visible" : "hidden"; 265 const pattern = filterInput.value ? filterInput.value.trim() 266 .replace(/[\[\]{}()*+?.\\^$|]/g, '\\$&') 267 .replace(/\s+/g, ".*") : ""; 268 const filter = new RegExp(pattern, "i"); 269 sidebar.querySelectorAll("ol.toc-list li").forEach((li) => { 270 if (filter.test(li.innerText)) { 271 // li.removeAttribute("style"); 272 const selfMatch = filter.test(li.firstElementChild.innerText); 273 li.style.display = "block"; 274 li.firstElementChild.style.opacity = selfMatch ? "100%" : "70%"; 275 li.firstElementChild.tabIndex = selfMatch ? 0 : -1; 276 } else { 277 li.style.display = "none"; 278 } 279 }); 280 updateToc(); 281 }); 282 } 283 if (resetInput) { 284 resetInput.removeAttribute("disabled"); 285 resetInput.addEventListener("click", (e) => { 286 filterInput.value = ""; 287 filterInput.focus(); 288 filterInput.dispatchEvent(new InputEvent("input")); 289 }); 290 } 291 function handleTocFocus(event) { 292 let links = Array.from(sidebar.querySelectorAll("ol > li > a")) 293 .filter(link => link.offsetParent && link.tabIndex === 0); 294 let current = links.indexOf(document.activeElement); 295 if (event.key === "ArrowUp") { 296 if (current > 0) { 297 links[current - 1].focus({focusVisible: true}); 298 } else if (filterInput) { 299 filterInput.focus(); 300 } 301 } else if (event.key === "ArrowDown" && current < links.length - 1) { 302 links[current + 1].focus({focusVisible: true}); 303 } 304 event.preventDefault(); 305 } 306 function isTocLink(sidebar, elem) { 307 let links = Array.from(sidebar.querySelectorAll("ol > li > a")) 308 .filter(link => link.offsetParent && link.tabIndex === 0); 309 return links.indexOf(elem) > -1; 310 } 311 return sidebar; 312 } 313 314 function setTopMargin() { 315 // Dynamically set scroll margin to accomodate for draft header 316 var headerHeight = Math.ceil(document.querySelector("header").offsetHeight); 317 document.querySelector(":root") 318 .style.setProperty("--nav-height", headerHeight + "px"); 319 } 320 document.addEventListener("readystatechange", (e) => { 321 if (document.readyState === "interactive") { 322 setTopMargin(); 323 } 324 if (sessionStorage.getItem("sidebar") === "hidden") { 325 const sidebar = document.querySelector(".main-grid nav.toc"); 326 if (sidebar) sidebar.classList.add("hide-sidebar"); 327 } 328 }); 329 document.addEventListener("DOMContentLoaded", function(e) { 330 setTopMargin(); 331 // Make sure current element is visible in breadcrumb navigation on small displays 332 const subnav = document.querySelector("ol.sub-nav-list"); 333 if (subnav && subnav.lastElementChild) { 334 subnav.lastElementChild.scrollIntoView({ behavior: "instant", inline: "start", block: "nearest" }); 335 } 336 const keymap = new Map(); 337 const searchInput = document.getElementById("search-input") 338 || document.getElementById("page-search-input"); 339 if (searchInput) { 340 searchInput.addEventListener("focus", collapse); 341 keymap.set("/", searchInput); 342 } 343 const filterInput = document.querySelector("input.filter-input"); 344 if (filterInput) { 345 keymap.set(".", filterInput); 346 } 347 // Clone TOC sidebar to header for mobile navigation 348 const navbar = document.querySelector("div#navbar-top"); 349 const sidebar = document.querySelector(".main-grid nav.toc"); 350 const main = document.querySelector(".main-grid main"); 351 const mainnav = navbar.querySelector("ul.nav-list"); 352 const toggleButton = document.querySelector("button#navbar-toggle-button"); 353 const tocMenu = sidebar ? sidebar.cloneNode(true) : null; 354 makeFilterWidget(sidebar, updateToc); 355 if (tocMenu) { 356 navbar.appendChild(tocMenu); 357 makeFilterWidget(tocMenu, updateToc); 358 var menuInput = tocMenu.querySelector("input.filter-input"); 359 } 360 document.addEventListener("keydown", (e) => { 361 if (e.ctrlKey || e.altKey || e.metaKey) { 362 return; 363 } 364 if (!isInput(e.target) && keymap.has(e.key)) { 365 var elem = keymap.get(e.key); 366 if (elem === filterInput && !elem.offsetParent) { 367 elem = getVisibleFilterInput(true); 368 } 369 elem.focus(); 370 elem.select(); 371 e.preventDefault(); 372 } else if (e.key === "Escape") { 373 if (expanded) { 374 collapse(); 375 e.preventDefault(); 376 } else if (e.target.id === "page-search-input") { 377 resetInput(e.target, e, false); 378 } else if (isInput(e.target)) { 379 resetInput(e.target, e, true); 380 } else { 381 var filter = getVisibleFilterInput(false); 382 if (filter && filter.value) { 383 resetInput(filterInput, e, true); 384 } 385 } 386 } 387 }); 388 var expanded = false; 389 var windowWidth; 390 var bodyHeight; 391 function collapse() { 392 if (expanded) { 393 mainnav.removeAttribute("style"); 394 if (tocMenu) { 395 tocMenu.removeAttribute("style"); 396 if (filterInput) { 397 keymap.set(".", filterInput); 398 } 399 } 400 toggleButton.classList.remove("expanded") 401 toggleButton.setAttribute("aria-expanded", "false"); 402 expanded = false; 403 } 404 } 405 function expand() { 406 expanded = true; 407 mainnav.style.display = "block"; 408 mainnav.style.removeProperty("height"); 409 var maxHeight = window.innerHeight - subnav.offsetTop + 4; 410 var expandedHeight = Math.min(maxHeight, mainnav.scrollHeight + 10); 411 if (tocMenu) { 412 tocMenu.style.display = "flex"; 413 expandedHeight = Math.min(maxHeight, 414 Math.max(expandedHeight, tocMenu.querySelector("div.toc-header").offsetHeight 415 + tocMenu.querySelector("ol.toc-list").scrollHeight + 10)); 416 tocMenu.style.height = expandedHeight + "px"; 417 if (menuInput) { 418 keymap.set(".", menuInput); 419 } 420 } 421 mainnav.style.height = expandedHeight + "px"; 422 toggleButton.classList.add("expanded"); 423 toggleButton.setAttribute("aria-expanded", "true"); 424 windowWidth = window.innerWidth; 425 } 426 function updateToc() { 427 if (expanded) { 428 expand(); 429 } else { 430 prevHash = null; 431 handleScroll(); 432 } 433 } 434 function getVisibleFilterInput(show) { 435 if (sidebar && sidebar.offsetParent) { 436 if (show) { 437 showSidebar(); 438 } 439 return filterInput; 440 } else { 441 if (show) { 442 expand(); 443 } 444 return menuInput; 445 } 446 } 447 toggleButton.addEventListener("click", (e) => { 448 if (expanded) { 449 collapse(); 450 } else { 451 expand(); 452 } 453 }); 454 if (tocMenu) { 455 tocMenu.querySelectorAll("a").forEach((link) => { 456 link.addEventListener("click", collapse); 457 }); 458 } 459 document.querySelector("main").addEventListener("click", collapse); 460 document.querySelectorAll("h1, h2, h3, h4, h5, h6") 461 .forEach((hdr, idx) => { 462 // Create anchor links for headers with an associated id attribute 463 var id = hdr.parentElement.getAttribute("id") || hdr.getAttribute("id") 464 || (hdr.querySelector("a") && hdr.querySelector("a").getAttribute("id")); 465 if (id) { 466 var template = document.createElement('template'); 467 template.innerHTML =" <a href='#" + encodeURI(id) + "' class='anchor-link' aria-label='" + linkToSection 468 + "'><img src='" + pathtoroot + "resource-files/link.svg' alt='" + linkIcon +"' tabindex='0'" 469 + " width='16' height='16'></a>"; 470 hdr.append(...template.content.childNodes); 471 } 472 }); 473 var sections; 474 var scrollTimeout; 475 var prevHash; 476 function initSectionData() { 477 bodyHeight = document.body.offsetHeight; 478 sections = [{ id: "", top: 0 }].concat(Array.from(main.querySelectorAll( 479 "section[id], h2[id], h2 a[id], h3[id], h3 a[id], div[id]")) 480 .filter((e) => { 481 return sidebar.querySelector("a[href=\"#" + encodeURI(e.getAttribute("id")) + "\"]") !== null 482 }).map((e) => { 483 return { 484 id: e.getAttribute("id"), 485 top: e.offsetTop 486 }; 487 })); 488 } 489 function setScrollTimeout() { 490 if (scrollTimeout) { 491 clearTimeout(scrollTimeout); 492 } 493 scrollTimeout = setTimeout(() => { 494 scrollTimeout = null; 495 }, 100); 496 } 497 function handleScroll() { 498 if (!sidebar || !sidebar.offsetParent || sidebar.classList.contains("hide-sidebar")) { 499 return; 500 } 501 if (scrollTimeout) { 502 setScrollTimeout(); 503 return; 504 } 505 var scrollTop = document.documentElement.scrollTop; 506 var scrollHeight = document.documentElement.scrollHeight; 507 var currHash = null; 508 for (var i = 0; i < sections.length; i++) { 509 var top = sections[i].top; 510 var bottom = sections[i + 1] ? sections[i + 1].top : scrollHeight; 511 if (top + ((bottom - top) / 2) > scrollTop || bottom > scrollTop + (window.innerHeight / 3)) { 512 currHash = "#" + encodeURI(sections[i].id); 513 break; 514 } 515 } 516 if (currHash !== prevHash) { 517 setSelected(currHash); 518 } 519 } 520 function setSelected(hash) { 521 var prev = sidebar.querySelector("a.current-selection"); 522 if (prev) 523 prev.classList.remove("current-selection"); 524 prevHash = hash; 525 if (hash) { 526 var curr = sidebar.querySelector("ol.toc-list a[href=\"" + hash + "\"]"); 527 if (curr) { 528 curr.classList.add("current-selection"); 529 curr.scrollIntoView({ behavior: "instant", block: "nearest" }); 530 } 531 } 532 } 533 function hideSidebar() { 534 sidebar.classList.add("hide-sidebar"); 535 sessionStorage.setItem("sidebar", "hidden"); 536 } 537 function showSidebar() { 538 sidebar.classList.remove("hide-sidebar"); 539 sessionStorage.removeItem("sidebar"); 540 initSectionData(); 541 handleScroll(); 542 } 543 if (sidebar) { 544 initSectionData(); 545 document.querySelectorAll("a[href^='#']").forEach((link) => { 546 link.addEventListener("click", (e) => { 547 link.blur(); 548 setScrollTimeout(); 549 setSelected(link.getAttribute("href")); 550 }) 551 }); 552 sidebar.querySelector("button.hide-sidebar").addEventListener("click", hideSidebar); 553 sidebar.querySelector("button.show-sidebar").addEventListener("click", showSidebar); 554 window.addEventListener("hashchange", (e) => { 555 setScrollTimeout(); 556 const hash = e.newURL.indexOf("#"); 557 if (hash > -1) { 558 setSelected(e.newURL.substring(hash)); 559 } 560 }); 561 if (document.location.hash) { 562 setScrollTimeout(); 563 setSelected(document.location.hash); 564 } else { 565 handleScroll(); 566 } 567 window.addEventListener("scroll", handleScroll); 568 } 569 // Resize handler 570 new ResizeObserver((entries) => { 571 if (expanded) { 572 if (windowWidth !== window.innerWidth) { 573 collapse(); 574 } else { 575 expand(); 576 } 577 } 578 if (sections && document.body.offsetHeight !== bodyHeight) { 579 initSectionData(); 580 prevHash = null; 581 handleScroll(); 582 } 583 setTopMargin(); 584 }).observe(document.body); 585 });