Run playground examples from entrypoint

This commit is contained in:
2026-07-09 19:12:18 +09:00
parent a653f0b7c6
commit 5b26d071ca
2 changed files with 38 additions and 7 deletions
+33 -7
View File
@@ -7,7 +7,7 @@ import { keymap } from '@codemirror/view';
import { decodal } from 'decodal-codemirror';
import { playgroundExamples } from './playground-examples.js';
const STORAGE_KEY = 'decodal-playground-project-v1';
const STORAGE_KEY = 'decodal-playground-project-v2';
const starterProject = playgroundExamples[0];
const editorHost = document.getElementById('editor');
@@ -90,6 +90,7 @@ for (const example of playgroundExamples) {
exampleSelect.value = starterProject.id;
setActiveFile(project.activePath);
updateRunLabel();
renderFileTree();
function loadProject() {
@@ -98,12 +99,22 @@ function loadProject() {
if (stored && stored.files && typeof stored.activePath === 'string') {
const files = normalizeFiles(stored.files);
const activePath = files[stored.activePath] === undefined ? Object.keys(files)[0] : stored.activePath;
if (activePath) return { files, activePath };
if (activePath) {
const storedEntryPath = typeof stored.entryPath === 'string' ? normalizePath(stored.entryPath) : '';
const entryPath = files[storedEntryPath] === undefined
? files['main.dcdl'] === undefined ? activePath : 'main.dcdl'
: storedEntryPath;
return { files, activePath, entryPath };
}
}
} catch (_error) {
// Fall back to the starter project.
}
return { files: cloneFiles(starterProject.files), activePath: starterProject.activePath };
return {
files: cloneFiles(starterProject.files),
activePath: starterProject.activePath,
entryPath: starterProject.entryPath ?? starterProject.activePath,
};
}
function cloneFiles(files) {
@@ -127,6 +138,7 @@ function loadExampleProject(exampleId) {
const example = playgroundExamples.find((item) => item.id === exampleId) ?? starterProject;
project.files = cloneFiles(example.files);
project.activePath = example.activePath;
project.entryPath = example.entryPath ?? example.activePath;
exampleSelect.value = example.id;
setActiveFile(project.activePath);
output.textContent = '';
@@ -166,16 +178,27 @@ function setActiveFile(path) {
}
project.activePath = normalized;
setEditorText(project.files[normalized]);
activeFile.textContent = normalized;
activeFile.textContent = normalized === project.entryPath ? `${normalized} (entry)` : normalized;
deleteFile.disabled = Object.keys(project.files).length <= 1;
renderFileTree();
updateRunLabel();
saveProject();
}
function updateRunLabel() {
const entryPath = project.files[project.entryPath] === undefined ? project.activePath : project.entryPath;
project.entryPath = entryPath;
run.textContent = `Run ${entryPath}`;
run.title = `Materialize ${entryPath}`;
}
function execute() {
project.files[project.activePath] = getEditorText();
const entryPath = project.files[project.entryPath] === undefined ? project.activePath : project.entryPath;
project.entryPath = entryPath;
updateRunLabel();
saveProject();
const result = JSON.parse(evaluateProject(project.activePath, JSON.stringify(project.files)));
const result = JSON.parse(evaluateProject(entryPath, JSON.stringify(project.files)));
output.textContent = result.ok ? result.output : result.error;
output.classList.toggle('error', !result.ok);
}
@@ -224,8 +247,8 @@ function renderTreeList(children) {
const button = document.createElement('button');
button.type = 'button';
button.className = child.path === project.activePath ? 'file active' : 'file';
button.textContent = child.name;
button.title = child.path;
button.textContent = child.path === project.entryPath ? `${child.name} *` : child.name;
button.title = child.path === project.entryPath ? `${child.path} (entry point)` : child.path;
button.addEventListener('click', () => setActiveFile(child.path));
item.append(button);
} else {
@@ -276,5 +299,8 @@ deleteFile.addEventListener('click', () => {
if (Object.keys(project.files).length <= 1) return;
if (!confirm(`Delete ${project.activePath}?`)) return;
delete project.files[project.activePath];
if (project.files[project.entryPath] === undefined) {
project.entryPath = Object.keys(project.files).sort()[0];
}
setActiveFile(Object.keys(project.files).sort()[0]);
});