hyperbook 0.84.4 → 0.85.0
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 +28 -17
- 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-embed/client.js +112 -0
- package/dist/assets/directive-embed/style.css +70 -1
- 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/sql-ide-embedded.js +3 -3
- 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/directive-youtube/client.js +99 -0
- package/dist/assets/directive-youtube/style.css +63 -0
- package/dist/assets/hyperbook.types.js +209 -0
- package/dist/assets/i18n.js +15 -1
- package/dist/assets/store.js +174 -139
- package/dist/assets/ui.js +279 -0
- package/dist/index.js +632 -413
- package/dist/locales/de.json +9 -1
- package/dist/locales/en.json +9 -1
- package/package.json +4 -4
- package/dist/assets/client.js +0 -506
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/// <reference path="../hyperbook.types.js" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Web IDE with HTML/CSS/JS editing.
|
|
5
|
+
* @type {HyperbookWebide}
|
|
6
|
+
* @memberof hyperbook
|
|
7
|
+
* @see hyperbook.store
|
|
8
|
+
* @see hyperbook.i18n
|
|
9
|
+
*/
|
|
1
10
|
hyperbook.webide = (function () {
|
|
2
11
|
window.codeInput?.registerTemplate(
|
|
3
12
|
"webide-highlighted",
|
|
@@ -7,9 +16,7 @@ hyperbook.webide = (function () {
|
|
|
7
16
|
]),
|
|
8
17
|
);
|
|
9
18
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
for (let elem of elems) {
|
|
19
|
+
function initElement(elem) {
|
|
13
20
|
const title = elem.getElementsByClassName("container-title")[0];
|
|
14
21
|
/** @type {HTMLTextAreaElement | null} */
|
|
15
22
|
const editorHTML = elem.querySelector(".editor.html");
|
|
@@ -33,8 +40,8 @@ hyperbook.webide = (function () {
|
|
|
33
40
|
const downloadEl = elem.querySelector("button.download");
|
|
34
41
|
|
|
35
42
|
resetEl?.addEventListener("click", () => {
|
|
36
|
-
if (window.confirm(i18n.get("webide-reset-prompt"))) {
|
|
37
|
-
store.webide.delete(id);
|
|
43
|
+
if (window.confirm(hyperbook.i18n.get("webide-reset-prompt"))) {
|
|
44
|
+
hyperbook.store.webide.delete(id);
|
|
38
45
|
window.location.reload();
|
|
39
46
|
}
|
|
40
47
|
});
|
|
@@ -70,7 +77,7 @@ hyperbook.webide = (function () {
|
|
|
70
77
|
});
|
|
71
78
|
|
|
72
79
|
const load = async () => {
|
|
73
|
-
const result = await store.webide.get(id);
|
|
80
|
+
const result = await hyperbook.store.webide.get(id);
|
|
74
81
|
if (!result) {
|
|
75
82
|
return;
|
|
76
83
|
}
|
|
@@ -84,7 +91,7 @@ hyperbook.webide = (function () {
|
|
|
84
91
|
load();
|
|
85
92
|
|
|
86
93
|
const update = () => {
|
|
87
|
-
store.webide.put({
|
|
94
|
+
hyperbook.store.webide.put({
|
|
88
95
|
id,
|
|
89
96
|
html: editorHTML?.value,
|
|
90
97
|
css: editorCSS?.value,
|
|
@@ -102,7 +109,7 @@ hyperbook.webide = (function () {
|
|
|
102
109
|
});
|
|
103
110
|
|
|
104
111
|
editorHTML?.addEventListener("code-input_load", async () => {
|
|
105
|
-
const result = await store.webide.get(id);
|
|
112
|
+
const result = await hyperbook.store.webide.get(id);
|
|
106
113
|
if (result) {
|
|
107
114
|
editorHTML.value = result.html;
|
|
108
115
|
}
|
|
@@ -115,7 +122,7 @@ hyperbook.webide = (function () {
|
|
|
115
122
|
});
|
|
116
123
|
|
|
117
124
|
editorCSS?.addEventListener("code-input_load", async () => {
|
|
118
|
-
const result = await store.webide.get(id);
|
|
125
|
+
const result = await hyperbook.store.webide.get(id);
|
|
119
126
|
if (result) {
|
|
120
127
|
editorCSS.value = result.css;
|
|
121
128
|
}
|
|
@@ -128,7 +135,7 @@ hyperbook.webide = (function () {
|
|
|
128
135
|
});
|
|
129
136
|
|
|
130
137
|
editorJS?.addEventListener("code-input_load", async () => {
|
|
131
|
-
const result = await store.webide.get(id);
|
|
138
|
+
const result = await hyperbook.store.webide.get(id);
|
|
132
139
|
if (result) {
|
|
133
140
|
editorJS.value = result.js;
|
|
134
141
|
}
|
|
@@ -149,4 +156,32 @@ hyperbook.webide = (function () {
|
|
|
149
156
|
a.click();
|
|
150
157
|
});
|
|
151
158
|
}
|
|
159
|
+
|
|
160
|
+
function init(root) {
|
|
161
|
+
const elems = root.querySelectorAll(".directive-webide");
|
|
162
|
+
elems.forEach(initElement);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Initialize existing elements on document load
|
|
166
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
167
|
+
init(document);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Observe for new elements added to the DOM
|
|
171
|
+
const observer = new MutationObserver((mutations) => {
|
|
172
|
+
mutations.forEach((mutation) => {
|
|
173
|
+
mutation.addedNodes.forEach((node) => {
|
|
174
|
+
if (
|
|
175
|
+
node.nodeType === 1 &&
|
|
176
|
+
node.classList.contains("directive-webide")
|
|
177
|
+
) {
|
|
178
|
+
initElement(node);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
185
|
+
|
|
186
|
+
return { init };
|
|
152
187
|
})();
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/// <reference path="../hyperbook.types.js" />
|
|
2
|
+
window.hyperbook = window.hyperbook || {};
|
|
3
|
+
|
|
4
|
+
hyperbook.youtube = hyperbook.youtube || {};
|
|
5
|
+
|
|
6
|
+
hyperbook.youtube.consent = (function () {
|
|
7
|
+
var CONSENT_ID = "youtube";
|
|
8
|
+
|
|
9
|
+
async function isAllowed() {
|
|
10
|
+
try {
|
|
11
|
+
var entry = await hyperbook.store.consent.get(CONSENT_ID);
|
|
12
|
+
return entry?.allowed === true;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function allow() {
|
|
19
|
+
await hyperbook.store.consent.put({ id: CONSENT_ID, allowed: true });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function loadContent(wrapper) {
|
|
23
|
+
var banner = wrapper.querySelector(".directive-youtube-consent-banner");
|
|
24
|
+
if (banner) {
|
|
25
|
+
banner.remove();
|
|
26
|
+
}
|
|
27
|
+
var iframe = wrapper.querySelector("iframe");
|
|
28
|
+
if (iframe) {
|
|
29
|
+
var src = iframe.getAttribute("data-consent-src");
|
|
30
|
+
if (src) {
|
|
31
|
+
iframe.setAttribute("src", src);
|
|
32
|
+
iframe.removeAttribute("data-consent-src");
|
|
33
|
+
iframe.style.display = "";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function initWrapper(wrapper) {
|
|
39
|
+
if (wrapper.getAttribute("data-consent-initialized")) return;
|
|
40
|
+
wrapper.setAttribute("data-consent-initialized", "true");
|
|
41
|
+
|
|
42
|
+
var allowed = await isAllowed();
|
|
43
|
+
if (allowed) {
|
|
44
|
+
loadContent(wrapper);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var btn = wrapper.querySelector(".directive-youtube-consent-accept-btn");
|
|
49
|
+
var checkbox = wrapper.querySelector(
|
|
50
|
+
".directive-youtube-consent-always-checkbox"
|
|
51
|
+
);
|
|
52
|
+
if (btn) {
|
|
53
|
+
btn.addEventListener("click", async function () {
|
|
54
|
+
if (checkbox && checkbox.checked) {
|
|
55
|
+
await allow();
|
|
56
|
+
}
|
|
57
|
+
loadContent(wrapper);
|
|
58
|
+
if (checkbox && checkbox.checked) {
|
|
59
|
+
document
|
|
60
|
+
.querySelectorAll(".directive-youtube-consent")
|
|
61
|
+
.forEach(function (el) {
|
|
62
|
+
loadContent(el);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function init(root) {
|
|
70
|
+
var wrappers = root.querySelectorAll
|
|
71
|
+
? root.querySelectorAll(".directive-youtube-consent")
|
|
72
|
+
: [];
|
|
73
|
+
wrappers.forEach(function (w) {
|
|
74
|
+
initWrapper(w);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
79
|
+
init(document);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
var observer = new MutationObserver(function (mutations) {
|
|
83
|
+
mutations.forEach(function (mutation) {
|
|
84
|
+
mutation.addedNodes.forEach(function (node) {
|
|
85
|
+
if (node.nodeType === 1) {
|
|
86
|
+
init(node);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
isAllowed: isAllowed,
|
|
96
|
+
allow: allow,
|
|
97
|
+
init: init,
|
|
98
|
+
};
|
|
99
|
+
})();
|
|
@@ -14,3 +14,66 @@
|
|
|
14
14
|
height: 100%;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
.directive-youtube-consent {
|
|
18
|
+
position: absolute;
|
|
19
|
+
top: 0;
|
|
20
|
+
left: 0;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 100%;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.directive-youtube-consent iframe[data-consent-src] {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.directive-youtube-consent-banner {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
gap: 12px;
|
|
35
|
+
padding: 24px;
|
|
36
|
+
background-color: var(--color-background-tinted, #f5f5f5);
|
|
37
|
+
border: 2px solid var(--color-brand, #333);
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
text-align: center;
|
|
40
|
+
height: 100%;
|
|
41
|
+
box-sizing: border-box;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.directive-youtube-consent-banner-text {
|
|
45
|
+
font-size: 0.95em;
|
|
46
|
+
line-height: 1.5;
|
|
47
|
+
color: var(--color-text, #333);
|
|
48
|
+
max-width: 600px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.directive-youtube-consent-always-label {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: 6px;
|
|
55
|
+
font-size: 0.85em;
|
|
56
|
+
color: var(--color-text, #333);
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.directive-youtube-consent-always-checkbox {
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
margin: 0!important;
|
|
63
|
+
vertical-align: middle;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.directive-youtube-consent-accept-btn {
|
|
67
|
+
padding: 8px 24px;
|
|
68
|
+
background-color: var(--color-brand, #333);
|
|
69
|
+
color: var(--color-brand-text, #fff);
|
|
70
|
+
border: none;
|
|
71
|
+
border-radius: 4px;
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
font-size: 0.95em;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.directive-youtube-consent-accept-btn:hover {
|
|
77
|
+
opacity: 0.9;
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Type definitions for the hyperbook global namespace.
|
|
3
|
+
* This file is NOT loaded in the browser. It exists solely for IDE support
|
|
4
|
+
* and JSDoc cross-referencing between scripts.
|
|
5
|
+
*
|
|
6
|
+
* Usage: Add the following to the top of any script that references
|
|
7
|
+
* other hyperbook modules:
|
|
8
|
+
* /// <reference path="../hyperbook.types.js" />
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @namespace hyperbook
|
|
13
|
+
* @description Global namespace for all hyperbook client-side modules.
|
|
14
|
+
* Initialized by i18n.js (first script to load) with
|
|
15
|
+
* `window.hyperbook = window.hyperbook || {}`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {Object} HyperbookI18n
|
|
20
|
+
* @property {(key: string, values?: Record<string, string>) => string} get
|
|
21
|
+
* Returns the translated string for the given key, substituting `{{placeholder}}`
|
|
22
|
+
* patterns with values from the `values` object. Falls back to the key itself
|
|
23
|
+
* if no translation is found.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {Object} HyperbookStore
|
|
28
|
+
* @property {import("dexie").Dexie} db - The underlying Dexie database instance.
|
|
29
|
+
* @property {import("dexie").Table} currentState - Ephemeral UI state (mouse, scroll, window size).
|
|
30
|
+
* @property {import("dexie").Table} collapsibles - Persisted open/close state for collapsible elements.
|
|
31
|
+
* @property {import("dexie").Table} abcMusic - ABC music editor tunes.
|
|
32
|
+
* @property {import("dexie").Table} audio - Audio playback positions.
|
|
33
|
+
* @property {import("dexie").Table} bookmarks - User bookmarks (path + label).
|
|
34
|
+
* @property {import("dexie").Table} p5 - p5.js sketches.
|
|
35
|
+
* @property {import("dexie").Table} protect - Password hashes for protected content.
|
|
36
|
+
* @property {import("dexie").Table} pyide - Python IDE scripts.
|
|
37
|
+
* @property {import("dexie").Table} slideshow - Active slide indices.
|
|
38
|
+
* @property {import("dexie").Table} tabs - Active tab selections.
|
|
39
|
+
* @property {import("dexie").Table} excalidraw - Excalidraw drawing state.
|
|
40
|
+
* @property {import("dexie").Table} webide - Web IDE editor contents (HTML/CSS/JS).
|
|
41
|
+
* @property {import("dexie").Table} h5p - H5P user data.
|
|
42
|
+
* @property {import("dexie").Table} geogebra - GeoGebra applet state.
|
|
43
|
+
* @property {import("dexie").Table} learningmap - Learning map node positions and zoom.
|
|
44
|
+
* @property {import("dexie").Table} textinput - Text input field values.
|
|
45
|
+
* @property {import("dexie").Table} custom - Custom directive payload storage.
|
|
46
|
+
* @property {import("dexie").Table} onlineide - Online IDE scripts.
|
|
47
|
+
* @property {import("dexie").Table} sqlideScripts - SQL IDE scripts.
|
|
48
|
+
* @property {import("dexie").Table} sqlideDatabases - SQL IDE databases.
|
|
49
|
+
* @property {import("dexie").Table} multievent - Multi-event state.
|
|
50
|
+
* @property {import("dexie").Table} typst - Typst editor code.
|
|
51
|
+
* @property {() => Promise<void>} export - Export all store data as a JSON download.
|
|
52
|
+
* @property {() => Promise<void>} reset - Clear all store data after user confirmation.
|
|
53
|
+
* @property {() => Promise<void>} import - Import store data from a JSON file.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @typedef {Object} HyperbookCloud
|
|
58
|
+
* @property {() => Promise<void>} save - Manually trigger a save to the cloud.
|
|
59
|
+
* @property {() => Promise<void>} sendSnapshot - Send a full snapshot to the cloud.
|
|
60
|
+
* @property {() => void} userToggle - Toggle the user login/info drawer.
|
|
61
|
+
* @property {() => Promise<void>} login - Log in with username and password from the form.
|
|
62
|
+
* @property {() => void} logout - Log out and clear auth state.
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @typedef {Object} HyperbookAbc
|
|
67
|
+
* @property {(root: HTMLElement) => void} init - Initialize ABC music elements.
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @typedef {Object} HyperbookArchive
|
|
72
|
+
* @property {() => void} init - Initialize archive download status indicators.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @typedef {Object} HyperbookAudio
|
|
77
|
+
* @property {(id: string) => void} togglePlayPause - Toggle play/pause for an audio element.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @typedef {Object} HyperbookBookmarks
|
|
82
|
+
* @property {(root?: Document) => void} update - Refresh the bookmarks list in the DOM.
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @typedef {Object} HyperbookDownload
|
|
87
|
+
* @property {(root: HTMLElement) => void} init - Initialize download status indicators.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @typedef {Object} HyperbookExcalidraw
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @typedef {Object} HyperbookGeogebra
|
|
96
|
+
* @property {(root: HTMLElement) => void} init - Initialize GeoGebra applets.
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @typedef {Object} HyperbookH5p
|
|
101
|
+
* @property {(root: HTMLElement) => Promise<void>} init - Initialize H5P elements.
|
|
102
|
+
* @property {(id: string) => void} save - Save H5P user data for an element.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @typedef {Object} HyperbookLearningmap
|
|
107
|
+
* @property {(root: HTMLElement) => void} init - Initialize learning map elements.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @typedef {Object} HyperbookMermaid
|
|
112
|
+
* @property {() => void} init - Initialize mermaid diagrams.
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @typedef {Object} HyperbookOnlineide
|
|
117
|
+
* @property {(el: HTMLElement) => void} openFullscreen - Open the online IDE in fullscreen.
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @typedef {Object} HyperbookP5
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @typedef {Object} HyperbookProtect
|
|
126
|
+
* @property {(root: HTMLElement) => void} init - Initialize protected content elements.
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @typedef {Object} HyperbookPython
|
|
131
|
+
* @property {(root: HTMLElement) => void} init - Initialize Python IDE elements.
|
|
132
|
+
*/
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @typedef {Object} HyperbookScratchblock
|
|
136
|
+
* @property {() => void} init - Render all scratch blocks on the page.
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @typedef {Object} HyperbookSlideshow
|
|
141
|
+
* @property {(id: string) => void} update - Update slideshow state from store.
|
|
142
|
+
* @property {(id: string, steps: number) => void} moveBy - Move the slideshow by a number of steps.
|
|
143
|
+
* @property {(id: string, index: number) => void} setActive - Set the active slide by index.
|
|
144
|
+
* @property {(root: HTMLElement) => void} init - Initialize slideshows within a root element.
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @typedef {Object} HyperbookSqlide
|
|
149
|
+
* @property {(el: HTMLElement) => void} openFullscreen - Open the SQL IDE in fullscreen.
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @typedef {Object} HyperbookTabs
|
|
154
|
+
* @property {(tabsId: string, tabId: string) => void} selectTab - Select a tab by ID.
|
|
155
|
+
* @property {(root: HTMLElement) => void} init - Initialize tab elements.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @typedef {Object} HyperbookTextinput
|
|
160
|
+
* @property {(root: HTMLElement) => void} init - Initialize text input elements.
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @typedef {Object} HyperbookWebide
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Global hyperbook namespace available on `window.hyperbook`.
|
|
169
|
+
*
|
|
170
|
+
* @type {{
|
|
171
|
+
* i18n: HyperbookI18n,
|
|
172
|
+
* store: HyperbookStore,
|
|
173
|
+
* cloud?: HyperbookCloud,
|
|
174
|
+
* toggleLightbox: (el: HTMLElement) => void,
|
|
175
|
+
* toggleBookmark: (key: string, label: string) => void,
|
|
176
|
+
* navToggle: () => void,
|
|
177
|
+
* tocToggle: () => void,
|
|
178
|
+
* searchToggle: () => void,
|
|
179
|
+
* search: () => void,
|
|
180
|
+
* qrcodeOpen: () => void,
|
|
181
|
+
* qrcodeClose: () => void,
|
|
182
|
+
* shareOpen: () => void,
|
|
183
|
+
* shareClose: () => void,
|
|
184
|
+
* shareUpdatePreview: () => void,
|
|
185
|
+
* shareCopyUrl: () => void,
|
|
186
|
+
* init: (root: HTMLElement) => void,
|
|
187
|
+
* abc?: HyperbookAbc,
|
|
188
|
+
* archive?: HyperbookArchive,
|
|
189
|
+
* audio?: HyperbookAudio,
|
|
190
|
+
* bookmarks?: HyperbookBookmarks,
|
|
191
|
+
* download?: HyperbookDownload,
|
|
192
|
+
* excalidraw?: HyperbookExcalidraw,
|
|
193
|
+
* geogebra?: HyperbookGeogebra,
|
|
194
|
+
* h5p?: HyperbookH5p,
|
|
195
|
+
* learningmap?: HyperbookLearningmap,
|
|
196
|
+
* mermaid?: HyperbookMermaid,
|
|
197
|
+
* onlineide?: HyperbookOnlineide,
|
|
198
|
+
* p5?: HyperbookP5,
|
|
199
|
+
* protect?: HyperbookProtect,
|
|
200
|
+
* python?: HyperbookPython,
|
|
201
|
+
* scratchblock?: HyperbookScratchblock,
|
|
202
|
+
* slideshow?: HyperbookSlideshow,
|
|
203
|
+
* sqlide?: HyperbookSqlide,
|
|
204
|
+
* tabs?: HyperbookTabs,
|
|
205
|
+
* textinput?: HyperbookTextinput,
|
|
206
|
+
* webide?: HyperbookWebide,
|
|
207
|
+
* }}
|
|
208
|
+
*/
|
|
209
|
+
var hyperbook;
|
package/dist/assets/i18n.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference path="./hyperbook.types.js" />
|
|
2
|
+
window.hyperbook = window.hyperbook || {};
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Internationalization module providing translation lookups.
|
|
6
|
+
* @type {HyperbookI18n}
|
|
7
|
+
* @memberof hyperbook
|
|
8
|
+
*/
|
|
9
|
+
hyperbook.i18n = (function () {
|
|
2
10
|
// LOCALES
|
|
3
11
|
const locales = {};
|
|
4
12
|
// LOCALES
|
|
5
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Get a translated string by key, with optional placeholder substitution.
|
|
16
|
+
* @param {string} key - The translation key.
|
|
17
|
+
* @param {Record<string, string>} [values] - Placeholder values to substitute.
|
|
18
|
+
* @returns {string} The translated string, or the key itself if not found.
|
|
19
|
+
*/
|
|
6
20
|
const get = (key, values) => {
|
|
7
21
|
if (!locales[key]) {
|
|
8
22
|
console.warn(
|