history: CodePanel — CodeMirror editor, FileEditorRegistry, file routing by suffix
This commit is contained in:
parent
55acdd3f12
commit
7ffa2f7588
|
|
@ -11,6 +11,7 @@ var NAV_DATA = {
|
|||
path: 'guides/index.html',
|
||||
children: [
|
||||
{ title: 'Writing TypeScript Code', path: 'guides/writing-typescript-code/index.html' },
|
||||
{ title: 'Writing Editor Panels', path: 'guides/writing-editor-panels/index.html' },
|
||||
{ title: 'Locales', path: 'guides/locales/index.html' },
|
||||
]
|
||||
},
|
||||
|
|
@ -26,6 +27,7 @@ var NAV_DATA = {
|
|||
title: 'History',
|
||||
path: 'history/index.html',
|
||||
children: [
|
||||
{ title: 'Friday, 10 July 2026', path: 'history/2026/07-July/10-Friday/index.html' },
|
||||
{ title: 'Thursday, 9 July 2026', path: 'history/2026/07-July/09-Thursday/index.html' },
|
||||
{ title: 'Monday, 6 July 2026', path: 'history/2026/07-July/06-Monday/index.html' },
|
||||
{ title: 'Sunday, 5 July 2026', path: 'history/2026/07-July/05-Sunday/index.html' },
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
<!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>
|
||||
|
|
@ -19,6 +19,11 @@
|
|||
<section>
|
||||
<h2>2026 — July</h2>
|
||||
|
||||
<div class="card">
|
||||
<h3><a href="2026/07-July/10-Friday/index.html">Friday, 10 July 2026</a></h3>
|
||||
<p>CodePanel — CodeMirror 5 code editor panel; FileEditorRegistry routes files to editors by suffix with a project-level JSON override; all file types now clickable in the tree.</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3><a href="2026/07-July/09-Thursday/index.html">Thursday, 9 July 2026</a></h3>
|
||||
<p>RojoChatPanel — streaming AI chat panel for the editor with LangChain backend (@langchain/core + @langchain/openai), markdown-it rendering, and tab container integration.</p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue