hyperbook 0.94.0 → 0.95.1
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/codemirror/codemirror.bundle.js +26 -0
- package/dist/assets/directive-abc-music/client.js +42 -42
- package/dist/assets/directive-abc-music/style.css +6 -0
- package/dist/assets/directive-openscad/client.js +350 -219
- package/dist/assets/directive-openscad/style.css +59 -4
- package/dist/assets/directive-openscad/worker.js +310 -0
- package/dist/assets/directive-p5/client.js +27 -26
- package/dist/assets/directive-p5/style.css +12 -6
- package/dist/assets/directive-pyide/client.js +37 -40
- package/dist/assets/directive-pyide/style.css +12 -6
- package/dist/assets/directive-typst/client.js +20 -55
- package/dist/assets/directive-typst/style.css +12 -6
- package/dist/assets/directive-webide/client.js +45 -79
- package/dist/assets/directive-webide/style.css +12 -6
- package/dist/index.js +37 -71
- package/dist/locales/de.json +1 -0
- package/dist/locales/en.json +1 -0
- package/package.json +4 -4
- package/dist/assets/code-input/auto-close-brackets.min.js +0 -1
- package/dist/assets/code-input/code-input.min.css +0 -1
- package/dist/assets/code-input/code-input.min.js +0 -12
- package/dist/assets/code-input/indent.min.js +0 -1
|
@@ -8,14 +8,6 @@
|
|
|
8
8
|
* @see hyperbook.i18n
|
|
9
9
|
*/
|
|
10
10
|
hyperbook.python = (function () {
|
|
11
|
-
window.codeInput?.registerTemplate(
|
|
12
|
-
"pyide-highlighted",
|
|
13
|
-
codeInput.templates.prism(window.Prism, [
|
|
14
|
-
new codeInput.plugins.AutoCloseBrackets(),
|
|
15
|
-
new codeInput.plugins.Indent(true, 2),
|
|
16
|
-
])
|
|
17
|
-
);
|
|
18
|
-
|
|
19
11
|
const PYODIDE_CDN = "https://cdn.jsdelivr.net/pyodide/v0.29.4/full/pyodide.js";
|
|
20
12
|
|
|
21
13
|
const loadPyodideScript = () => {
|
|
@@ -1784,22 +1776,31 @@ hyperbook.python = (function () {
|
|
|
1784
1776
|
}
|
|
1785
1777
|
}
|
|
1786
1778
|
|
|
1779
|
+
let lastStdinPrompt = "";
|
|
1780
|
+
pyodide.setStdout({
|
|
1781
|
+
write: (msg) => {
|
|
1782
|
+
const text = typeof msg === "string" ? msg : decoder.decode(msg);
|
|
1783
|
+
if (text.endsWith("\n")) {
|
|
1784
|
+
lastStdinPrompt = "";
|
|
1785
|
+
} else {
|
|
1786
|
+
lastStdinPrompt += text;
|
|
1787
|
+
}
|
|
1788
|
+
appendOutputLine(id, text);
|
|
1789
|
+
return msg?.length ?? text.length;
|
|
1790
|
+
},
|
|
1791
|
+
});
|
|
1787
1792
|
pyodide.setStdin({
|
|
1788
1793
|
stdin: () => {
|
|
1789
|
-
const
|
|
1794
|
+
const promptText =
|
|
1795
|
+
lastStdinPrompt || hyperbook.i18n.get("pyide-input-prompt");
|
|
1796
|
+
lastStdinPrompt = "";
|
|
1797
|
+
const value = window.prompt(promptText);
|
|
1790
1798
|
if (value === null) {
|
|
1791
1799
|
return "";
|
|
1792
1800
|
}
|
|
1793
1801
|
return value;
|
|
1794
1802
|
},
|
|
1795
1803
|
});
|
|
1796
|
-
pyodide.setStdout({
|
|
1797
|
-
write: (msg) => {
|
|
1798
|
-
const text = typeof msg === "string" ? msg : decoder.decode(msg);
|
|
1799
|
-
appendOutputLine(id, text);
|
|
1800
|
-
return msg?.length ?? text.length;
|
|
1801
|
-
},
|
|
1802
|
-
});
|
|
1803
1804
|
pyodide.setStderr({
|
|
1804
1805
|
write: (msg) => {
|
|
1805
1806
|
const text = typeof msg === "string" ? msg : decoder.decode(msg);
|
|
@@ -1899,7 +1900,7 @@ if _pg:
|
|
|
1899
1900
|
const test = elem.getElementsByClassName("test")[0];
|
|
1900
1901
|
const stop = elem.getElementsByClassName("stop")[0];
|
|
1901
1902
|
const editor = elem.getElementsByClassName("editor")[0];
|
|
1902
|
-
const
|
|
1903
|
+
const editorCm = editor?._cm;
|
|
1903
1904
|
const state = getExecutionState(elem.id);
|
|
1904
1905
|
const hasRuntime = runtimes.has(elem.id);
|
|
1905
1906
|
const hasInterrupt = interruptBuffers.has(elem.id);
|
|
@@ -1917,11 +1918,8 @@ if _pg:
|
|
|
1917
1918
|
elem.classList.toggle("locked-by-other", lockedByOther);
|
|
1918
1919
|
|
|
1919
1920
|
if (state.running || lockedByOther) {
|
|
1920
|
-
editor?.setAttribute("disabled", "");
|
|
1921
1921
|
editor?.classList.add("running");
|
|
1922
|
-
|
|
1923
|
-
editorTextarea.readOnly = true;
|
|
1924
|
-
}
|
|
1922
|
+
editorCm?.setReadOnly(true);
|
|
1925
1923
|
if (state.running && state.type === "run") {
|
|
1926
1924
|
run.textContent = hyperbook.i18n.get("pyide-running");
|
|
1927
1925
|
run.disabled = true;
|
|
@@ -1969,11 +1967,8 @@ if _pg:
|
|
|
1969
1967
|
stop.classList.toggle("stopping", state.stopping);
|
|
1970
1968
|
}
|
|
1971
1969
|
} else {
|
|
1972
|
-
editor?.removeAttribute("disabled");
|
|
1973
1970
|
editor?.classList.remove("running");
|
|
1974
|
-
|
|
1975
|
-
editorTextarea.readOnly = false;
|
|
1976
|
-
}
|
|
1971
|
+
editorCm?.setReadOnly(false);
|
|
1977
1972
|
run.classList.remove("stopping");
|
|
1978
1973
|
run.classList.remove("running");
|
|
1979
1974
|
run.textContent = hyperbook.i18n.get("pyide-run");
|
|
@@ -2162,7 +2157,7 @@ if _pg:
|
|
|
2162
2157
|
if (elem.getAttribute("data-pyide-initialized") === "true") continue;
|
|
2163
2158
|
elem.setAttribute("data-pyide-initialized", "true");
|
|
2164
2159
|
|
|
2165
|
-
const
|
|
2160
|
+
const editorDiv = elem.getElementsByClassName("editor")[0];
|
|
2166
2161
|
const container = elem.getElementsByClassName("container")[0];
|
|
2167
2162
|
const editorContainer = elem.getElementsByClassName("editor-container")[0];
|
|
2168
2163
|
const splitter = elem.getElementsByClassName("splitter")[0];
|
|
@@ -2202,11 +2197,20 @@ if _pg:
|
|
|
2202
2197
|
};
|
|
2203
2198
|
let pyideState = { id };
|
|
2204
2199
|
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2200
|
+
// Initialize CodeMirror
|
|
2201
|
+
const initialSource = editorDiv ? editorDiv.textContent : "";
|
|
2202
|
+
if (editorDiv) editorDiv.textContent = "";
|
|
2203
|
+
const cm = editorDiv ? HyperbookCM.create(editorDiv, {
|
|
2204
|
+
lang: editorDiv.dataset.lang || "python",
|
|
2205
|
+
value: initialSource,
|
|
2206
|
+
onChange: (code) => {
|
|
2207
|
+
void persistPyideState({ script: code });
|
|
2208
|
+
},
|
|
2209
|
+
}) : null;
|
|
2210
|
+
// Store CM on the element so updateRunning() can toggle readOnly
|
|
2211
|
+
if (editorDiv && cm) editorDiv._cm = cm;
|
|
2212
|
+
|
|
2213
|
+
const getEditorValue = () => cm?.getValue() ?? "";
|
|
2210
2214
|
|
|
2211
2215
|
pyideState = { ...pyideState, script: getEditorValue() };
|
|
2212
2216
|
|
|
@@ -2359,7 +2363,7 @@ if _pg:
|
|
|
2359
2363
|
if (result) {
|
|
2360
2364
|
pyideState = { ...pyideState, ...result };
|
|
2361
2365
|
if (typeof result.script === "string") {
|
|
2362
|
-
|
|
2366
|
+
cm?.setValue(result.script);
|
|
2363
2367
|
}
|
|
2364
2368
|
if (
|
|
2365
2369
|
Number.isFinite(result.splitHorizontal) &&
|
|
@@ -2386,10 +2390,7 @@ if _pg:
|
|
|
2386
2390
|
}
|
|
2387
2391
|
};
|
|
2388
2392
|
|
|
2389
|
-
|
|
2390
|
-
if (editor.querySelector("textarea")) {
|
|
2391
|
-
void restoreEditorState();
|
|
2392
|
-
}
|
|
2393
|
+
void restoreEditorState();
|
|
2393
2394
|
|
|
2394
2395
|
window.addEventListener("resize", () => {
|
|
2395
2396
|
applyCanvasOutputLayout();
|
|
@@ -2397,10 +2398,6 @@ if _pg:
|
|
|
2397
2398
|
});
|
|
2398
2399
|
applyCanvasOutputLayout();
|
|
2399
2400
|
|
|
2400
|
-
editor.addEventListener("input", () => {
|
|
2401
|
-
void persistPyideState({ script: getEditorValue() });
|
|
2402
|
-
});
|
|
2403
|
-
|
|
2404
2401
|
test?.addEventListener("click", async () => {
|
|
2405
2402
|
showOutput();
|
|
2406
2403
|
const state = getExecutionState(id);
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
margin: 0;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
.directive-pyide .editor {
|
|
16
|
+
width: 100%;
|
|
17
|
+
border: 1px solid var(--color-spacer);
|
|
18
|
+
flex: 1;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.directive-pyide .editor .cm-editor {
|
|
24
|
+
height: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
.directive-pyide .container {
|
|
16
28
|
width: 100%;
|
|
17
29
|
overflow: hidden;
|
|
@@ -135,12 +147,6 @@
|
|
|
135
147
|
opacity: 0.75;
|
|
136
148
|
}
|
|
137
149
|
|
|
138
|
-
.directive-pyide .editor {
|
|
139
|
-
width: 100%;
|
|
140
|
-
border: 1px solid var(--color-spacer);
|
|
141
|
-
flex: 1;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
150
|
.directive-pyide .editor.running {
|
|
145
151
|
pointer-events: none;
|
|
146
152
|
opacity: 0.7;
|
|
@@ -88,21 +88,6 @@ hyperbook.typst = (function () {
|
|
|
88
88
|
// INITIALIZATION
|
|
89
89
|
// ============================================================================
|
|
90
90
|
|
|
91
|
-
/**
|
|
92
|
-
* Initialize code-input template for Typst syntax highlighting
|
|
93
|
-
*/
|
|
94
|
-
const initializeCodeInput = () => {
|
|
95
|
-
if (!window.codeInput) return;
|
|
96
|
-
|
|
97
|
-
window.codeInput.registerTemplate(
|
|
98
|
-
"typst-highlighted",
|
|
99
|
-
window.codeInput.templates.prism(window.Prism, [
|
|
100
|
-
new window.codeInput.plugins.AutoCloseBrackets(),
|
|
101
|
-
new window.codeInput.plugins.Indent(true, 2),
|
|
102
|
-
])
|
|
103
|
-
);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
91
|
// ============================================================================
|
|
107
92
|
// TYPST LOADER
|
|
108
93
|
// ============================================================================
|
|
@@ -1269,6 +1254,7 @@ hyperbook.typst = (function () {
|
|
|
1269
1254
|
this.sourceTextarea = elem.querySelector('.typst-source');
|
|
1270
1255
|
this.fullscreenBtn = elem.querySelector('.fullscreen');
|
|
1271
1256
|
this.editorInitialized = false;
|
|
1257
|
+
this.cm = null;
|
|
1272
1258
|
|
|
1273
1259
|
setupSplitter(this.elem, this.previewContainer, this.editorContainer, this.splitter);
|
|
1274
1260
|
|
|
@@ -1320,28 +1306,26 @@ hyperbook.typst = (function () {
|
|
|
1320
1306
|
*/
|
|
1321
1307
|
async initialize() {
|
|
1322
1308
|
if (this.editor) {
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
this.editor.addEventListener('input', () => {
|
|
1309
|
+
if (this.editorInitialized) return;
|
|
1310
|
+
this.editorInitialized = true;
|
|
1311
|
+
|
|
1312
|
+
// Create CodeMirror editor
|
|
1313
|
+
const initialSource = this.editor.textContent;
|
|
1314
|
+
this.editor.textContent = "";
|
|
1315
|
+
const debouncedRerender = debounce(() => this.rerender(), CONFIG.DEBOUNCE_DELAY);
|
|
1316
|
+
this.cm = HyperbookCM.create(this.editor, {
|
|
1317
|
+
lang: "typst",
|
|
1318
|
+
value: initialSource,
|
|
1319
|
+
onChange: () => {
|
|
1335
1320
|
this.saveState();
|
|
1336
1321
|
debouncedRerender();
|
|
1337
|
-
}
|
|
1338
|
-
};
|
|
1322
|
+
},
|
|
1323
|
+
});
|
|
1339
1324
|
|
|
1340
|
-
|
|
1341
|
-
this.
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
}
|
|
1325
|
+
await this.restoreState();
|
|
1326
|
+
this.uiManager.updateTabs();
|
|
1327
|
+
this.uiManager.updateBinaryFilesList();
|
|
1328
|
+
this.rerender();
|
|
1345
1329
|
} else if (this.sourceTextarea) {
|
|
1346
1330
|
// Preview mode
|
|
1347
1331
|
const initialCode = this.sourceTextarea.value;
|
|
@@ -1606,28 +1590,12 @@ hyperbook.typst = (function () {
|
|
|
1606
1590
|
|
|
1607
1591
|
getEditorValue() {
|
|
1608
1592
|
if (!this.editor) return '';
|
|
1609
|
-
|
|
1610
|
-
if (textarea) return textarea.value;
|
|
1611
|
-
try {
|
|
1612
|
-
if (typeof this.editor.value === 'string') {
|
|
1613
|
-
return this.editor.value;
|
|
1614
|
-
}
|
|
1615
|
-
} catch (e) {}
|
|
1616
|
-
return this.editor.textContent || '';
|
|
1593
|
+
return this.cm?.getValue() ?? '';
|
|
1617
1594
|
}
|
|
1618
1595
|
|
|
1619
1596
|
setEditorValue(value) {
|
|
1620
1597
|
if (!this.editor) return;
|
|
1621
|
-
|
|
1622
|
-
const textarea = this.editor.querySelector('textarea');
|
|
1623
|
-
if (textarea) {
|
|
1624
|
-
textarea.value = normalizedValue;
|
|
1625
|
-
}
|
|
1626
|
-
try {
|
|
1627
|
-
this.editor.value = normalizedValue;
|
|
1628
|
-
} catch (e) {
|
|
1629
|
-
this.editor.textContent = normalizedValue;
|
|
1630
|
-
}
|
|
1598
|
+
this.cm?.setValue(value ?? '');
|
|
1631
1599
|
}
|
|
1632
1600
|
}
|
|
1633
1601
|
|
|
@@ -1635,9 +1603,6 @@ hyperbook.typst = (function () {
|
|
|
1635
1603
|
// MAIN INITIALIZATION
|
|
1636
1604
|
// ============================================================================
|
|
1637
1605
|
|
|
1638
|
-
// Initialize code-input
|
|
1639
|
-
initializeCodeInput();
|
|
1640
|
-
|
|
1641
1606
|
// Get all Typst directive elements
|
|
1642
1607
|
const elements = document.getElementsByClassName('directive-typst');
|
|
1643
1608
|
|
|
@@ -12,6 +12,18 @@ code-input {
|
|
|
12
12
|
margin: 0;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
.directive-typst .editor {
|
|
16
|
+
width: 100%;
|
|
17
|
+
border: 1px solid var(--color-spacer);
|
|
18
|
+
flex: 1;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.directive-typst .editor .cm-editor {
|
|
24
|
+
height: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
.directive-typst .preview-container {
|
|
16
28
|
width: 100%;
|
|
17
29
|
min-height: 120px;
|
|
@@ -419,12 +431,6 @@ code-input {
|
|
|
419
431
|
color: #dc2626;
|
|
420
432
|
}
|
|
421
433
|
|
|
422
|
-
.directive-typst .editor {
|
|
423
|
-
width: 100%;
|
|
424
|
-
border: 1px solid var(--color-spacer);
|
|
425
|
-
flex: 1;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
434
|
.directive-typst .editor:not(.active) {
|
|
429
435
|
display: none;
|
|
430
436
|
}
|
|
@@ -8,14 +8,6 @@
|
|
|
8
8
|
* @see hyperbook.i18n
|
|
9
9
|
*/
|
|
10
10
|
hyperbook.webide = (function () {
|
|
11
|
-
window.codeInput?.registerTemplate(
|
|
12
|
-
"webide-highlighted",
|
|
13
|
-
codeInput.templates.prism(window.Prism, [
|
|
14
|
-
new codeInput.plugins.AutoCloseBrackets(),
|
|
15
|
-
new codeInput.plugins.Indent(true, 2),
|
|
16
|
-
]),
|
|
17
|
-
);
|
|
18
|
-
|
|
19
11
|
function setupSplitter(elem, container, editorContainer, splitter) {
|
|
20
12
|
if (!container || !editorContainer || !splitter) return;
|
|
21
13
|
|
|
@@ -118,12 +110,9 @@ hyperbook.webide = (function () {
|
|
|
118
110
|
const editorContainer = elem.querySelector(".editor-container");
|
|
119
111
|
const splitter = elem.querySelector(".splitter");
|
|
120
112
|
const title = elem.getElementsByClassName("container-title")[0];
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
const editorCSS = elem.querySelector(".editor.css");
|
|
125
|
-
/** @type {HTMLTextAreaElement | null} */
|
|
126
|
-
const editorJS = elem.querySelector(".editor.js");
|
|
113
|
+
const editorHTMLDiv = elem.querySelector(".editor.html");
|
|
114
|
+
const editorCSSDiv = elem.querySelector(".editor.css");
|
|
115
|
+
const editorJSDiv = elem.querySelector(".editor.js");
|
|
127
116
|
/** @type {HTMLButtonElement | null} */
|
|
128
117
|
const btnHTML = elem.querySelector("button.html");
|
|
129
118
|
/** @type {HTMLButtonElement | null} */
|
|
@@ -131,6 +120,23 @@ hyperbook.webide = (function () {
|
|
|
131
120
|
/** @type {HTMLButtonElement | null} */
|
|
132
121
|
const btnJS = elem.querySelector("button.js");
|
|
133
122
|
|
|
123
|
+
// Initialize CodeMirror instances
|
|
124
|
+
const cmHTML = editorHTMLDiv ? (() => {
|
|
125
|
+
const src = editorHTMLDiv.textContent;
|
|
126
|
+
editorHTMLDiv.textContent = "";
|
|
127
|
+
return HyperbookCM.create(editorHTMLDiv, { lang: "html", value: src, onChange: () => update() });
|
|
128
|
+
})() : null;
|
|
129
|
+
const cmCSS = editorCSSDiv ? (() => {
|
|
130
|
+
const src = editorCSSDiv.textContent;
|
|
131
|
+
editorCSSDiv.textContent = "";
|
|
132
|
+
return HyperbookCM.create(editorCSSDiv, { lang: "css", value: src, onChange: () => update() });
|
|
133
|
+
})() : null;
|
|
134
|
+
const cmJS = editorJSDiv ? (() => {
|
|
135
|
+
const src = editorJSDiv.textContent;
|
|
136
|
+
editorJSDiv.textContent = "";
|
|
137
|
+
return HyperbookCM.create(editorJSDiv, { lang: "javascript", value: src, onChange: () => update() });
|
|
138
|
+
})() : null;
|
|
139
|
+
|
|
134
140
|
const frame = elem.getElementsByTagName("iframe")[0];
|
|
135
141
|
const template = elem.getAttribute("data-template");
|
|
136
142
|
const id = elem.getAttribute("data-id");
|
|
@@ -164,9 +170,9 @@ hyperbook.webide = (function () {
|
|
|
164
170
|
btnCSS?.classList.remove("active");
|
|
165
171
|
btnJS?.classList.remove("active");
|
|
166
172
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
editorHTMLDiv?.classList.add("active");
|
|
174
|
+
editorCSSDiv?.classList.remove("active");
|
|
175
|
+
editorJSDiv?.classList.remove("active");
|
|
170
176
|
});
|
|
171
177
|
|
|
172
178
|
btnCSS?.addEventListener("click", () => {
|
|
@@ -174,9 +180,9 @@ hyperbook.webide = (function () {
|
|
|
174
180
|
btnCSS?.classList.add("active");
|
|
175
181
|
btnJS?.classList.remove("active");
|
|
176
182
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
editorHTMLDiv?.classList.remove("active");
|
|
184
|
+
editorCSSDiv?.classList.add("active");
|
|
185
|
+
editorJSDiv?.classList.remove("active");
|
|
180
186
|
});
|
|
181
187
|
|
|
182
188
|
btnJS?.addEventListener("click", () => {
|
|
@@ -184,80 +190,40 @@ hyperbook.webide = (function () {
|
|
|
184
190
|
btnCSS?.classList.remove("active");
|
|
185
191
|
btnJS?.classList.add("active");
|
|
186
192
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
193
|
+
editorHTMLDiv?.classList.remove("active");
|
|
194
|
+
editorCSSDiv?.classList.remove("active");
|
|
195
|
+
editorJSDiv?.classList.add("active");
|
|
190
196
|
});
|
|
191
197
|
|
|
192
|
-
const load = async () => {
|
|
193
|
-
const result = await hyperbook.store.db.webide.get(id);
|
|
194
|
-
if (!result) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
const website = template
|
|
198
|
-
.replace("###HTML###", result.html)
|
|
199
|
-
.replace("###CSS###", result.css)
|
|
200
|
-
.replace("###JS###", result.js);
|
|
201
|
-
frame.srcdoc = website;
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
load();
|
|
205
|
-
|
|
206
198
|
const update = () => {
|
|
199
|
+
const htmlVal = cmHTML?.getValue() ?? "";
|
|
200
|
+
const cssVal = cmCSS?.getValue() ?? "";
|
|
201
|
+
const jsVal = cmJS?.getValue() ?? "";
|
|
207
202
|
hyperbook.store.db.webide.put({
|
|
208
203
|
id,
|
|
209
|
-
html:
|
|
210
|
-
css:
|
|
211
|
-
js:
|
|
204
|
+
html: htmlVal,
|
|
205
|
+
css: cssVal,
|
|
206
|
+
js: jsVal,
|
|
212
207
|
});
|
|
213
208
|
const website = template
|
|
214
|
-
.replace("###HTML###",
|
|
215
|
-
.replace("###CSS###",
|
|
216
|
-
.replace("###JS###",
|
|
209
|
+
.replace("###HTML###", htmlVal)
|
|
210
|
+
.replace("###CSS###", cssVal)
|
|
211
|
+
.replace("###JS###", jsVal);
|
|
217
212
|
frame.srcdoc = website;
|
|
218
213
|
};
|
|
219
214
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
editorHTML?.addEventListener("code-input_load", async () => {
|
|
225
|
-
const result = await hyperbook.store.db.webide.get(id);
|
|
226
|
-
if (result) {
|
|
227
|
-
editorHTML.value = result.html;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
update();
|
|
231
|
-
|
|
232
|
-
editorHTML.addEventListener("input", () => {
|
|
233
|
-
update();
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
editorCSS?.addEventListener("code-input_load", async () => {
|
|
238
|
-
const result = await hyperbook.store.db.webide.get(id);
|
|
215
|
+
// Restore saved state on init
|
|
216
|
+
hyperbook.store.db.webide.get(id).then((result) => {
|
|
239
217
|
if (result) {
|
|
240
|
-
|
|
218
|
+
if (cmHTML && result.html != null) cmHTML.setValue(result.html);
|
|
219
|
+
if (cmCSS && result.css != null) cmCSS.setValue(result.css);
|
|
220
|
+
if (cmJS && result.js != null) cmJS.setValue(result.js);
|
|
241
221
|
}
|
|
242
|
-
|
|
243
222
|
update();
|
|
244
|
-
|
|
245
|
-
editorCSS.addEventListener("input", () => {
|
|
246
|
-
update();
|
|
247
|
-
});
|
|
248
223
|
});
|
|
249
224
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (result) {
|
|
253
|
-
editorJS.value = result.js;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
update();
|
|
257
|
-
|
|
258
|
-
editorJS.addEventListener("input", () => {
|
|
259
|
-
update();
|
|
260
|
-
});
|
|
225
|
+
frame.addEventListener("load", () => {
|
|
226
|
+
title.textContent = frame.contentDocument.title;
|
|
261
227
|
});
|
|
262
228
|
|
|
263
229
|
downloadEl?.addEventListener("click", async () => {
|
|
@@ -12,6 +12,18 @@ code-input {
|
|
|
12
12
|
margin: 0;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
.directive-webide .editor {
|
|
16
|
+
width: 100%;
|
|
17
|
+
border: 1px solid var(--color-spacer);
|
|
18
|
+
flex: 1;
|
|
19
|
+
min-height: 0;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.directive-webide .editor .cm-editor {
|
|
24
|
+
height: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
.directive-webide .container {
|
|
16
28
|
width: 100%;
|
|
17
29
|
min-height: 120px;
|
|
@@ -89,12 +101,6 @@ code-input {
|
|
|
89
101
|
opacity: 0.75;
|
|
90
102
|
}
|
|
91
103
|
|
|
92
|
-
.directive-webide .editor {
|
|
93
|
-
width: 100%;
|
|
94
|
-
border: 1px solid var(--color-spacer);
|
|
95
|
-
flex: 1;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
104
|
.directive-webide .editor:not(.active) {
|
|
99
105
|
display: none;
|
|
100
106
|
}
|