rojects/workspace/history/2026/07-July/10-Friday/index.html

188 lines
8.5 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Session Summary — 10 July 2026</title>
<link rel="stylesheet" href="../../../../_assets_/styles.css">
<link rel="stylesheet" href="../../../../_assets_/nav.css">
</head>
<body>
<div class="page">
<header>
<p class="date">Friday, 10 July 2026</p>
<h1>Roject — Session Summary</h1>
<p class="subtitle">
CodePanel — a CodeMirror-based code editor panel with a central
file-editor registry that routes files to the right panel by suffix.
</p>
</header>
<section>
<h2>What we built</h2>
<div class="card">
<h3>FileEditorRegistry</h3>
<p>
A new <code>src/editor/FileEditorRegistry.ts</code> class that maps file
suffixes to editor panel tags. It holds a default in-memory list and
optionally loads a project-level override from
<code>workspace/editor/file-editors.json</code> inside the open project.
</p>
<p style="margin-top:0.75rem">
Matching is pure suffix comparison — <code>filename.endsWith('.' + suffix)</code>
— so <code>special.html</code> beats <code>html</code> when it appears
earlier in the list. The project list is checked first entry-by-entry;
only when no match is found there does it fall through to the defaults.
Unknown extensions fire an <code>onFileTypeUnknown</code> event instead
of opening anything.
</p>
<div class="tags">
<span class="tag">src/editor/FileEditorRegistry.ts</span>
<span class="tag">suffix matching</span>
<span class="tag">project override</span>
</div>
</div>
<div class="card">
<h3>Editor routing changes</h3>
<p>
<code>Editor.openDocument</code> now loads the registry (once, lazily)
before fetching file content. It resolves an <code>editorTag</code> and
includes it in the <code>DocumentOpenedEvent</code>. If no tag is found
it dispatches the new <code>onFileTypeUnknown</code> event and returns
early without fetching the file.
</p>
<p style="margin-top:0.75rem">
<code>HtmlEditorPanel</code> was updated to ignore events where
<code>editorTag !== 'html-editor-panel'</code>.
<code>TabContainer</code>'s dirty and saved listeners were simplified
to match any panel by <code>currentPath</code> rather than hard-coding
<code>panelType === 'html-editor'</code>.
</p>
<div class="tags">
<span class="tag">src/editor/Editor.ts</span>
<span class="tag">editorTag in DocumentOpenedEvent</span>
<span class="tag">onFileTypeUnknown</span>
</div>
</div>
<div class="card">
<h3>CodePanel component</h3>
<p>
A new <code>code-panel</code> custom element backed by CodeMirror 5.
Toolbar matches <code>html-editor-panel</code>: Pin, Undo, Redo, Save.
Undo and Redo delegate directly to <code>cm.undo()</code> /
<code>cm.redo()</code>; button enable-states are refreshed from
<code>cm.historySize()</code> on every CM <code>change</code> event.
</p>
<p style="margin-top:0.75rem">
Language mode is resolved from the file extension
(<code>js</code>/<code>ts</code>/<code>json</code> → javascript,
<code>css</code> → css, <code>xml</code>/<code>svg</code> → xml,
<code>md</code> → markdown, others → plain text).
A custom <code>cp-dark</code> CodeMirror theme matches the editor's
colour palette (background <code>#0f1117</code>, Material-style token
colours).
</p>
<p style="margin-top:0.75rem">
The file tree was updated so all files are clickable (not just HTML);
clicking an unsupported extension shows a 3-second red banner
("Can't open extension .xyz") at the top of the tree.
</p>
<div class="tags">
<span class="tag">src/components/code-panel/code-panel.ts</span>
<span class="tag">public/components/code-panel/code-panel.css</span>
<span class="tag">CodeMirror 5</span>
<span class="tag">cp-dark theme</span>
</div>
</div>
</section>
<section>
<h2>Key Decisions</h2>
<div class="decision">
<strong>Central JSON list, not editor self-registration</strong>
<p>
Editors could declare their own patterns at import time, but that makes
overriding them require touching editor source. A central list stored as
data (JSON) lets a project prepend custom mappings without modifying any
editor code. The project file is optional; when absent, in-memory
defaults apply.
</p>
</div>
<div class="decision">
<strong>Per-entry layered lookup, not full list replacement</strong>
<p>
When a project provides <code>file-editors.json</code>, only the suffixes
it declares are overridden. Everything else falls through to the defaults.
This means a project only needs to list custom formats, not restate all
standard ones.
</p>
</div>
<div class="decision">
<strong>Plain suffix strings, no glob patterns</strong>
<p>
Glob matching requires a library or a non-trivial implementation.
Stripping the leading <code>*.</code> and using
<code>endsWith('.' + suffix)</code> is sufficient for all real cases
(including compound extensions like <code>special.html</code>) and
needs no dependency.
</p>
</div>
<div class="decision">
<strong>CodeMirror 5 as a UMD global, vendored locally</strong>
<p>
CodeMirror 6 requires a bundler or complex import maps to use without
a build step. CM5 ships a single-file UMD build that works as a plain
<code>&lt;script&gt;</code> tag, matching the existing pattern
(<code>markdown-it</code>). The core and five language modes were
downloaded from cdnjs and placed in <code>public/vendor/</code>,
keeping the setup self-hosted and version-locked.
</p>
</div>
</section>
<section>
<h2>Structural Changes</h2>
<div class="card">
<p>
<code>src/editor/FileEditorRegistry.ts</code> — new: suffix-to-editor registry with project override<br>
<code>src/editor/Editor.ts</code> — added <code>fileEditorRegistry</code>, <code>editorTag</code> in event, <code>onFileTypeUnknown</code><br>
<code>src/components/html-editor-panel/html-editor-panel.ts</code> — filters <code>onDocumentOpened</code> by <code>editorTag</code><br>
<code>src/components/file-tree-panel/file-tree-panel.ts</code> — all files clickable, <code>_showTypeError</code> for unknown extensions<br>
<code>public/components/file-tree-panel/file-tree-panel.css</code> — all files get hover/active styles, added <code>.ftp-type-error</code><br>
<code>src/components/code-panel/code-panel.ts</code> — new: CodeMirror 5 editor panel<br>
<code>public/components/code-panel/code-panel.css</code> — new: panel layout + <code>cp-dark</code> CM theme<br>
<code>public/vendor/codemirror.min.js</code> — new (CM5 core)<br>
<code>public/vendor/codemirror.min.css</code> — new (CM5 base CSS)<br>
<code>public/vendor/cm-mode-xml.min.js</code> — new<br>
<code>public/vendor/cm-mode-javascript.min.js</code> — new<br>
<code>public/vendor/cm-mode-css.min.js</code> — new<br>
<code>public/vendor/cm-mode-htmlmixed.min.js</code> — new<br>
<code>public/vendor/cm-mode-markdown.min.js</code> — new<br>
<code>public/editor.html</code> — added CM vendor scripts, code-panel CSS and module script<br>
<code>src/components/tab-container/tab-container.ts</code> — added Code Editor to menu, panel-agnostic dirty tracking<br>
<code>src/components/editor-shell/editor-shell.ts</code> — awaits <code>code-panel</code> definition
</p>
</div>
</section>
<footer>
Roject &mdash; session log &mdash; 10 July 2026
</footer>
</div>
<script>var NAV_ROOT = '../../../../';</script>
<script src="../../../../_assets_/nav-data.js"></script>
<script src="../../../../_assets_/nav.js"></script>
</body>
</html>