-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathcustom.js
More file actions
180 lines (149 loc) · 6.83 KB
/
Copy pathcustom.js
File metadata and controls
180 lines (149 loc) · 6.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// custom js
// Mobile navigation: the site sets doks.bootstrapJavascript = false, so no
// Bootstrap plugins load and the header's offcanvas toggles are dead markup.
// Importing the Offcanvas plugin evaluates its module, which registers the
// data-bs-toggle="offcanvas" click handling; the window reference keeps the
// import (and its side effects) from being tree-shaken.
import { Offcanvas } from 'bootstrap';
window.ddOffcanvas = Offcanvas;
// Edition toggler (Open Source / Pro)
//
// The sidebar renders both edition menus (.version-opensource / .version-pro).
// Which menu shows — and which segmented-control button reads as selected —
// is pure CSS keyed off html[data-dd-version] (see _custom.scss). An inline
// script in custom-head.html stamps that attribute from localStorage before
// first paint, so every page load renders the stored edition immediately with
// no hide-then-reveal flicker. This module only handles toggling: update the
// attribute, persist the choice, sync aria-checked for assistive tech.
(() => {
"use strict";
// Asset-modelling landing pages per edition. The top nav is otherwise
// static, so a single URL can't be correct for both editions: we keep the
// "Model Your Assets" nav link in sync with the selected version, and —
// when the user is already viewing one of these pages — navigate to the
// matching edition's page so the main content follows the toggle.
const assetNavUrls = {
opensource: "/asset_modelling/engagements_tests/os__assets/",
pro: "/asset_modelling/pro_hierarchy/assets_organizations/",
};
const switchAssetPageForVersion = (version) => {
const target = assetNavUrls[version];
const other = assetNavUrls[version === "pro" ? "opensource" : "pro"];
// Only redirect when currently on the *other* edition's asset page,
// so this never fires on unrelated pages or loops on the target page.
if (target && location.pathname === other) {
location.assign(target);
}
};
const setVersion = (version) => {
// CSS shows the matching menu and highlights the matching button
document.documentElement.dataset.ddVersion = version;
try {
localStorage.setItem("version", version);
} catch (e) {
// Storage blocked (private browsing) — toggle still works this page
}
// aria-checked is for assistive tech only; visuals come from the
// html[data-dd-version] attribute above
document.querySelectorAll(".dd-version-seg button[data-version-value]").forEach(btn => {
btn.setAttribute("aria-checked", btn.dataset.versionValue === version ? "true" : "false");
});
// Edition-aware top nav: route "Model Your Assets" to the page that
// matches the selected version (see assetNavUrls above).
document.querySelectorAll("a.nav-link").forEach(link => {
if (link.textContent.trim() === "Model Your Assets") {
link.setAttribute("href", assetNavUrls[version] || assetNavUrls.opensource);
}
});
};
const initVersionToggle = () => {
// custom-head.html already stamped the stored edition on <html> before
// paint; re-applying it here syncs aria-checked and the nav link on
// freshly parsed (or dynamically replaced) markup.
setVersion(document.documentElement.dataset.ddVersion || "opensource");
};
// Delegated listener on body — catches every control instance
document.body.addEventListener("click", (e) => {
const btn = e.target.closest("button[data-version-value]");
if (btn) {
setVersion(btn.dataset.versionValue);
// Only on an explicit user toggle (not on load) follow the page to
// the matching edition when viewing an asset-modelling page.
switchAssetPageForVersion(btn.dataset.versionValue);
}
});
// Run on DOM ready
window.addEventListener("DOMContentLoaded", initVersionToggle);
// MutationObserver to detect dynamically replaced sidebar
const observer = new MutationObserver(() => {
// Re-run init to make sure menus match stored version
initVersionToggle();
});
observer.observe(document.body, { childList: true, subtree: true });
})();
// Code block language labels — stamp the fence language onto each
// expressive-code frame's (empty) title span so CSS can render it in the
// header band via attr(data-lang). Frames whose fence "language" is really
// an editor artifact (paths, line ranges) get a generic "code" label.
(() => {
"use strict";
const CLEAN_LANG = /^[a-z0-9_+#.-]{1,16}$/i;
const init = () => {
document.querySelectorAll(".docs-content .expressive-code .frame").forEach(frame => {
const title = frame.querySelector(".header .title");
if (!title || title.textContent.trim() !== "" || title.dataset.lang) return;
const code = frame.querySelector("pre code[data-lang]");
let lang = code ? code.dataset.lang : "";
if (!lang || lang === "fallback" || !CLEAN_LANG.test(lang)) lang = "code";
title.dataset.lang = lang;
frame.classList.add("dd-has-lang");
});
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
// Homepage hero search field — forwards to the DocSearch modal
(() => {
"use strict";
const init = () => {
const trigger = document.getElementById("ddHomeSearch");
if (!trigger) return;
trigger.addEventListener("click", () => {
const btn = document.getElementsByClassName("DocSearch-Button")[0];
if (btn) btn.click();
});
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
// Scroll progress bar — shows reading progress on doc pages
(() => {
"use strict";
const init = () => {
// Only add on doc pages (pages with .docs-content)
if (!document.querySelector('.docs-content')) return;
const bar = document.createElement('div');
bar.className = 'scroll-progress';
bar.style.width = '0%';
document.body.appendChild(bar);
const update = () => {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
bar.style.width = progress + '%';
};
window.addEventListener('scroll', update, { passive: true });
update();
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();