hyperbook 0.84.3 → 0.84.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/bootstrap.js +248 -0
- package/dist/assets/cloud.js +217 -169
- package/dist/assets/directive-abc-music/client.js +11 -3
- package/dist/assets/directive-archive/client.js +17 -4
- package/dist/assets/directive-audio/client.js +67 -28
- package/dist/assets/directive-bookmarks/client.js +9 -1
- package/dist/assets/directive-download/client.js +10 -2
- package/dist/assets/directive-excalidraw/client.js +9 -0
- package/dist/assets/directive-excalidraw/hyperbook-excalidraw.umd.js +1 -1
- package/dist/assets/directive-geogebra/client.js +16 -3
- package/dist/assets/directive-h5p/client.js +32 -3
- package/dist/assets/directive-learningmap/client.js +11 -3
- package/dist/assets/directive-mermaid/client.js +11 -1
- package/dist/assets/directive-multievent/multievent.js +2 -2
- package/dist/assets/directive-onlineide/client.js +7 -0
- package/dist/assets/directive-onlineide/include/online-ide-embedded.js +43 -43
- package/dist/assets/directive-p5/client.js +39 -7
- package/dist/assets/directive-protect/client.js +11 -3
- package/dist/assets/directive-pyide/client.js +20 -9
- package/dist/assets/directive-scratchblock/client.js +9 -0
- package/dist/assets/directive-slideshow/client.js +12 -4
- package/dist/assets/directive-sqlide/client.js +7 -0
- package/dist/assets/directive-sqlide/include/includeIDE.js +22 -11
- package/dist/assets/directive-sqlide/include/sql-ide-embedded.js +30 -30
- package/dist/assets/directive-tabs/client.js +14 -3
- package/dist/assets/directive-textinput/client.js +14 -3
- package/dist/assets/directive-webide/client.js +45 -10
- package/dist/assets/hyperbook.types.js +209 -0
- package/dist/assets/i18n.js +15 -1
- package/dist/assets/store.js +174 -266
- package/dist/assets/ui.js +279 -0
- package/dist/index.js +53 -29
- package/package.json +4 -4
- package/dist/assets/client.js +0 -506
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/// <reference path="./hyperbook.types.js" />
|
|
2
|
+
window.hyperbook = window.hyperbook || {};
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bootstrap script: initializes collapsibles, search, bookmarks,
|
|
6
|
+
* standalone mode, and section filtering on DOMContentLoaded.
|
|
7
|
+
* @type {HyperbookBootstrap}
|
|
8
|
+
* @memberof hyperbook
|
|
9
|
+
* @see hyperbook.store
|
|
10
|
+
*/
|
|
11
|
+
hyperbook.bootstrap = (function () {
|
|
12
|
+
/**
|
|
13
|
+
* Initialize collapsible elements within the given root.
|
|
14
|
+
* @param {HTMLElement} root
|
|
15
|
+
*/
|
|
16
|
+
const initCollapsibles = (root) => {
|
|
17
|
+
const detailsEls = root.querySelectorAll("details.section, details.directive-collapsible");
|
|
18
|
+
for (let details of detailsEls) {
|
|
19
|
+
const id = details.getAttribute("data-id");
|
|
20
|
+
|
|
21
|
+
// Prevent link clicks from toggling the details element in navigation
|
|
22
|
+
if (id && id.startsWith("_nav:") && !details.classList.contains("empty")) {
|
|
23
|
+
const link = details.querySelector("summary a");
|
|
24
|
+
link?.addEventListener("click", (event) => {
|
|
25
|
+
event.stopPropagation();
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Listen for toggle events to persist state and sync with other elements
|
|
30
|
+
details.addEventListener("toggle", () => {
|
|
31
|
+
if (id) {
|
|
32
|
+
if (details.open) {
|
|
33
|
+
hyperbook.store.collapsibles.put({ id });
|
|
34
|
+
} else {
|
|
35
|
+
hyperbook.store.collapsibles.delete(id);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Sync all elements with the same ID
|
|
39
|
+
const allWithSameId = document.querySelectorAll(`[data-id="${id}"]`);
|
|
40
|
+
for (let el of allWithSameId) {
|
|
41
|
+
if (el !== details && el.tagName === "DETAILS") {
|
|
42
|
+
el.open = details.open;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
window.dispatchEvent(new Event("resize"));
|
|
49
|
+
}, 100);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
updateCollapsibles(root);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Restore collapsible open/close state from the store.
|
|
57
|
+
* @param {HTMLElement} root
|
|
58
|
+
*/
|
|
59
|
+
const updateCollapsibles = (root) => {
|
|
60
|
+
hyperbook.store.collapsibles.toArray().then((collapsibles) => {
|
|
61
|
+
const detailsEls = root.querySelectorAll("details.section, details.directive-collapsible");
|
|
62
|
+
for (let details of detailsEls) {
|
|
63
|
+
const id = details.getAttribute("data-id");
|
|
64
|
+
if (id) {
|
|
65
|
+
const shouldBeOpen = collapsibles.some((c) => c.id === id);
|
|
66
|
+
if (!id.startsWith("_nav:") && details.open !== shouldBeOpen) {
|
|
67
|
+
details.open = shouldBeOpen;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Initialize search input Enter key handling.
|
|
76
|
+
* @param {HTMLElement} root
|
|
77
|
+
*/
|
|
78
|
+
const initSearch = (root) => {
|
|
79
|
+
const searchInputEl = root.querySelector("#search-input");
|
|
80
|
+
if (searchInputEl) {
|
|
81
|
+
searchInputEl.addEventListener("keypress", (event) => {
|
|
82
|
+
if (event.key === "Enter") {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
hyperbook.ui.search();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Initialize bookmark active states within the given root.
|
|
92
|
+
* @param {HTMLElement} [root=document]
|
|
93
|
+
*/
|
|
94
|
+
function initBookmarks(root = document) {
|
|
95
|
+
const bookmarkEls = root.getElementsByClassName("bookmark");
|
|
96
|
+
for (let bookmarkEl of bookmarkEls) {
|
|
97
|
+
const key = bookmarkEl.getAttribute("data-key");
|
|
98
|
+
hyperbook.store.bookmarks.get(key).then((bookmark) => {
|
|
99
|
+
if (bookmark) {
|
|
100
|
+
bookmarkEl.classList.add("active");
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Initialize all hyperbook elements within a root.
|
|
108
|
+
* @param {HTMLElement} root
|
|
109
|
+
*/
|
|
110
|
+
function init(root) {
|
|
111
|
+
initCollapsibles(root);
|
|
112
|
+
initSearch(root);
|
|
113
|
+
initBookmarks(root);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Hide TOC toggle button when sections are filtered.
|
|
118
|
+
*/
|
|
119
|
+
function hideTocWhenFiltered() {
|
|
120
|
+
const tocToggle = document.getElementById('toc-toggle');
|
|
121
|
+
if (tocToggle) {
|
|
122
|
+
tocToggle.style.display = 'none';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Filter sections based on the `sections` query parameter.
|
|
128
|
+
*/
|
|
129
|
+
function filterSections() {
|
|
130
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
131
|
+
const sectionsParam = urlParams.get('sections');
|
|
132
|
+
|
|
133
|
+
if (!sectionsParam) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const sectionIds = sectionsParam.split(',').map(id => id.trim()).filter(id => id);
|
|
138
|
+
|
|
139
|
+
if (sectionIds.length === 0) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const allHeadings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
|
144
|
+
const headingsArray = Array.from(allHeadings);
|
|
145
|
+
|
|
146
|
+
const visibleElements = new Set();
|
|
147
|
+
|
|
148
|
+
sectionIds.forEach(sectionId => {
|
|
149
|
+
const heading = document.getElementById(sectionId);
|
|
150
|
+
if (!heading) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const headingLevel = parseInt(heading.tagName.substring(1));
|
|
155
|
+
|
|
156
|
+
visibleElements.add(heading);
|
|
157
|
+
|
|
158
|
+
const headingIndex = headingsArray.indexOf(heading);
|
|
159
|
+
if (headingIndex === -1) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let currentElement = heading.nextElementSibling;
|
|
164
|
+
|
|
165
|
+
while (currentElement) {
|
|
166
|
+
const isHeading = /^H[1-6]$/.test(currentElement.tagName);
|
|
167
|
+
|
|
168
|
+
if (isHeading) {
|
|
169
|
+
const currentLevel = parseInt(currentElement.tagName.substring(1));
|
|
170
|
+
|
|
171
|
+
if (currentLevel <= headingLevel) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
visibleElements.add(currentElement);
|
|
176
|
+
} else {
|
|
177
|
+
visibleElements.add(currentElement);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
currentElement = currentElement.nextElementSibling;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const markdownDiv = document.querySelector('main article .hyperbook-markdown');
|
|
185
|
+
if (markdownDiv) {
|
|
186
|
+
Array.from(markdownDiv.children).forEach(element => {
|
|
187
|
+
const isUIElement = element.id === 'floating-buttons-container' ||
|
|
188
|
+
element.tagName === 'SIDE-DRAWER';
|
|
189
|
+
|
|
190
|
+
if (!visibleElements.has(element) && !isUIElement) {
|
|
191
|
+
element.style.display = 'none';
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
hideTocWhenFiltered();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Check for standalone layout URL parameter or iframe context.
|
|
201
|
+
*/
|
|
202
|
+
function checkStandaloneMode() {
|
|
203
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
204
|
+
const standaloneParam = urlParams.get('standalone') === 'true';
|
|
205
|
+
|
|
206
|
+
const isVSCodeWebview = typeof acquireVsCodeApi !== 'undefined';
|
|
207
|
+
const isInIframe = window.self !== window.top && !isVSCodeWebview;
|
|
208
|
+
|
|
209
|
+
if (standaloneParam || isInIframe) {
|
|
210
|
+
const mainGrid = document.querySelector('.main-grid');
|
|
211
|
+
if (mainGrid && !mainGrid.classList.contains('layout-standalone')) {
|
|
212
|
+
mainGrid.classList.add('layout-standalone');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const tocToggle = document.getElementById('toc-toggle');
|
|
216
|
+
if (tocToggle) {
|
|
217
|
+
tocToggle.style.display = 'none';
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const qrcodeOpen = document.getElementById('qrcode-open');
|
|
221
|
+
if (qrcodeOpen) {
|
|
222
|
+
qrcodeOpen.style.display = 'none';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Initialize on DOMContentLoaded
|
|
228
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
229
|
+
init(document);
|
|
230
|
+
checkStandaloneMode();
|
|
231
|
+
filterSections();
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Observe for new elements added to the DOM
|
|
235
|
+
const observer = new MutationObserver((mutations) => {
|
|
236
|
+
mutations.forEach((mutation) => {
|
|
237
|
+
mutation.addedNodes.forEach((node) => {
|
|
238
|
+
if (node.nodeType === 1) {
|
|
239
|
+
init(node);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
246
|
+
|
|
247
|
+
return { init };
|
|
248
|
+
})();
|