172 lines
7.7 KiB
HTML
172 lines
7.7 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>Friday, 31 July 2026 — Roject</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, 31 July 2026</p>
|
||
|
|
<h1>Session History</h1>
|
||
|
|
<p class="subtitle">File tree UX improvements, page editor toolbar, EditorConsole message system, console-panel tab.</p>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<section>
|
||
|
|
<h2>What we built</h2>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>File tree: open-state preservation on refresh</h3>
|
||
|
|
<p>
|
||
|
|
Before this fix, calling <code>refresh()</code> on <code>file-tree-panel</code>
|
||
|
|
collapsed all open directories. The fix records which <code>ftp-dir</code> elements
|
||
|
|
carry the <code>open</code> class (via <code>data-path</code> on their
|
||
|
|
<code>ftp-dir-label</code>) before rebuilding the HTML, then re-adds
|
||
|
|
<code>open</code> to the matching labels after the new tree renders.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>File tree: "Mark As Root Directory" moved to context menu</h3>
|
||
|
|
<p>
|
||
|
|
The double-click listener on <code>ftp-dir-label</code> was removed.
|
||
|
|
"As Root Directory" is now a context menu entry that appears when right-clicking
|
||
|
|
a directory, inside the existing <code>showItemMenu()</code> method.
|
||
|
|
<code>isDir</code> detection uses <code>targetPath.endsWith('/')</code>.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>File tree: "Open >" submenu for alternate editors</h3>
|
||
|
|
<p>
|
||
|
|
When right-clicking a file that has a known editor, the context menu shows an
|
||
|
|
<em>Open ></em> submenu listing the default editor plus all registered
|
||
|
|
alternatives. Selecting an entry calls <code>_openFileIn(path, editorTag)</code>,
|
||
|
|
which focuses an existing tab of that type or creates a new one.
|
||
|
|
</p>
|
||
|
|
<p style="margin-top:0.75rem">
|
||
|
|
Two static maps drive this:
|
||
|
|
<code>_panelTypeMap</code> (editorTag → panelType + label) and
|
||
|
|
<code>_editorAlternatives</code> (defaultEditorTag → alternativeEditorTags[]).
|
||
|
|
<code>_openFileDefault</code> (single click) focuses the file in any open editor
|
||
|
|
regardless of type; <code>_openFileIn</code> (context menu) focuses only in the
|
||
|
|
specified editor type.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>File tree: context menu label truncation</h3>
|
||
|
|
<p>
|
||
|
|
The context menu title now shows only the filename (not the full path), truncated
|
||
|
|
to a configurable <code>menuLabelMaxChars</code> (20). Names longer than the limit
|
||
|
|
are shown as <code>...last-20-chars</code>.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>Page editor: mode buttons moved into toolbar</h3>
|
||
|
|
<p>
|
||
|
|
The left sidebar (<code>.pep-sidebar</code>) and its wrapper (<code>.pep-main</code>)
|
||
|
|
were removed. The Blocks (⊞) and Areas (T) mode buttons were moved directly into
|
||
|
|
<code>.pep-toolbar</code>, separated from the left-side toolbar items by a
|
||
|
|
<code>.pep-toolbar-sep</code> spacer (<code>flex: 1</code>) that pushes them to
|
||
|
|
the right. <code>page-editor-panel</code> now uses <code>flex-direction: column</code>
|
||
|
|
with three direct children: toolbar, mode panel, iframe.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>EditorConsole — centralised message system</h3>
|
||
|
|
<p>
|
||
|
|
New singleton <code>EditorConsole</code> (<code>source/editor/EditorConsole.ts</code>)
|
||
|
|
holds a capped ring of 500 <code>ConsoleMessage</code> objects
|
||
|
|
(<code>text</code>, <code>type</code>: <code>'info'|'error'|'hint'</code>,
|
||
|
|
<code>timestamp</code>) and dispatches them via <code>onMessage: EventSlot</code>.
|
||
|
|
<code>showHover</code> / <code>hideHover</code> dispatch a secondary
|
||
|
|
<code>onHover: EventSlot<string | null></code> for future tooltip use.
|
||
|
|
</p>
|
||
|
|
<p style="margin-top:0.75rem">
|
||
|
|
<code>editor-shell</code> subscribes to <code>onMessage</code> and shows incoming
|
||
|
|
messages in a new <code>.es-info</code> element in the header — fades in for 5 s
|
||
|
|
then fades out. Portrait mode hides the inline element and would show a fixed bottom
|
||
|
|
bar instead. <code>Editor.get().onFileTypeUnknown</code> is now handled here,
|
||
|
|
logging to <code>EditorConsole</code> rather than as an inline error in
|
||
|
|
<code>file-tree-panel</code>.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>console-panel — new editor tab</h3>
|
||
|
|
<p>
|
||
|
|
<code>console-panel</code> is a new tab that renders all messages from
|
||
|
|
<code>EditorConsole</code>. Custom elements: <code>conp-header</code>,
|
||
|
|
<code>conp-title</code>, <code>conp-list</code>, <code>conp-entry</code>,
|
||
|
|
<code>conp-time</code>, <code>conp-text</code>. On connect it pre-populates
|
||
|
|
from <code>EditorConsole.get().messages</code>, then appends new entries as they
|
||
|
|
arrive. Time format: <code>HH:MM:SS</code>. Entry classes (<code>conp-entry-error</code>,
|
||
|
|
<code>conp-entry-hint</code>) colour <code>conp-text</code> accordingly.
|
||
|
|
Implements <code>EditorPanelDefinition.type</code> via <code>__interfaces__</code>.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<h3>Bug fix: <code>openDocumentIn</code> ignored the target panel type</h3>
|
||
|
|
<p>
|
||
|
|
<code>Editor.openDocumentIn(filePath, panelElement)</code> was re-resolving
|
||
|
|
<code>editorTag</code> from the <code>FileEditorRegistry</code>, which always
|
||
|
|
returned the <em>default</em> editor for the file type (e.g. <code>page-editor-panel</code>
|
||
|
|
for <code>.page</code> files). The <code>code-panel</code> listener checked
|
||
|
|
<code>if ('code-panel' !== e.editorTag) return</code> and bailed, so the file
|
||
|
|
appeared to open but showed no content.
|
||
|
|
</p>
|
||
|
|
<p style="margin-top:0.75rem">
|
||
|
|
Fix: derive <code>editorTag</code> from <code>panelElement.tagName.toLowerCase()</code>
|
||
|
|
directly, removing the registry lookup entirely from <code>openDocumentIn</code>.
|
||
|
|
The caller already decided which panel to target; the dispatch should respect that
|
||
|
|
decision.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section>
|
||
|
|
<h2>Key decisions</h2>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<p>
|
||
|
|
<strong><code>EditorConsole</code> as a standalone singleton, not part of
|
||
|
|
<code>Editor</code>.</strong>
|
||
|
|
Keeping it separate means any component (including future non-editor panels) can
|
||
|
|
import just <code>EditorConsole</code> without pulling in the full editor state.
|
||
|
|
<code>Editor.onFileTypeUnknown</code> is bridged to it in <code>editor-shell</code>,
|
||
|
|
the single component that knows about both.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="card">
|
||
|
|
<p>
|
||
|
|
<strong>Two open-file methods instead of one.</strong>
|
||
|
|
<code>_openFileDefault</code> (single click) focuses the file in any editor;
|
||
|
|
<code>_openFileIn</code> (context menu "Open >") focuses only in the specified
|
||
|
|
editor type and forces that type when creating a new tab. This makes the intent
|
||
|
|
explicit without adding a flag parameter.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<footer>
|
||
|
|
Roject — session history
|
||
|
|
</footer>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
<script>var NAV_ROOT = '../../../../';</script>
|
||
|
|
<script src="../../../../_assets_/nav-data.js"></script>
|
||
|
|
<script src="../../../../_assets_/nav.js"></script>
|
||
|
|
</body>
|
||
|
|
</html>
|