@openpresentation/opf-editor 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -3
- package/dist/index.js +3 -1
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Embeddable local editor primitives for Open Presentation Format documents. The package turns traced `@openpresentation/opf-render` SVG output into JSON-path-aware edits, validates OPF after each change, and records undo/redo as JSON Patch operations.
|
|
4
4
|
|
|
5
|
+
Version 0.5.0 uses core 0.8.0 and renderer 0.6.0. `paginateSlide` records a one-page readability-policy change in undo history; repeating an unchanged result is a no-op. Quote preview uses accepted shared body/source geometry. The local example verifies source editing, pagination, export and reimport with PPTX 0.6.0; native reimport preserves quote text as editable blocks but loses its OPF quote structure, typography and readability policy.
|
|
6
|
+
|
|
5
7
|
## Scope
|
|
6
8
|
|
|
7
9
|
- Package: `@openpresentation/opf-editor`
|
|
@@ -14,7 +16,7 @@ Embeddable local editor primitives for Open Presentation Format documents. The p
|
|
|
14
16
|
- JSON Patch state transitions with inverse patches for undo/redo
|
|
15
17
|
- Optional DOM controls plus React and Svelte bindings in separate embeddable entry points
|
|
16
18
|
|
|
17
|
-
## Live browser canvas
|
|
19
|
+
## Live browser canvas
|
|
18
20
|
|
|
19
21
|
The new `@openpresentation/opf-editor/canvas` entry provides a framework-independent SVG canvas with inline text/table-cell editing, live validated drafts, undo/redo, cancellation, and structured property forms for charts, lists, metrics, quotes, code, timelines and images. Mount it in a DOM container:
|
|
20
22
|
|
|
@@ -32,7 +34,7 @@ await canvas.ready;
|
|
|
32
34
|
|
|
33
35
|
Load the same font bytes into the browser using `loadBrowserFontRegistry` from `@openpresentation/opf-render/fonts-browser` before mounting. The host owns font URLs, storage and collaboration. `onDraft` provides live document drafts; the session only changes on commit. Escape cancels. Concurrent edits to the selected payload cancel a stale draft.
|
|
34
36
|
|
|
35
|
-
These APIs were introduced in 0.1.0. Version 0.
|
|
37
|
+
These APIs were introduced in 0.1.0. Version 0.5.0 requires core 0.8.0 and renderer 0.6.0 for the canvas, including shared quote geometry, styled/merged cells, rich table values, headers and content-aware row heights. See the OPF repository’s `docs/live-editor.md` for setup, the support matrix and roadmap. `pnpm pack:ecosystem` in that repository also prepares local preview tarballs for coordinated development.
|
|
36
38
|
|
|
37
39
|
The canvas retains canonical SVG glyphs while a transparent native input supplies the caret. Advanced shaping, freeform object positioning, all chart/media treatments, and cross-engine pixel identity remain work in progress. The Source dialog in the playground now provides a live JSON preview; changes are validated before committing.
|
|
38
40
|
|
|
@@ -193,7 +195,11 @@ The browser-safe `/transfer` export provides `parseOpfTransfer`, `serializeOpfTr
|
|
|
193
195
|
|
|
194
196
|
The `/galleries` export provides `loadOpfGallery` and `loadOpfGalleryItem`, accepting an AbortSignal and injectable fetch. Registries use `{name, items:[{id, name, category, opf}]}` for inline documents or `opfUrl` for a relative JSON URL. Public PPTX.gallery registry descriptors are supported. Cross-origin endpoints need CORS; requests omit credentials/referrers, cap responses at 20 MB, and keep automatic item requests on the configured gallery origin. Documents should include inline catalog records; arbitrary external catalog sources are not automatically fetched.
|
|
195
197
|
|
|
196
|
-
The playground includes Copy OPF and
|
|
198
|
+
The playground includes Copy OPF and Import dialogs with paste, file/drop, gallery search, and URL tabs. Files accept OPF JSON and PowerPoint `.pptx` up to 20 MB. PPTX conversion runs locally using `@openpresentation/opf-pptx`; review the converted preview and diagnostics before inserting slides or opening a presentation. Applying an import is one undoable edit. Custom registries persist in local storage; defaults are configured in `examples/galleries.json`. Copy permissions may require using the Select all fallback. Pasting within text fields keeps normal text editing. Cmd/Ctrl+Shift+C opens copying and Cmd/Ctrl+O opens file import.
|
|
199
|
+
|
|
200
|
+
The **PowerPoint** button commits the current canvas draft and prepares an editable `.pptx` download from that snapshot, using the preview's text measurements. Conversion diagnostics remain visible in the download dialog. Missing/remote images require an explicit host resolver or embedded data; export does not silently fetch them or omit them. Save OPF separately to retain the complete original source. Native fonts must be installed in PowerPoint; the download does not embed font binaries. Arbitrary native positions and unsupported PowerPoint features can change during reimport.
|
|
201
|
+
|
|
202
|
+
Run `npm ci`, `npm run build:playground`, then serve `artifacts/playground` with a local static server. This example uses the published core/render/PPTX packages and this checkout's editor source; it does not require an account, AI provider or paid service. `npm run test:playground` builds and executes a real browser flow (local Edge on Windows, installed Chromium in CI): author JSON, inline edit, export a native merged table, validate/reimport the actual downloaded file, undo/redo, save OPF and reject malformed input without changing the document. It is browser behavior evidence, not a claim of native PowerPoint raster equivalence.
|
|
197
203
|
|
|
198
204
|
Slide insertion does not merge root speakers, organizations, or narrative metadata. Use Open as a presentation for the full source document. Some gallery presets contain minimal examples. The root OPF workspace's `docs/live-editor.md` documents the complete demo and npm API workflow.
|
|
199
205
|
|
|
@@ -224,3 +230,11 @@ The canvas can show draggable, keyboard-accessible dividers for root and nested
|
|
|
224
230
|
Arrange mode also shows numbered block handles. Drag to reorder siblings, use arrow keys for earlier/later, or click a handle to choose an existing destination group/slide and insertion position. The move preserves the whole block, including rich text, table/chart data, and nested groups. Each move is validated, preflighted by the renderer, and undoable. Parent weights stay with layout positions; moves that leave an empty container or create a containment cycle are rejected.
|
|
225
231
|
|
|
226
232
|
Agents can import `prepareBlockMove` and `listBlockContainers` from `@openpresentation/opf-editor/layout`. The prepared result includes a full candidate document, guarded atomic patches, the new block path, and a changed flag. Destination indexes refer to the pre-removal document. Use `canvas.openBlockMenu(path)` for the corresponding browser controls.
|
|
233
|
+
|
|
234
|
+
## Styled and merged table cells
|
|
235
|
+
|
|
236
|
+
Define cells with `{value, style, rowSpan, colSpan}` and place explicit `null` at covered positions. Inline editing follows the anchor's `.value` path, preserving its style and merge geometry. Double-click a value or focus it and press Enter to edit; the existing text-formatting controls support scalar promotion, rich runs and partial selection. Covered positions are not separate editable targets.
|
|
237
|
+
|
|
238
|
+
The core schema rejects overlapping/out-of-bounds spans and hidden content. Model patches can change a span and remove a row atomically; undo restores the complete operation. Styling or restructuring a table remains available through JSON/model edits and the existing structured property forms.
|
|
239
|
+
|
|
240
|
+
`test/styled-table.mjs` covers model behavior. The core repository's `scripts/build-rich-table-browser.mjs` builds both rich and styled browser fixtures. Browser verification uses actual loaded Roboto fonts and covers merged typing, scalar formatting, partial selection, empty values, cancellation and undo. Native PowerPoint appearance is a separate converter verification boundary.
|
package/dist/index.js
CHANGED
|
@@ -244,7 +244,9 @@ export function createEditorSession(input, options = {}) {
|
|
|
244
244
|
paginateSlide(slideIndex, options = {}, meta = {}) {
|
|
245
245
|
const resolved = resolveCompositionOptions(document, slideIndex, options);
|
|
246
246
|
const pagination = paginateSlide(document.slides[slideIndex], { ...resolved, reservedIds: document.slides.map(slide => slide.id).filter(Boolean) });
|
|
247
|
-
|
|
247
|
+
// Pagination can persist a readability policy without adding a page. Commit
|
|
248
|
+
// that change too, so preview/export use the same minimum that was evaluated.
|
|
249
|
+
if (pagination.slides.length === 1 && jsonEqual(pagination.slides[0], document.slides[slideIndex])) return { change: null, pagination };
|
|
248
250
|
const slides = [...document.slides];
|
|
249
251
|
slides.splice(slideIndex, 1, ...pagination.slides);
|
|
250
252
|
const change = editor.set('slides', slides, { ...meta, rejectInvalid: true, pagination: pagination.pages });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpresentation/opf-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Embeddable local OPF editor primitives built on the deterministic renderer.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -75,16 +75,19 @@
|
|
|
75
75
|
"sideEffects": false,
|
|
76
76
|
"scripts": {
|
|
77
77
|
"build": "node scripts/build.mjs",
|
|
78
|
-
"typecheck": "node --check src/index.js && node --check src/react.js && node --check src/svelte.js && node --check scripts/build.mjs && node --check scripts/validate-package.mjs && node --check test/smoke.mjs && node --check test/component-smoke.mjs && node --check src/canvas.js && node --check src/canvas-fields.js && node --check test/canvas-fields.mjs && node --check test/browser-canvas.mjs && node --check src/transfer.js && node --check src/galleries.js && node --check examples/transfer-controls.js && node --check src/schema.js && node --check src/schema-inspector.js && node --check test/rich-table-browser.mjs",
|
|
79
|
-
"test": "npm run build && node test/smoke.mjs && node test/component-smoke.mjs && node test/canvas-fields.mjs && node test/transfer.mjs && node test/schema.mjs && node test/rich-text.mjs && node test/layout.mjs && node test/blocks.mjs",
|
|
78
|
+
"typecheck": "node --check src/index.js && node --check src/react.js && node --check src/svelte.js && node --check scripts/build.mjs && node --check scripts/validate-package.mjs && node --check test/smoke.mjs && node --check test/component-smoke.mjs && node --check src/canvas.js && node --check src/canvas-fields.js && node --check test/canvas-fields.mjs && node --check test/browser-canvas.mjs && node --check src/transfer.js && node --check src/galleries.js && node --check examples/transfer-controls.js && node --check src/schema.js && node --check src/schema-inspector.js && node --check test/rich-table-browser.mjs && node --check test/styled-table.mjs && node --check test/styled-table-browser.mjs && node --check examples/pptx-controls.js && node --check scripts/build-playground.mjs && node --check test/playground-pptx.mjs",
|
|
79
|
+
"test": "npm run build && node test/smoke.mjs && node test/component-smoke.mjs && node test/canvas-fields.mjs && node test/transfer.mjs && node test/schema.mjs && node test/rich-text.mjs && node test/layout.mjs && node test/blocks.mjs && node test/styled-table.mjs",
|
|
80
80
|
"validate": "node scripts/validate-package.mjs",
|
|
81
|
-
"
|
|
81
|
+
"test:packed": "node test/packed-install.mjs",
|
|
82
|
+
"prepack": "npm run build",
|
|
83
|
+
"build:playground": "node scripts/build-playground.mjs",
|
|
84
|
+
"test:playground": "npm run build:playground && node test/playground-pptx.mjs"
|
|
82
85
|
},
|
|
83
86
|
"dependencies": {
|
|
84
|
-
"@openpresentation/opf": "^0.
|
|
87
|
+
"@openpresentation/opf": "^0.8.0"
|
|
85
88
|
},
|
|
86
89
|
"peerDependencies": {
|
|
87
|
-
"@openpresentation/opf-render": "^0.
|
|
90
|
+
"@openpresentation/opf-render": "^0.6.0"
|
|
88
91
|
},
|
|
89
92
|
"peerDependenciesMeta": {
|
|
90
93
|
"@openpresentation/opf-render": {
|
|
@@ -92,6 +95,9 @@
|
|
|
92
95
|
}
|
|
93
96
|
},
|
|
94
97
|
"devDependencies": {
|
|
95
|
-
"@openpresentation/opf-
|
|
98
|
+
"@openpresentation/opf-pptx": "0.6.0",
|
|
99
|
+
"@openpresentation/opf-render": "0.6.0",
|
|
100
|
+
"esbuild": "0.28.2",
|
|
101
|
+
"playwright": "1.63.0"
|
|
96
102
|
}
|
|
97
103
|
}
|