|
1 | 1 | // custom js |
2 | 2 |
|
3 | | - |
4 | | -// version toggler |
| 3 | +// Mobile navigation: the site sets doks.bootstrapJavascript = false, so no |
| 4 | +// Bootstrap plugins load and the header's offcanvas toggles are dead markup. |
| 5 | +// Importing the Offcanvas plugin evaluates its module, which registers the |
| 6 | +// data-bs-toggle="offcanvas" click handling; the window reference keeps the |
| 7 | +// import (and its side effects) from being tree-shaken. |
| 8 | +import { Offcanvas } from 'bootstrap'; |
| 9 | + |
| 10 | +window.ddOffcanvas = Offcanvas; |
| 11 | + |
| 12 | + |
| 13 | +// Edition toggler (Open Source / Pro) |
| 14 | +// |
| 15 | +// The sidebar renders both edition menus (.version-opensource / .version-pro). |
| 16 | +// Which menu shows — and which segmented-control button reads as selected — |
| 17 | +// is pure CSS keyed off html[data-dd-version] (see _custom.scss). An inline |
| 18 | +// script in custom-head.html stamps that attribute from localStorage before |
| 19 | +// first paint, so every page load renders the stored edition immediately with |
| 20 | +// no hide-then-reveal flicker. This module only handles toggling: update the |
| 21 | +// attribute, persist the choice, sync aria-checked for assistive tech. |
5 | 22 | (() => { |
6 | 23 | "use strict"; |
7 | 24 |
|
8 | | - console.log("[VersionToggle] custom.js loaded"); |
9 | | - |
10 | 25 | // Asset-modelling landing pages per edition. The top nav is otherwise |
11 | 26 | // static, so a single URL can't be correct for both editions: we keep the |
12 | 27 | // "Model Your Assets" nav link in sync with the selected version, and — |
|
28 | 43 | }; |
29 | 44 |
|
30 | 45 | const setVersion = (version) => { |
31 | | - console.log("[VersionToggle] Setting version to:", version); |
| 46 | + // CSS shows the matching menu and highlights the matching button |
| 47 | + document.documentElement.dataset.ddVersion = version; |
32 | 48 |
|
33 | | - document.querySelectorAll(".version-opensource, .version-pro").forEach(el => { |
34 | | - el.style.display = el.classList.contains(`version-${version}`) ? "block" : "none"; |
35 | | - }); |
36 | | - |
37 | | - localStorage.setItem("version", version); |
38 | | - console.log("[VersionToggle] localStorage updated:", localStorage.getItem("version")); |
| 49 | + try { |
| 50 | + localStorage.setItem("version", version); |
| 51 | + } catch (e) { |
| 52 | + // Storage blocked (private browsing) — toggle still works this page |
| 53 | + } |
39 | 54 |
|
40 | | - // Update dropdown |
41 | | - const selects = document.querySelectorAll("#version-select"); |
42 | | - selects.forEach(sel => { |
43 | | - sel.value = version; |
44 | | - sel.dataset.version = version; |
45 | | - sel.style.visibility = "visible"; |
| 55 | + // aria-checked is for assistive tech only; visuals come from the |
| 56 | + // html[data-dd-version] attribute above |
| 57 | + document.querySelectorAll(".dd-version-seg button[data-version-value]").forEach(btn => { |
| 58 | + btn.setAttribute("aria-checked", btn.dataset.versionValue === version ? "true" : "false"); |
46 | 59 | }); |
47 | 60 |
|
48 | | - // unhide sidebar after version is applied |
49 | | - const sidebar = document.querySelector(".docs-sidebar"); |
50 | | - if (sidebar) { |
51 | | - sidebar.style.visibility = "visible"; |
52 | | - console.log("[VersionToggle] Sidebar revealed"); |
53 | | - } |
54 | | - |
55 | 61 | // Edition-aware top nav: route "Model Your Assets" to the page that |
56 | 62 | // matches the selected version (see assetNavUrls above). |
57 | 63 | document.querySelectorAll("a.nav-link").forEach(link => { |
|
62 | 68 | }; |
63 | 69 |
|
64 | 70 | const initVersionToggle = () => { |
65 | | - const storedVersion = localStorage.getItem("version") || "opensource"; |
66 | | - console.log("[VersionToggle] Stored version:", storedVersion); |
67 | | - setVersion(storedVersion); |
| 71 | + // custom-head.html already stamped the stored edition on <html> before |
| 72 | + // paint; re-applying it here syncs aria-checked and the nav link on |
| 73 | + // freshly parsed (or dynamically replaced) markup. |
| 74 | + setVersion(document.documentElement.dataset.ddVersion || "opensource"); |
68 | 75 | }; |
69 | 76 |
|
70 | | - // Delegated listener on body |
71 | | - document.body.addEventListener("change", (e) => { |
72 | | - if (e.target && e.target.id === "version-select") { |
73 | | - console.log("[VersionToggle] Dropdown changed to:", e.target.value); |
74 | | - setVersion(e.target.value); |
| 77 | + // Delegated listener on body — catches every control instance |
| 78 | + document.body.addEventListener("click", (e) => { |
| 79 | + const btn = e.target.closest("button[data-version-value]"); |
| 80 | + if (btn) { |
| 81 | + setVersion(btn.dataset.versionValue); |
75 | 82 | // Only on an explicit user toggle (not on load) follow the page to |
76 | 83 | // the matching edition when viewing an asset-modelling page. |
77 | | - switchAssetPageForVersion(e.target.value); |
| 84 | + switchAssetPageForVersion(btn.dataset.versionValue); |
78 | 85 | } |
79 | 86 | }); |
80 | 87 |
|
|
91 | 98 | })(); |
92 | 99 |
|
93 | 100 |
|
| 101 | +// Code block language labels — stamp the fence language onto each |
| 102 | +// expressive-code frame's (empty) title span so CSS can render it in the |
| 103 | +// header band via attr(data-lang). Frames whose fence "language" is really |
| 104 | +// an editor artifact (paths, line ranges) get a generic "code" label. |
| 105 | +(() => { |
| 106 | + "use strict"; |
| 107 | + |
| 108 | + const CLEAN_LANG = /^[a-z0-9_+#.-]{1,16}$/i; |
| 109 | + |
| 110 | + const init = () => { |
| 111 | + document.querySelectorAll(".docs-content .expressive-code .frame").forEach(frame => { |
| 112 | + const title = frame.querySelector(".header .title"); |
| 113 | + if (!title || title.textContent.trim() !== "" || title.dataset.lang) return; |
| 114 | + const code = frame.querySelector("pre code[data-lang]"); |
| 115 | + let lang = code ? code.dataset.lang : ""; |
| 116 | + if (!lang || lang === "fallback" || !CLEAN_LANG.test(lang)) lang = "code"; |
| 117 | + title.dataset.lang = lang; |
| 118 | + frame.classList.add("dd-has-lang"); |
| 119 | + }); |
| 120 | + }; |
| 121 | + |
| 122 | + if (document.readyState === "loading") { |
| 123 | + document.addEventListener("DOMContentLoaded", init); |
| 124 | + } else { |
| 125 | + init(); |
| 126 | + } |
| 127 | +})(); |
| 128 | + |
| 129 | + |
| 130 | +// Homepage hero search field — forwards to the DocSearch modal |
| 131 | +(() => { |
| 132 | + "use strict"; |
| 133 | + |
| 134 | + const init = () => { |
| 135 | + const trigger = document.getElementById("ddHomeSearch"); |
| 136 | + if (!trigger) return; |
| 137 | + trigger.addEventListener("click", () => { |
| 138 | + const btn = document.getElementsByClassName("DocSearch-Button")[0]; |
| 139 | + if (btn) btn.click(); |
| 140 | + }); |
| 141 | + }; |
| 142 | + |
| 143 | + if (document.readyState === "loading") { |
| 144 | + document.addEventListener("DOMContentLoaded", init); |
| 145 | + } else { |
| 146 | + init(); |
| 147 | + } |
| 148 | +})(); |
| 149 | + |
| 150 | + |
94 | 151 | // Scroll progress bar — shows reading progress on doc pages |
95 | 152 | (() => { |
96 | 153 | "use strict"; |
|
0 commit comments