Skip to content

Commit 8476cd2

Browse files
namedgraphclaude
andauthored
Replace WYMEditor with the RDFa editor for XMLLiteral editing (#336)
* Replace WYMEditor with the RDFa editor for XMLLiteral editing - vendor the RDFa editor XSLT modules under xsl/rdfa-editor/ (synced from the RDFa-Editor repo) and import them from client.xsl - render XMLLiteral form controls as editable div.rdfa-editor-content regions with hidden ol/lt inputs (imports/default.xsl) - create the editor state container in the client main template; full chrome bring-up on the first region, per-region init afterwards via the upstream local:init-editor/local:init-region seams (form.xsl) - serialize canonicalized editor content into the ol input in ldh:FormPreSubmit - run the ldh:FormPreSubmit pass before ldh:parse-rdf-post in the block POST and generic row-form submit handlers (previously the param defaults parsed the inputs before the pass could sync them, dropping the empty ol and tripping the ldh:XHTML MissingValue constraint) and canonicalize XMLLiterals in the request body (block.xsl, form.xsl) - chain body onmousemove to the editor's sweep-selection tracker which it shadowed by import precedence (navigation.xsl) - host the singleton toolbar in a per-document editor-bar below the action bar (document.xsl slot + local:toolbar-host override); sticky, matching action-bar chrome, hidden while no editable region is open along with the editor breadcrumb footer (bootstrap.css) - drop the WYMEditor assets from layout.xsl; load rdfa-editor.css under the same conditions instead Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix RDFa editor-bar visual alignment - Move border to action-bar bottom (border-top on editor-bar was hidden under action-bar's higher z-index) - Flex-center editor-bar content (Bootstrap navbar-inner has min-height: 50px with no vertical centering) - Fix select vertical alignment via auto margins (Firefox ignores align-items: center on native select) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add click-to-edit and autosave for XHTML blocks - Click anywhere on .main content to enter edit mode (skips if text selected) - Autosave XMLLiteral on focusout unless focus moved to toolbar/editor UI - Hide .btn-edit on XHTML blocks (entry point is now content click) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Suppress form-actions for XHTML blocks and exit edit mode on column click - bs2:RowForm gains $show-form-actions param (default true); XHTML blocks pass false via xsl:next-match, omitting the Save/Reset/Cancel buttons since autosave-on-blur already handles submission - ixsl:onclick on XHTML blocks in edit mode submits the form when the click target is outside the editor canvas; interactive elements are excluded (they steal focus, triggering focusout + autosave instead) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Override RDFa editor annotation typeahead and dialog with LDH's Bootstrap UI Intercepts local:typeahead-field, local:typeahead-set-value, local:typeahead-value, and local:render-overlay in form.xsl (which has higher import precedence than the vendored rdfa-editor/ stylesheets) to replace the upstream's doc()-on-vocabs typeahead with LDH's /ns-querying bs2:Lookup widget and to re-style the annotation dialog using Bootstrap 2.3.2 form classes (.well, .form-horizontal, .control-group, .btn). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Refine RDFa editor LDH integration: CSS split, overlay id, modal structure, fieldset fix - Remove host-UI sections (overlay + toolbar) from vendored rdfa-editor.css; host styles now live only in bootstrap.css - Replace !important overlay overrides in bootstrap.css with clean rules scoped to #rdfa-editor-overlay; add full #edit-toolbar layout rules - Parameterize overlay element id via $local:overlay-id in vendored overlay.xsl (matches upstream feature/ldh-integration-seams) - Restructure RDFa Annotation dialog to follow LDH modal convention: div.modal > div.modal-header + div.modal-body; add label @for attributes - Suppress fieldset border inside XHTML block edit form to avoid spurious outline around div.main in edit mode - Mention in-place RDFa editing in README Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Extract .edit-dialog styles from vendored rdfa-editor.css; add Bootstrap overrides Follows upstream feature/ldh-integration-seams: .edit-dialog host-UI rules (border, border-radius, box-shadow, label/input sizing, action-buttons, checkbox-label) removed from rdfa-editor.css; Bootstrap-compatible replacements added to bootstrap.css so toolbar dialogs (insert link, table, figure) inherit the host UI without Material-blue borders or Roboto sizing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Override toolbar dialog templates in form.xsl with Bootstrap-compatible HTML Add LDH-layer overrides for all five rdfa-editor named dialog templates (local:render-table-dialog, local:render-link-dialog, local:render-figure-dialog, local:render-find-dialog, local:render-extra-dialogs). Each override preserves the upstream element ids, name attributes, and semantic button classes that the event handlers depend on, while replacing btn-primary/btn-secondary with Bootstrap's btn btn-primary / btn / btn btn-danger, adding label @for attributes, and using Bootstrap's checkbox label pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Handle empty XHTML block in ldh:load-edited-resource When a block is referenced in the document container (rdf:_N) but has no own triples, key('resources', \$about) returns empty and the as="element()" type assertion crashes the promise chain. Synthesise a minimal rdf:Description from the block element's @typeof attribute so the edit form can open normally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Revert "Handle empty XHTML block in ldh:load-edited-resource" This reverts commit e6acae8. * Auto-focus first contenteditable block after editor init to trigger autosave When a new XHTML block is added via [ + XHTML ] and the user clicks away without entering the editor, ixsl:onfocusout never fires (focus was never in the region), so requestSubmit() is never called and the block is not persisted. Calling focus() on the first contenteditable block after local:init-region (or local:init-editor) ensures that any subsequent click outside the region triggers focusout → requestSubmit() → POST to server. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Forward caller params through the XHTML bs2:RowForm override Non-tunnel params do not survive xsl:next-match, so the override added for autosave (show-form-actions=false) dropped the ADD flow's method='post' along with about and show-cancel-button. The new-block form fell back to the base template's default method='patch', and the autosave PATCH's DELETE/INSERT/WHERE update matched zero solutions for a resource with no triples yet — a silent no-op. The block was never persisted, and re-editing it failed with an empty key('resources', ...) cardinality error. Re-declare the params with the base template's defaults and forward them, so new XHTML blocks are created via POST again (as they were in the WYMEditor era) and PATCH only ever targets existing blocks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Adopt the RDFa editor's w3id.org namespaces (rdfae:, rdfax:) Vendored editor stylesheets re-synced from RDFa-Editor after its urn: -> https://w3id.org/atomgraph/rdfa-editor# namespace switch; client.xsl, form.xsl and document.xsl updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 11d589d commit 8476cd2

30 files changed

Lines changed: 8882 additions & 66 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
/http-tests/out
1616
/fuseki
1717
.claude/scheduled_tasks.lock
18+
/cli/target

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ We are building LinkedDataHub primarily for:
1515

1616
What makes LinkedDataHub unique is its completely _data-driven architecture_: applications and documents are defined as data, managed using a single generic HTTP API and presented using declarative technologies. The default application structure and user interface are provided, but they can be completely overridden and customized. Unless a custom server-side processing is required, no imperative code such as Java or JavaScript needs to be involved at all.
1717

18+
XHTML documents can be edited in-place using a built-in RDFa-aware rich text editor — annotations link selected text directly to Knowledge Graph terms, embedding machine-readable RDF statements in the markup without leaving the page.
19+
1820
**Follow the [Get started](https://atomgraph.github.io/LinkedDataHub/linkeddatahub/docs/get-started/) guide to LinkedDataHub.** The setup and basic configuration sections are provided below and should get you running.
1921

2022
**LinkedDataHub is also available as a free AWS Marketplace product!** <a href="https://aws.amazon.com/marketplace/pp/prodview-vqbeztc3f2nni" target="_blank"><img src="https://github.com/AtomGraph/LinkedDataHub/raw/master/AWS%20Marketplace.svg" width="160" alt="AWS Marketplace"/></a>

src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ ul.dropdown-menu ul { margin: 0; }
4444
.action-bar #doc-controls { text-align: right; padding-top: 5px; }
4545
.action-bar #doc-controls .btn-edit { margin-top: -5px; margin-left: 10px; }
4646
.action-bar p.alert { margin-bottom: 0; }
47+
body:has(#edit-toolbar) .action-bar { border-bottom: 1px solid #aaa; }
4748
.nav-header.btn { color: inherit; }
4849
.btn.btn-primary.create-action { background-image: url('../icons/ic_note_add_white_24px.svg'); background-position: 12px center; background-repeat: no-repeat; padding-left: 40px; /* height: 30px; */ }
4950
.btn.create-action, a.create-action { background-image: url('../icons/ic_note_add_black_24px.svg'); background-position: 12px center; background-repeat: no-repeat; padding-left: 40px; /* height: 30px; */ }
@@ -152,6 +153,8 @@ h2.item-logo { background-image: url('../icons/file.svg'); background-position:
152153
.modal-footer { position: sticky; bottom: 0; background-color: white; z-index: 1060; }
153154
.modal-first-time-message { margin-left: 0; width: 80%; left: 10%; }
154155
.modal-first-time-message .hero-unit { margin-bottom: 0; }
156+
/* Annotation overlay */
157+
#rdfa-editor-overlay { position: absolute; min-width: 360px; max-width: 520px; z-index: 10001; }
155158
.control-group.endpoint-classes ul { max-height: 20em; overflow: auto; }
156159
.nav-tabs > li > a, .pager > li > a.active { cursor: pointer; }
157160
.pager > li.previous > a { text-align: right; font-size: 0; color: transparent; background-image: url('../icons/ic_navigate_before_black_24px.svg'); background-position: center center; background-repeat: no-repeat; width: 64px; height: 24px; }
@@ -180,8 +183,11 @@ button.add-typeahead { width: 219px; }
180183
.description { display: none; }
181184
.content .dl-horizontal { max-height: 35em; overflow: auto; }
182185
div[typeof="https://w3id.org/atomgraph/linkeddatahub#XHTML"] .main { font-size: larger; line-height: 25px; }
186+
div[typeof="https://w3id.org/atomgraph/linkeddatahub#XHTML"]:not(:has(form)) .main { cursor: pointer; }
187+
div[typeof="https://w3id.org/atomgraph/linkeddatahub#XHTML"] .btn-edit { display: none; }
183188
div[typeof="https://w3id.org/atomgraph/linkeddatahub#XHTML"] .form-horizontal .control-label { display: none; }
184189
div[typeof="https://w3id.org/atomgraph/linkeddatahub#XHTML"] .form-horizontal .controls { margin-left: 0; }
190+
div[typeof="https://w3id.org/atomgraph/linkeddatahub#XHTML"] form fieldset { border: none; }
185191
.span12.progress .row-block-controls { background-color: #e9ecef; }
186192
.span12.progress .bar { height: 20px; }
187193
/* .content .btn.add-typeahead { margin-top: -10px; } */
@@ -210,4 +216,18 @@ object { display: block; margin: auto; max-height: 400px; overflow: hidden; widt
210216
.ol-overlay-container { width: 60%; max-height: 75%; background-color: white; overflow: auto; }
211217
.ol-overlay-container img { max-width: 100%; }
212218
/* SVG graph specific */
213-
circle { cursor: move; }
219+
circle { cursor: move; }
220+
/* RDFa editor specific */
221+
.editor-bar { position: sticky; top: calc(var(--action-bar-top, 51px) + 50px); z-index: 998; background: #dfdfdf; padding: 0; box-shadow: none; display: flex; align-items: center; }
222+
#edit-toolbar { order: -1; margin-right: auto; display: flex; gap: 6px; align-items: center; }
223+
#edit-toolbar button, #edit-toolbar select { padding: 4px 8px; border: 1px solid #ccc; border-radius: 4px; background: white; font-size: 13px; font-family: inherit; cursor: pointer; margin-top: auto; margin-bottom: auto; }
224+
#edit-toolbar button:disabled { opacity: 0.4; cursor: default; }
225+
#edit-toolbar button:hover { background: #f5f5f5; }
226+
#edit-toolbar button[aria-pressed="true"] { background: #e3f0ff; border-color: #6aa3e0; color: #1a5fb4; }
227+
#edit-toolbar .tb-group { display: flex; gap: 6px; align-items: center; }
228+
#edit-toolbar .tb-group + .tb-group { border-left: 1px solid #e0e0e0; padding-left: 6px; }
229+
#edit-toolbar .tb-group.table-ops.active { background: #e3f0ff; border-radius: 4px; }
230+
.edit-dialog { background: white; border: 1px solid #ccc; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,.2); padding: 12px; min-width: 280px; z-index: 10000; }
231+
.edit-dialog .rdfa-editor-ui .action-buttons { margin-top: 10px; }
232+
.edit-dialog .rdfa-editor-ui .checkbox-label { display: inline-flex; gap: 6px; align-items: center; font-weight: 400; margin-top: 8px; }
233+
.editor-bar:not(:has(#edit-toolbar)), body:not(:has(.rdfa-editor-content)) .editor-bar, body:not(:has(.rdfa-editor-content)) #rdfa-editor-breadcrumb { display: none; }

0 commit comments

Comments
 (0)