diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 37a0f5d..0ec0a48 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -27,6 +27,10 @@ jobs: mkdir -p _site cp index.html rdfa-editor.css _site/ cp -r lib dist vocabs _site/ + # core editor only: the LinkedDataHub-extended flavor (demo/ + + # its SEF) needs the content-negotiating dev server (serve.mjs) + # and is never deployed to Pages + rm -f _site/dist/ldh-editor.xsl.sef.json - name: Publish to gh-pages branch uses: peaceiris/actions-gh-pages@v4 with: diff --git a/CLAUDE.md b/CLAUDE.md index e0b6da5..13305cf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,26 +13,30 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Overview -RDFa-Editor is a prototype XHTML+RDFa authoring tool using client-side XSLT. Content lives in a `#content` container of structured blocks (p, h1–h3, ul/ol, blockquote, pre, figure, table), always editable Notion-style: typing within blocks, Enter splits, Backspace-at-start merges, toolbar for block types / inline formatting / lists / figures / tables / links, drag-handle reordering, a `/` slash menu (in an empty block) and markdown shortcuts (`# `, `- `, `1. `, `> `, ` ``` `) that insert/convert blocks per the content model. Nesting follows the **XHTML Strict content model** (see content-model.xsl below): `blockquote` is a block *container* (`blockquote > p+` — bare text inside it is invalid and gets normalized; the toolbar quote toggle wraps/unwraps), `li`/`td`/`th`/`dd`/`figcaption` are `%Flow;` (mixed text AND nested blocks — Tab/Shift+Tab indent/outdent nested lists), `p`/`h1–h6`/`caption`/`dt` are inline-only. Tables are composite blocks (structure locked; `td`/`th`/`caption` editable) inserted via a rows×cols dialog with an optional header row and caption; row/column toolbar controls, Tab/Shift+Tab cell traversal and Enter (step down a column) all grow the grid at its bottom edge. Right-click a text selection to annotate it with RDFa; right-click an existing annotation to edit or remove it. "Extract RDF" shows the page's triples; "Source" shows the canonical XHTML+RDFa serialization (all editing ephemera stripped). +RDFa-Editor is a prototype XHTML+RDFa authoring tool using client-side XSLT. Content lives in a `#content` container of structured blocks (p, h1–h3, ul/ol, blockquote, pre, figure, table), always editable Notion-style: typing within blocks, Enter splits, Backspace-at-start merges, toolbar for block types / inline formatting / lists / figures / tables / links, drag-handle reordering, a `/` slash menu (in an empty block) and markdown shortcuts (`# `, `- `, `1. `, `> `, ` ``` `) that insert/convert blocks per the content model. **Object blocks** (blocks.xsl) embed RDF-defined blocks per the LDH v6 document format (`XHTML-RDFa-as-LDH-v6-Document-Format` wiki) — a `div[@about][@typeof]` whose `@typeof` matches the `$object-block-types` param, its defining triples inline as `span[@property]` children — treated as **atomic islands** (never editable inside, focusable/navigable/deletable like block images, hard merge/delete boundaries) and rendered client-side into an ephemeral `div[@data-role='rendering']` child via the overridable `mode="local:render-island"` hook; the LinkedDataHub extension (ldh-blocks.xsl, layered by the ldh-editor.xsl entry via `xsl:import`) supplies `ldh:Object`/`ldh:View`/`ldh:ResultSetChart` renderers, an insert dialog and slash/toolbar contributions. Nesting follows the **XHTML Strict content model** (see content-model.xsl below): `blockquote` is a block *container* (`blockquote > p+` — bare text inside it is invalid and gets normalized; the toolbar quote toggle wraps/unwraps), `li`/`td`/`th`/`dd`/`figcaption` are `%Flow;` (mixed text AND nested blocks — Tab/Shift+Tab indent/outdent nested lists), `p`/`h1–h6`/`caption`/`dt` are inline-only. Tables are composite blocks (structure locked; `td`/`th`/`caption` editable) inserted via a rows×cols dialog with an optional header row and caption; row/column toolbar controls, Tab/Shift+Tab cell traversal and Enter (step down a column) all grow the grid at its bottom edge. Right-click a text selection to annotate it with RDFa; right-click an existing annotation to edit or remove it. "Extract RDF" shows the page's triples; "Source" shows the canonical XHTML+RDFa serialization (all editing ephemera stripped). ## Architecture -XSLT 3.0 running on **SaxonJS 3** with its interactive extensions (`ixsl:` namespace). `index.html` loads `lib/SaxonJS3.js` and executes `dist/index.xsl.sef.json` (initial template `main`). The editor UI is fully generated by the stylesheet — the overlay is rendered once at startup (hidden) and only populated/shown/hidden afterwards, so the stylesheet is self-contained and embeddable on any host page. +XSLT 3.0 running on **SaxonJS 3** with its interactive extensions (`ixsl:` namespace). `index.html` loads `lib/SaxonJS3.js` and executes `dist/index.xsl.sef.json` (initial template `main`); async work uses the **SaxonJS 3 promise API** (`ixsl:promise` + `ixsl:http-request` `=> ixsl:then`, `on-failure`; DOM-mutating callbacks are `ixsl:updating="yes"` functions) — **never the legacy `ixsl:schedule-action`**. The editor UI is fully generated by the stylesheet — the overlay is rendered once at startup (hidden) and only populated/shown/hidden afterwards, so the stylesheet is self-contained and embeddable on any host page. + +Two build flavors: **core** (`src/index.xsl` → `dist/index.xsl.sef.json`, deployed to GitHub Pages — `deploy-pages.yml` excludes the LDH artifacts) and **LDH-extended** (`src/ldh-editor.xsl` → `dist/ldh-editor.xsl.sef.json`, used by `demo/index.html` and the browser fixtures — local only, its object blocks need the content-negotiating dev server). Modules under `src/`: -- **index.xsl** — entry point: `$vocab-hrefs` param, `main` template (async vocabulary prefetch via `ixsl:schedule-action/@document`, then overlay init), `local:document-uri()`. +- **index.xsl** — the core entry point: `main` template (fully synchronous — the host page preloads the vocabularies into the SaxonJS `documentPool` keyed by page-relative URI, see index.html), editor-state container init, `local:editor-state()`; the module include list. - **RDFa2RDFXML-v3.xsl** — RDFa 1.1 → RDF/XML extraction. **Pure XSLT, no `ixsl:`** — it runs headless via `xslt3` for the test suite. Strictly W3C-conformant (RDFa 1.1 processing rules, section 7.5, including chaining via typed resources and `rdfa:usesVocabulary`). Covers `@about`/`@typeof`/`@property`/`@content`/`@datatype`/`@resource`/`@href`/`@src`/`@prefix` (and `xmlns:*`)/`@vocab` with bare terms, `@lang`+`@xml:lang` inheritance, base-URI resolution (`about=""` = the document, `` honored), and exclusion of `head`/`script`/`style`/`[data-role='rendering']` subtrees. Out of scope (documented future work): `@rel`/`@rev`, `@inlist`, safe CURIEs, `@datetime`/`