188 lines
8.5 KiB
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><script></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 — session log — 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>
|