history: add session entry for 25 July 2026
Page editor panel: structured .page format, block registry, rich-text toolbar, default-roject theme, wrapSelection helper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
420c682408
commit
3e25a419ca
|
|
@ -51,6 +51,7 @@ var NAV_DATA = {
|
||||||
title: 'History',
|
title: 'History',
|
||||||
path: 'history/index.html',
|
path: 'history/index.html',
|
||||||
children: [
|
children: [
|
||||||
|
{ title: 'Friday, 25 July 2026', path: 'history/2026/07-July/25-Friday/index.html' },
|
||||||
{ title: 'Friday, 18 July 2026', path: 'history/2026/07-July/18-Friday/index.html' },
|
{ title: 'Friday, 18 July 2026', path: 'history/2026/07-July/18-Friday/index.html' },
|
||||||
{ title: 'Wednesday, 16 July 2026', path: 'history/2026/07-July/16-Wednesday/index.html' },
|
{ title: 'Wednesday, 16 July 2026', path: 'history/2026/07-July/16-Wednesday/index.html' },
|
||||||
{ title: 'Tuesday, 15 July 2026', path: 'history/2026/07-July/15-Tuesday/index.html' },
|
{ title: 'Tuesday, 15 July 2026', path: 'history/2026/07-July/15-Tuesday/index.html' },
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,205 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Friday, 25 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, 25 July 2026</p>
|
||||||
|
<h1>Session History</h1>
|
||||||
|
<p class="subtitle">Page editor panel: structured .page format, block registry, rich-text toolbar, default theme.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>What we built</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Rename: <code>html-editor-panel</code> → <code>page-editor-panel</code></h3>
|
||||||
|
<p>
|
||||||
|
The old HTML editor panel is replaced by <code>page-editor-panel</code>
|
||||||
|
(<code>PageEditorPanel</code>), handling <code>.page</code> files instead of
|
||||||
|
<code>.html</code>/<code>.htm</code>. All references updated across:
|
||||||
|
<code>FileEditorRegistry.ts</code>, <code>editor.html</code>,
|
||||||
|
<code>editor-shell.ts</code>, <code>tab-container.ts</code>,
|
||||||
|
<code>file-tree-panel.ts</code>. The old folder was deleted.
|
||||||
|
<code>editor-shell</code> no longer auto-opens <code>index.html</code> on startup
|
||||||
|
— the panel shows an empty state until the user opens a <code>.page</code> file
|
||||||
|
from the file tree.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Structured <code>.page</code> format</h3>
|
||||||
|
<p>
|
||||||
|
A <code>.page</code> file is a full HTML document whose <code><body></code>
|
||||||
|
must contain exactly one <code><page-header></code>, one
|
||||||
|
<code><page-root></code>, and one <code><page-footer></code> as direct
|
||||||
|
children, in that order.
|
||||||
|
<code><page-root></code> holds any number of <code><page-block></code>
|
||||||
|
elements; each block contains one or more <code><page-area></code> elements
|
||||||
|
for rich-text content.
|
||||||
|
</p>
|
||||||
|
<p style="margin-top:0.75rem">
|
||||||
|
Format validation is a placeholder function (<code>validatePageFormat</code>) that
|
||||||
|
always returns <code>true</code>, documented for future implementation. When real
|
||||||
|
validation is added, invalid files fall back to <code>code-panel</code>.
|
||||||
|
</p>
|
||||||
|
<p style="margin-top:0.75rem">
|
||||||
|
<strong>Auto-template for empty files:</strong> when a <code>.page</code> file is
|
||||||
|
opened with empty content, validation is bypassed and the standard template
|
||||||
|
(full-width block, default theme) is injected automatically. The document is marked
|
||||||
|
dirty — the user must save to persist the structure.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Block registry</h3>
|
||||||
|
<p>
|
||||||
|
Available block templates are defined in a static table
|
||||||
|
(<code>PAGE_BLOCK_REGISTRY</code>) in <code>page-editor-panel.ts</code>. Each
|
||||||
|
entry has a <code>name</code>, optional CSS-sketch <code>preview</code> markup
|
||||||
|
(using <code>.pbp-*</code> helper classes), and an <code>html</code> snippet
|
||||||
|
appended to <code><page-root></code> when selected. Two standard blocks ship:
|
||||||
|
</p>
|
||||||
|
<ul style="line-height:1.9;margin-top:0.75rem">
|
||||||
|
<li><strong>Full Width</strong> — one <code><page-area></code> spanning the
|
||||||
|
full container width (<code>pep-block-full</code>).</li>
|
||||||
|
<li><strong>Two Columns</strong> — two equal <code><page-area></code> elements
|
||||||
|
side by side on landscape; stacked top-to-bottom on portrait via a CSS media
|
||||||
|
query (<code>pep-block-two-col</code>).</li>
|
||||||
|
</ul>
|
||||||
|
<p style="margin-top:0.75rem">
|
||||||
|
Block items without a <code>preview</code> entry show their name as a text label
|
||||||
|
inside the preview box.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Two-mode sidebar</h3>
|
||||||
|
<p>
|
||||||
|
Two icon buttons on the left edge of the panel switch between editing modes:
|
||||||
|
</p>
|
||||||
|
<ul style="line-height:1.9;margin-top:0.75rem">
|
||||||
|
<li><strong>Blocks mode (⊞)</strong> — shows a horizontal scrollable list of block
|
||||||
|
templates. Each entry has a CSS layout sketch preview above its name. Clicking
|
||||||
|
a block appends it to <code><page-root></code> in the iframe and makes
|
||||||
|
its new <code><page-area></code> elements contenteditable immediately,
|
||||||
|
without a full re-render.</li>
|
||||||
|
<li><strong>Areas mode (T)</strong> — shows the rich-text formatting toolbar.
|
||||||
|
Buttons: <code>B</code> (bold), <code>I</code> (italic), <code>U</code>
|
||||||
|
(underline), then a separator, then <code>H1</code>, <code>H2</code>,
|
||||||
|
<code>H3</code>.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Rich-text: <code>wrapSelection</code></h3>
|
||||||
|
<p>
|
||||||
|
Formatting is applied via <code>wrapSelection(doc, range, tagName, attributes?)</code>
|
||||||
|
— no <code>execCommand</code>. The helper uses <code>Range.extractContents()</code>
|
||||||
|
to pull the selected fragment out of the DOM, wraps it in the target element
|
||||||
|
(created in the iframe document), and re-inserts via <code>Range.insertNode()</code>.
|
||||||
|
The Range API automatically splits text nodes and element boundaries, so both
|
||||||
|
fully-contained nodes and boundary intersections are handled correctly.
|
||||||
|
Semantic tags are preferred: <code><b></code>, <code><i></code>,
|
||||||
|
<code><u></code>, <code><h1></code>–<code><h3></code>.
|
||||||
|
Adjacent identical elements are not merged after wrapping (future work, documented).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>iframe sandbox + editor CSS injection</h3>
|
||||||
|
<p>
|
||||||
|
The editor iframe carries <code>sandbox="allow-same-origin"</code>, blocking script
|
||||||
|
execution for user-authored <code><script></code> tags. The sandbox attribute
|
||||||
|
is documented as the single point to change if sandboxing needs adjustment.
|
||||||
|
</p>
|
||||||
|
<p style="margin-top:0.75rem">
|
||||||
|
Editor-side layout styles (<code>PEP_EDITOR_STYLES</code>) are injected into the
|
||||||
|
live iframe <code><head></code> post-load as
|
||||||
|
<code><style id="pep-editor-injected"></code>. Before saving, the element is
|
||||||
|
temporarily removed, <code>outerHTML</code> is captured, then the element is
|
||||||
|
re-appended — so the injected styles never reach disk. The MutationObserver watches
|
||||||
|
only <code><page-root></code>, so head mutations do not trigger change events.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Default theme: <code>default-roject</code></h3>
|
||||||
|
<p>
|
||||||
|
All theme CSS rules are scoped to <code>[data-theme="default-roject"]</code>.
|
||||||
|
The <code><body></code> and <code><page-root></code> in the standard
|
||||||
|
template both carry this attribute so the theme applies to the full document and
|
||||||
|
to all content inside blocks.
|
||||||
|
</p>
|
||||||
|
<p style="margin-top:0.75rem">
|
||||||
|
The theme CSS (<code>DEFAULT_THEME_CSS</code>) is embedded as a
|
||||||
|
<code><style></code> block in the page <code><head></code> for new
|
||||||
|
files. Future plan: replace with a <code><link></code> to
|
||||||
|
<code>styles.rokojori.com</code> when themes are hosted there.
|
||||||
|
</p>
|
||||||
|
<p style="margin-top:0.75rem">Styles defined:</p>
|
||||||
|
<ul style="line-height:1.9;margin-top:0.5rem">
|
||||||
|
<li>Base: dark background (<code>#0f1117</code>), whitish copy (<code>#c8cce0</code>),
|
||||||
|
Barlow font via <code>@import</code> from <code>styles.rokojori.com</code>,
|
||||||
|
<code>1rem / 1.7</code> line-height.</li>
|
||||||
|
<li><code>h1</code>: blue (<code>#7c8cff</code>), 2.5rem, 900 italic, uppercase.</li>
|
||||||
|
<li><code>h2</code>: blue (<code>#7c8cff</code>), 1.6rem, 700.</li>
|
||||||
|
<li><code>h3</code>: muted blue (<code>#9ba4c7</code>), 1.2rem, 700.</li>
|
||||||
|
<li><code>b</code> / <code>strong</code>: bright white (<code>#e2e4ed</code>).</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Key decisions</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>
|
||||||
|
<strong>Placeholder validation instead of gating immediately.</strong>
|
||||||
|
The real format check (exactly one page-header / page-root / page-footer in body,
|
||||||
|
no other elements) is documented but not enforced yet — <code>validatePageFormat</code>
|
||||||
|
always returns <code>true</code>. This keeps the editor usable while the format
|
||||||
|
stabilises, without hiding the validation contract.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>
|
||||||
|
<strong><code>wrapSelection</code> for headings, not block-level replacement.</strong>
|
||||||
|
H1/H2/H3 buttons wrap the selection the same way as B/I/U rather than replacing
|
||||||
|
the parent block element. This is consistent with the existing system and avoids
|
||||||
|
the complexity of block-level conversion for now. The limitation is documented.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<p>
|
||||||
|
<strong>Theme attribute on both <code><body></code> and
|
||||||
|
<code><page-root></code>.</strong>
|
||||||
|
Putting <code>data-theme</code> on <code><body></code> lets the base styles
|
||||||
|
(background, font, colour) apply to the full document without a separate unscoped
|
||||||
|
<code>body { }</code> rule. <code><page-root></code> keeps its own attribute
|
||||||
|
for future per-block theme overrides.
|
||||||
|
</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>
|
||||||
Loading…
Reference in New Issue