import/export worx git add -A

This commit is contained in:
Theis Pieter Hollebeek 2025-10-11 20:02:27 +02:00
parent 3ae6187380
commit 5650e3ff4f
3 changed files with 56 additions and 15 deletions

View File

@ -68,14 +68,27 @@ editor.addEventListener("change", () => {
}); });
importButton.onclick = async () => { importButton.onclick = async () => {
const files = await promptUpload("", false); const files = await promptUpload(".karlkode", false);
if (files.length === 0) { if (files.length === 0) {
return; return;
} }
if (files.length > 1) { if (files.length > 1) {
throw new Error("unreachable: something went wrong ! files.length > 1"); throw new Error(
`unreachable: something went wrong ! files.length > 1 : files.length = ${files.length}`,
);
} }
const item = Vermiparous.de(await fetch(URL.createObjectURL(files[0])).then((x) => x.bytes())); const items = Vermiparous.de(await fetch(URL.createObjectURL(files[0])).then((x) => x.bytes()));
const sprites = items
.filter((x) => x.tag === "asset")
.map((x) => {
delete x.tag;
return x;
});
const code = items.find((x) => x.tag === "code");
delete code.tag;
spriteEditor.importSprites(sprites);
const dec = new TextDecoder();
editor.setValue(dec.decode(code.content));
}; };
runButton.onclick = () => { runButton.onclick = () => {
@ -95,7 +108,26 @@ runButton.onclick = () => {
} }
}; };
function downloadFile(content, mime, extension) { function downloadBinaryFile(content, extension) {
const filename = prompt("Filename?");
const blob = new Blob([content]);
const url = URL.createObjectURL(blob);
const element = document.createElement("a");
element.href = url;
element.download = filename.endsWith(extension) ? filename : filename + extension;
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
function downloadTextFile(content, mime, extension) {
const filename = prompt("Filename?"); const filename = prompt("Filename?");
const element = document.createElement("a"); const element = document.createElement("a");
@ -129,7 +161,7 @@ saveButton.onclick = () => {
}; };
saveJsButton.onclick = () => { saveJsButton.onclick = () => {
downloadFile(editor.getValue(), "text/javascript", ".js"); downloadTextFile(editor.getValue(), "text/javascript", ".js");
}; };
saveHtmlButton.onclick = async () => { saveHtmlButton.onclick = async () => {
@ -154,6 +186,9 @@ saveHtmlButton.onclick = async () => {
height: 100vh; height: 100vh;
margin: 0; margin: 0;
} }
An iterable object such as an Array, having ArrayBuffers, TypedArrays, DataViews, Blobs, strings, or a mix of any of such elements, that will be put inside the Blob. Strings should be well-formed Unicode, and lone surrogates are sanitized using the same algorithm as String.prototype.toWellFormed().
</style> </style>
<script type="importmap"> <script type="importmap">
{ {
@ -171,18 +206,15 @@ ${js}
</body> </body>
</html>`; </html>`;
downloadFile(html, "text/html", ".html"); downloadTextFile(html, "text/html", ".html");
}; };
saveKarlkoderButton.onclick = () => { saveKarlkoderButton.onclick = () => {
downloadFile( downloadBinaryFile(
Vermiparous.en( Vermiparous.en(
editor.getValue() editor.getValue(),
.split("\n")
.map((line) => " ".repeat(12) + line).join("\n"),
spriteEditor.sprites, spriteEditor.sprites,
), ),
"",
".karlkode", ".karlkode",
); );
}; };

View File

@ -1,7 +1,7 @@
import { promptUpload } from "./prompt_upload.js"; import { promptUpload } from "./prompt_upload.js";
export class SpriteEditor { export class SpriteEditor {
constructor(rootEl, sprites) { constructor(rootEl) {
this.list = rootEl.querySelector("#sprite-editor-sprite-list"); this.list = rootEl.querySelector("#sprite-editor-sprite-list");
this.editor = rootEl.querySelector("#sprite-editor"); this.editor = rootEl.querySelector("#sprite-editor");
this.toggleButton = rootEl.querySelector("#toggle-sprite-editor-button"); this.toggleButton = rootEl.querySelector("#toggle-sprite-editor-button");
@ -11,7 +11,7 @@ export class SpriteEditor {
this.preview.title = rootEl.querySelector("#sprite-editor-preview-title"); this.preview.title = rootEl.querySelector("#sprite-editor-preview-title");
this.preview.image = rootEl.querySelector("#sprite-editor-preview-image"); this.preview.image = rootEl.querySelector("#sprite-editor-preview-image");
this.preview.snippet = rootEl.querySelector("#sprite-editor-preview-snippet"); this.preview.snippet = rootEl.querySelector("#sprite-editor-preview-snippet");
this.sprites = sprites; this.sprites = [];
rootEl.querySelector("#sprite-editor-upload-button").addEventListener("click", () => { rootEl.querySelector("#sprite-editor-upload-button").addEventListener("click", () => {
this.promptUpload(); this.promptUpload();
@ -20,6 +20,11 @@ export class SpriteEditor {
this.renderList(); this.renderList();
} }
importSprites(sprites) {
this.sprites = sprites;
this.renderList();
}
async promptUpload() { async promptUpload() {
for (const file of await promptUpload("image/*", true)) { for (const file of await promptUpload("image/*", true)) {
const rootName = file.name; const rootName = file.name;

View File

@ -41,8 +41,12 @@ export class Vermiparous {
let idx = 0; let idx = 0;
while (idx < bytes.length) { while (idx < bytes.length) {
buffer.push(bytes[idx]); buffer.push(bytes[idx]);
if (buffer.length >= MAX_KW_LENGTH) { if (buffer.length > MAX_KW_LENGTH) {
throw new Error("unreachable: something went wrong ! unrecognized action"); throw new Error(
`unreachable: something went wrong ! unrecognized action '${
JSON.stringify(buffer)
}'`,
);
} }
if (buffer.length < MIN_KW_LENGTH || !isKeyword(buffer)) { if (buffer.length < MIN_KW_LENGTH || !isKeyword(buffer)) {
++idx; ++idx;