@openpresentation/opf-editor 0.25.3 → 0.26.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 CHANGED
@@ -9,7 +9,7 @@ Unfinished prepared shaping work is preserved in the [September 15 roadmap](docs
9
9
  | You use | Also install |
10
10
  | --- | --- |
11
11
  | The canvas, the preview, SVG downloads in a browser (the host serves its own font files) | nothing |
12
- | `loadFonts` from `/fonts-node` (a server, a test, a build script such as `npm run build:playground`) | the font packages of the pack: `@expo-google-fonts/roboto` and `roboto-mono` for `base`; also `arimo`, `caladea`, `cousine`, `gelasio`, `tinos` and `noto-sans` for `office`; a script face (`scripts: 'auto'`) needs its `@expo-google-fonts/noto-*` package. A missing one fails with `font-resource-unavailable` and names it |
12
+ | `loadFonts` from `/fonts-node` (a server, a test, a build script such as `pnpm run build:playground`) | the font packages of the pack: `@expo-google-fonts/roboto` and `roboto-mono` for `base`; also `arimo`, `caladea`, `cousine`, `gelasio`, `tinos` and `noto-sans` for `office`; a script face (`scripts: 'auto'`) needs its `@expo-google-fonts/noto-*` package. A missing one fails with `font-resource-unavailable` and names it |
13
13
  | `toPng` / `toPdf` from the Node entries (`/png`, `/pdf`) | `@resvg/resvg-js` (and `sharp`, `pdf-lib` as the renderer's README says); a missing one fails with `converter-missing` |
14
14
  | `convert` PDF (vector), PNG, SVG | nothing: the browser entry `@openpresentation/opf-render/export-browser` imports no converter |
15
15
  | `convert` raster PDF (`raster: true`) | `pdf-lib`, imported by the page and passed as the `pdfLib` option (`import * as pdfLib from "pdf-lib"`); without it the conversion rejects with `converter-missing` |
@@ -82,7 +82,7 @@ Click a categorical property/value or press `Ctrl+Space`, `Cmd+Space` or `Alt+Do
82
82
 
83
83
  In OPF 0.19, layout choices change only the template reference and preserve authored content. Empty regions remain available for explicit insertion; choosing a template does not invent blank payloads. The JSON field menu groups templates by intent and describes their supported regions. Hosts apply `replaceFieldOption` or `fieldOptionEdit(context, value)` as one undoable edit and check that `context.source` is still current.
84
84
 
85
- Run `npm run test:json` and `npm run test:json-browser` for the focused model and offline browser checks. The browser runner also accepts a report path followed by a clean installed consumer directory. These checks cover the JSON control; renderer, native PowerPoint and production adoption remain separate acceptance steps.
85
+ Run `pnpm run test:json` and `pnpm run test:json-browser` for the focused model and offline browser checks. The browser runner also accepts a report path followed by a clean installed consumer directory. These checks cover the JSON control; renderer, native PowerPoint and production adoption remain separate acceptance steps.
86
86
 
87
87
  Version 0.7.0 uses core 0.10.0 and renderer 0.8.0. Code source/metadata edits preserve line endings, literal tabs and cancellation/undo through accepted trace targets. Committed preview uses shared quote/code geometry; the active source textarea uses native browser editing. `paginateSlide` records a one-page readability-policy change in undo history, and an unchanged repeat is a no-op. Coordinated examples use PPTX 0.8.0 for exact code source/metadata recovery. Native formatting, font theme and geometry are not restored; quotes still import as editable text blocks with structure and readability-policy loss.
88
88
 
@@ -122,7 +122,7 @@ Methods: `replaceDocument(document, { source?, format?, name?, meta? })` (below)
122
122
  - **Styles.** `src/styles/source-pane.css` uses only `--opf-ui-*` tokens under the `opf-source-` prefix. It ships in the editor's `styles.css` (`@openpresentation/opf-editor/styles.css`), which also defines the tokens.
123
123
  - **Dependency.** `@codemirror/lang-yaml` (MIT) highlights YAML; Markdown uses a small stream tokenizer built on `@codemirror/language`, so no Markdown, HTML, CSS or JavaScript grammar is added.
124
124
 
125
- Icons are inline paths from [Lucide](https://lucide.dev) (ISC license). The harness is `examples/source-pane.html` (built by `npm run build:playground`); `npm run test:source-pane-browser` drives it.
125
+ Icons are inline paths from [Lucide](https://lucide.dev) (ISC license). The harness is `examples/source-pane.html` (built by `pnpm run build:playground`); `pnpm run test:source-pane-browser` drives it.
126
126
 
127
127
  ## Layout editor (RR-99)
128
128
 
@@ -183,12 +183,12 @@ createLayoutInspector(inspectorHost, { model });
183
183
 
184
184
  **Keyboard:** arrows move between siblings, Enter goes into a split and Esc goes up; `[` and `]` move a region earlier or later (at the end of a split it leaves the split); Shift with a bracket moves it into the neighboring split; Cmd or Ctrl+D duplicates; Delete deletes. A divider is `role="separator"` with `aria-valuenow` (the first side's share of the pair, in percent) and `aria-valuetext` ("2 : 1"); Arrow keys resize it by half a share (Shift: one), Enter makes the sides equal. The layers panel is `role="tree"` (Up and Down, Right to open or enter, Left to close or go to the parent, Home, End, F2). Every action is also a button in the inspector. Touch density makes controls 40px and the divider hit area wider; below 760px the palette is a row above the canvas and Layers and Inspector are tabs under it.
185
185
 
186
- The headless operations the editor runs are in `@openpresentation/opf-editor/layout-tree` (`splitRegion`, `wrapNodes`, `unwrapNode`, `moveNodes`, `deleteNodes`, `duplicateNodes`, `resizeSizes`, `layoutBoxes` and more): pure functions that return a new record and the paths to select, or throw a `LayoutOperationError` with the reason, and keep a core-valid record core-valid. `npm run test:layout-editor-browser` drives `examples/layout-editor.html` (built by `npm run build:playground`); the playground's Layouts view mounts the same editor on the presentation's custom layouts. Icons are inline paths from [Lucide](https://lucide.dev) (ISC license).
186
+ The headless operations the editor runs are in `@openpresentation/opf-editor/layout-tree` (`splitRegion`, `wrapNodes`, `unwrapNode`, `moveNodes`, `deleteNodes`, `duplicateNodes`, `resizeSizes`, `layoutBoxes` and more): pure functions that return a new record and the paths to select, or throw a `LayoutOperationError` with the reason, and keep a core-valid record core-valid. `pnpm run test:layout-editor-browser` drives `examples/layout-editor.html` (built by `pnpm run build:playground`); the playground's Layouts view mounts the same editor on the presentation's custom layouts. Icons are inline paths from [Lucide](https://lucide.dev) (ISC license).
187
187
 
188
188
  ## Scope
189
189
 
190
190
  - Package: `@openpresentation/opf-editor`
191
- - Repository: `OpenPresentation/opf-editor`
191
+ - Repository: `OpenPresentation/opf` (`packages/editor`)
192
192
  - License: MIT
193
193
  - Compatibility target: `@openpresentation/opf`
194
194
  - Renderer relationship: built on `@openpresentation/opf-render` trace output
@@ -225,7 +225,7 @@ await canvas.ready;
225
225
  // canvas.destroy() when unmounting.
226
226
  ```
227
227
 
228
- Load the same font bytes into the browser with `loadFonts` from `@openpresentation/opf-render/fonts-browser` before mounting; the handle it returns is the one `fonts` option of the canvas, `convert` (`/export`), `editor.composeSlide` and `editor.paginateSlide`. The host owns font URLs, storage and collaboration. For non-Latin documents, pass the pinned script pack's location as `scriptBaseUrl` and the canvas calls `fonts.ensure(presentation)` after edits (`scripts: 'auto'`, FF-19): only the faces for the scripts a document draws are fetched, once, hash-verified, for example Noto Sans JP for Japanese; a Latin-only document fetches none. The playground does this from `./script-fonts/`, which `npm run build:playground` fills with the pinned faces. `onDraft` provides live document drafts; the session only changes on commit. Escape cancels. Concurrent edits to the selected payload cancel a stale draft.
228
+ Load the same font bytes into the browser with `loadFonts` from `@openpresentation/opf-render/fonts-browser` before mounting; the handle it returns is the one `fonts` option of the canvas, `convert` (`/export`), `editor.composeSlide` and `editor.paginateSlide`. The host owns font URLs, storage and collaboration. For non-Latin documents, pass the pinned script pack's location as `scriptBaseUrl` and the canvas calls `fonts.ensure(presentation)` after edits (`scripts: 'auto'`, FF-19): only the faces for the scripts a document draws are fetched, once, hash-verified, for example Noto Sans JP for Japanese; a Latin-only document fetches none. The playground does this from `./script-fonts/`, which `pnpm run build:playground` fills with the pinned faces. `onDraft` provides live document drafts; the session only changes on commit. Escape cancels. Concurrent edits to the selected payload cancel a stale draft.
229
229
 
230
230
  Fonts load before pixels (FF-41). A document can need faces the browser has not loaded yet: script faces for the languages it draws and vendored preview faces for the font families it resolves (Intos for Aptos, Open Sans, Barlow). The handle knows what is missing (`fonts.pending(presentation)`) and loads it (`await fonts.ensure(presentation)`), so the canvas needs no separate gate: with the handle as `fonts` it never renders such a document early: on every path (editor changes, undo and redo, imports, dimension switches, slide changes, in-progress edits) it shows "Loading fonts…", loads the faces and then renders. A load that fails is reported through `onFonts`/`onError` and offers a retry button; nothing retries by itself, and the failed document is not drawn.
231
231
 
@@ -291,11 +291,12 @@ The package runtime must stay local and deterministic:
291
291
  ## Development
292
292
 
293
293
  ```sh
294
- npm ci
295
- npm run build
296
- npm run typecheck
297
- npm test
298
- npm run validate
294
+ pnpm install --frozen-lockfile # from the repository root (the OPF monorepo)
295
+ pnpm run build:deps # gallery and core, which the editor build and tests import
296
+ pnpm run build
297
+ pnpm run typecheck
298
+ pnpm test
299
+ pnpm run validate
299
300
  ```
300
301
 
301
302
  ## Headless Editing
@@ -672,7 +673,7 @@ useEffect(() => {
672
673
 
673
674
  The playground mounts both panels (the Design tab, and the selection area of the Content tab). One click on text still enters text editing; the panels follow the selection after Escape. Every image field (organization logo, watermark, background image and header/footer zone image) takes an asset reference (suggested from the document's assets), a web address or a data address, and has a file picker and an alt-text field: the chosen file is validated (PNG, JPEG, GIF, WebP or SVG, up to `maxImageBytes`, 2 MiB by default), added to `assets` and used in one undo step, or handed to your app through `onAddAsset`. Alt text is saved on the asset; typed before an upload it is used for that upload.
674
675
 
675
- Run `npm run test:design-controls-browser` (after `npm run build:playground`) for the real-browser check of every control, its keyboard operation and its undo.
676
+ Run `pnpm run test:design-controls-browser` (after `pnpm run build:playground`) for the real-browser check of every control, its keyboard operation and its undo.
676
677
 
677
678
  ### What a switch does not establish
678
679
 
@@ -750,7 +751,7 @@ The editor panels ship one stylesheet. Import it once, next to your own CSS:
750
751
  import "@openpresentation/opf-editor/styles.css";
751
752
  ```
752
753
 
753
- `npm run build` writes `dist/styles.css`: the token layer (`src/styles/tokens.css`) first, then every other `src/styles/*.css` in alphabetical order. It is plain CSS with no preprocessor, no `@import` and no `url()`: nothing is fetched. The package bundles no fonts either; load Inter and Geist Mono yourself (or leave the fallbacks: `system-ui` and `ui-monospace`). The panels that existed before it (design controls, review, slide manager, find, fill template, numbering, chart options, data grid, crop, the custom layout editor, the JSON editor and the restore banner) are styled with the tokens and nothing else. The find, review, crop and data-grid components still inject a small fallback stylesheet of their own, so they look as before when you do not import `styles.css`; with it, its rules win whichever `<style>` comes last.
754
+ `pnpm run build` writes `dist/styles.css`: the token layer (`src/styles/tokens.css`) first, then every other `src/styles/*.css` in alphabetical order. It is plain CSS with no preprocessor, no `@import` and no `url()`: nothing is fetched. The package bundles no fonts either; load Inter and Geist Mono yourself (or leave the fallbacks: `system-ui` and `ui-monospace`). The panels that existed before it (design controls, review, slide manager, find, fill template, numbering, chart options, data grid, crop, the custom layout editor, the JSON editor and the restore banner) are styled with the tokens and nothing else. The find, review, crop and data-grid components still inject a small fallback stylesheet of their own, so they look as before when you do not import `styles.css`; with it, its rules win whichever `<style>` comes last.
754
755
 
755
756
  **Tokens.** Every rule reads only `--opf-ui-*` custom properties, defined on `:root` and on `.opf-ui`, light by default. Override any of them on `:root`, on a wrapper with the class `opf-ui`, or on one component's container:
756
757
 
@@ -837,7 +838,7 @@ const { files, findings } = await convert(editor.presentation, {
837
838
  });
838
839
  ```
839
840
 
840
- `convert` reads `fonts.subsets` and `fonts.outlines` from that handle, so nothing else changes: the same call writes SVG files with the faces cut to what each slide draws (the licence rule above still decides which faces may be embedded, and the renderer cuts only faces whose licence allows a modified version; the others stay whole) and, with `renderOptions: { text: "paths" }`, SVG and PNG files whose text is glyph outlines (no font needed). A PDF is unaffected: it embeds the registry's faces and cuts its own subsets, and it always draws selectable text. `renderOptions.subsetFonts: false` embeds whole faces. The canvas draws with `text: "system"`, which embeds nothing, so it never reads either. The playground does this: `npm run build:playground` copies both files next to the page.
841
+ `convert` reads `fonts.subsets` and `fonts.outlines` from that handle, so nothing else changes: the same call writes SVG files with the faces cut to what each slide draws (the licence rule above still decides which faces may be embedded, and the renderer cuts only faces whose licence allows a modified version; the others stay whole) and, with `renderOptions: { text: "paths" }`, SVG and PNG files whose text is glyph outlines (no font needed). A PDF is unaffected: it embeds the registry's faces and cuts its own subsets, and it always draws selectable text. `renderOptions.subsetFonts: false` embeds whole faces. The canvas draws with `text: "system"`, which embeds nothing, so it never reads either. The playground does this: `pnpm run build:playground` copies both files next to the page.
841
842
  - **Fonts.** The fonts handle loads the faces the deck needs before anything is drawn (a failure rejects with `fonts-unavailable`). Only faces the handle's registry holds are embedded (bundled or hash-pinned, never a system font), only where a slide draws them, as `@font-face` data in each SVG and as subsets in the PDF. A face whose own license text is not OFL, Apache, MIT or UFL is left out and reported (`fonts/export-font-license`).
842
843
  - **PDF** is the renderer's vector PDF (selectable text, vector shapes, embedded subsets, tagged structure), `raster: true` is the image-only form. **PNG** is drawn on a canvas from the same SVG (within anti-aliasing of the renderer's resvg PNG) and is limited to 40 megapixels. **SVG** files are standalone (XML header, fonts embedded, no external references).
843
844
  - **Files.** A PDF is one file (`pages`, and the one-based `slides` it shows). PNG and SVG give one file per slide, in slide order, each with its one-based `slide`, its `id` and its `width` and `height` in pixels, as core's `convert` does; with `zip: true` they are one archive (`createZip`, no dependency; `entries` names the files in it), even for one slide. `zip` with a PDF, or `raster` with PNG or SVG, rejects with `invalid-option`.
@@ -927,7 +928,7 @@ bindPresentShortcut(document, () => presenter.start(current)); // F5
927
928
 
928
929
  `createPresentButton(container, { onPresent, disabled, density, variant })` mounts an icon-only button (the Lucide Presentation icon, inlined) named "Present" (`aria-label`), titled "Present (F5)". `variant` is `"quiet"` (the default: a transparent icon in `--opf-ui-muted-fg` that turns `--opf-ui-fg` on `--opf-ui-muted` on hover, like the toolbar's undo and redo, so a lone icon beside a primary Export does not compete with it) or `"primary"` (the filled accent look of the Export menu's trigger). `disabled` is `true` or a reason string (the title); the button stays focusable (`aria-disabled`) and does nothing. It returns `{ element, setDisabled(reason), setDensity(density), setVariant(variant), destroy() }`. `bindPresentShortcut(target, onPresent)` binds F5 (and prevents the browser's reload); it ignores F5 while typing in inputs, selects and editors (CodeMirror, contenteditable), in menus and dialogs, and with a modifier key, and returns a function that removes the listener. `examples/playground.js` wires all three next to the Export menu.
929
930
 
930
- Tests: `npm run test:presenter-browser` and `npm run test:present-button-browser`.
931
+ Tests: `pnpm run test:presenter-browser` and `pnpm run test:present-button-browser`.
931
932
 
932
933
  ## Opening a deck file (RR-98)
933
934
 
@@ -992,17 +993,17 @@ Svelte bindings are isolated under `@openpresentation/opf-editor/svelte` as acti
992
993
 
993
994
  ## Release Lane
994
995
 
995
- Public npm package publication is handled by `.github/workflows/release.yml` through npm Trusted Publishing (GitHub Actions OIDC) with npm provenance; no npm token is stored. The owner authorized agents to prepare and publish npm releases whenever a release is required (2026-09-29). This authorization does not waive any gate.
996
+ The editor releases with the other five packages of the OPF monorepo at one version, through the repository's release workflow (npm Trusted Publishing from GitHub Actions OIDC, with npm provenance; no npm token is stored). The owner authorized agents to prepare and publish npm releases whenever a release is required (2026-09-29); this authorization does not waive any gate. The steps, the gates and the order are in the root `AGENTS.md` and `docs/release-process.md`. In short:
996
997
 
997
- 1. Open a release-prep PR containing only the version bump, `CHANGELOG.md` (assembled from `changes/` with `node scripts/changelog-fragments.mjs assemble --version X.Y.Z`), dependency ranges, lockfile and current-instruction docs. Publish in dependency order (core, then renderer, then PPTX, then editor): refresh this repo's lockfile only after the required `@openpresentation/opf`, `@openpresentation/opf-render` and `@openpresentation/opf-pptx` versions are on the registry (`npm install --package-lock-only`), then run `npm run test:packed` against them.
998
- 2. Merge after CI is green, then publish by pushing the git tag `opf-editor-v<version>` (or `@openpresentation/opf-editor@v<version>`) at the merge commit. The workflow verifies that the tag matches `package.json`, that the push-to-`main` run of `ci.yml` on exactly the tagged commit succeeded (`scripts/ci-evidence.mjs`; it fails closed and re-runs no test, RR-100), and the artifact itself (audit, the packed install, `npm pack --dry-run`) before `npm publish --access public --provenance`. A tag pushed while CI still runs fails at the evidence step; re-run the failed job once CI is green. A manual `workflow_dispatch` runs the same job without the tag check and is a fallback only.
999
- 3. Verify with `npm view @openpresentation/opf-editor@<version> version gitHead dist.attestations` and, from the core repo, `node scripts/test-editor-publication.mjs <version> <release-commit> <this-checkout>`. Never republish an existing version.
998
+ 1. A release-prep PR contains only the version bump (all six manifests), `CHANGELOG.md` files assembled from the root `changes/` fragments, dependency ranges, the lockfile and current-instruction docs.
999
+ 2. The release workflow rebuilds `dist/` from source (it is not tracked), runs the gates on the release commit and publishes with provenance. Never republish an existing version.
1000
+ 3. Verify with `npm view @openpresentation/opf-editor@<version> version gitHead dist.attestations`.
1000
1001
 
1001
1002
  ## Shared dynamic composition
1002
1003
 
1003
- The current checkout uses `@openpresentation/opf/composition` for portable geometry. Slides can select `auto`, `row`, `column`, or `grid`, set weighted tracks, and request path-specific overflow diagnostics. See the sibling OPF repo's `docs/dynamic-composition.md` for the complete contract.
1004
+ The current checkout uses `@openpresentation/opf/composition` for portable geometry. Slides can select `auto`, `row`, `column`, or `grid`, set weighted tracks, and request path-specific overflow diagnostics. See `docs/dynamic-composition.md` at the repository root for the complete contract.
1004
1005
 
1005
- The current editor requires core `^0.15.1`; canvas rendering uses the optional renderer peer `^0.15.0`, and playground PPTX import/export uses `@openpresentation/opf-pptx@^0.15.0`. Clean registry installs support composition without sibling checkouts. For coordinated source development, build OPF and run `node scripts/link-ecosystem.mjs` there; `pnpm test:ecosystem` verifies shared geometry and import/export behavior.
1006
+ The editor requires the core, renderer and PPTX converter of its own release (`workspace:^` in this repository, `^<version>` in the published package). In the workspace the packages link to each other, so `pnpm run test:contract` here checks shared geometry and import/export behavior against this checkout's sources.
1006
1007
 
1007
1008
  ## Local interactive demo
1008
1009
 
@@ -1027,7 +1028,7 @@ The playground includes Copy OPF and Import dialogs with paste, file/drop, galle
1027
1028
 
1028
1029
  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. Since 0.14, PPTX export names the font the user selected, so PowerPoint uses it when installed or available as a Microsoft 365 cloud font. The download does not embed font binaries, and license-restricted (proprietary) fonts are never embedded. Arbitrary native positions and unsupported PowerPoint features can change during reimport.
1029
1030
 
1030
- 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.
1031
+ Run `pnpm install` at the repository root, then `pnpm run build:deps` and `pnpm run build:playground` here, then serve `artifacts/playground` with a local static server. This example uses the workspace's core/render/PPTX packages and this checkout's editor source; it does not require an account, AI provider or paid service. `pnpm 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.
1031
1032
 
1032
1033
  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.
1033
1034
 
@@ -1047,7 +1048,7 @@ Select rendered rich text to format it, or click a rich text block to type (see
1047
1048
 
1048
1049
  Version 0.7.0: rich input maps the textarea's LF-normalized offsets back to the original source. Typing preserves untouched CRLF/CR endings and surrounding run metadata; newly inserted newlines use the first source line-ending style. The `updateRichTextInput` change offsets are native textarea offsets, while formatting and replacement helpers continue to use original source offsets.
1049
1050
 
1050
- Browser regression checks run with `npm run test:rich-input-browser -- artifacts/rich-input-browser.json measured` (or `estimated`). An optional consumer path after the mode selects an existing coordinated installed consumer; all browser runtime and font-preparation imports must then resolve inside that consumer. See [line-ending acceptance](docs/evidence/rich-input-line-endings-20260915/README.md) for scope and preserved failures.
1051
+ Browser regression checks run with `pnpm run test:rich-input-browser artifacts/rich-input-browser.json measured` (or `estimated`). An optional consumer path after the mode selects an existing coordinated installed consumer; all browser runtime and font-preparation imports must then resolve inside that consumer. See [line-ending acceptance](docs/evidence/rich-input-line-endings-20260915/README.md) for scope and preserved failures.
1051
1052
 
1052
1053
  Headless applications and agents can import `formatRichTextRange`, `replaceRichTextRange`, and `richTextContent` from `@openpresentation/opf-editor/rich-text`. The helpers preserve surrounding run metadata and accept UTF-16 offsets on whole grapheme boundaries. A null format value removes an override. Apply the returned value through the editor session or validate the resulting document before saving.
1053
1054
 
package/dist/index.d.ts CHANGED
@@ -16,7 +16,8 @@ export interface EditorDiagnosticOptions {
16
16
  export declare const packageName = "@openpresentation/opf-editor";
17
17
 
18
18
  export declare const releaseLane: Readonly<{
19
- githubRepository: "OpenPresentation/opf-editor";
19
+ githubRepository: "OpenPresentation/opf";
20
+ directory: "packages/editor";
20
21
  npmPackage: "@openpresentation/opf-editor";
21
22
  compatibilityPackage: "@openpresentation/opf";
22
23
  rendererPackage: "@openpresentation/opf-render";
package/dist/index.js CHANGED
@@ -45,7 +45,8 @@ function slideContext(presentation, slideIndex, catalogs, { fonts, catalogs: _ex
45
45
  export const packageName = "@openpresentation/opf-editor";
46
46
 
47
47
  export const releaseLane = Object.freeze({
48
- githubRepository: "OpenPresentation/opf-editor",
48
+ githubRepository: "OpenPresentation/opf",
49
+ directory: "packages/editor",
49
50
  npmPackage: "@openpresentation/opf-editor",
50
51
  compatibilityPackage: "@openpresentation/opf",
51
52
  rendererPackage: "@openpresentation/opf-render"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpresentation/opf-editor",
3
- "version": "0.25.3",
3
+ "version": "0.26.0",
4
4
  "description": "Embeddable local OPF editor primitives built on the deterministic renderer.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,12 +10,13 @@
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
13
- "url": "git+https://github.com/OpenPresentation/opf-editor.git"
13
+ "url": "git+https://github.com/OpenPresentation/opf.git",
14
+ "directory": "packages/editor"
14
15
  },
15
16
  "bugs": {
16
- "url": "https://github.com/OpenPresentation/opf-editor/issues"
17
+ "url": "https://github.com/OpenPresentation/opf/issues"
17
18
  },
18
- "homepage": "https://github.com/OpenPresentation/opf-editor#readme",
19
+ "homepage": "https://github.com/OpenPresentation/opf/tree/main/packages/editor#readme",
19
20
  "publishConfig": {
20
21
  "access": "public"
21
22
  },
@@ -269,52 +270,6 @@
269
270
  },
270
271
  "types": "./dist/index.d.ts",
271
272
  "sideEffects": false,
272
- "scripts": {
273
- "build": "node scripts/build.mjs",
274
- "typecheck": "node scripts/check-syntax.mjs src test scripts examples",
275
- "test": "npm run build && npm run check:font-hotlinks && node scripts/run-tests.mjs && npm run check:runners && npm run check:changes",
276
- "test:contract": "npm run build && node scripts/run-tests.mjs --suite contract",
277
- "check:runners": "node --test scripts/run-tests.test.mjs",
278
- "check:changes": "node --test scripts/changelog-fragments.test.mjs && node scripts/changelog-fragments.mjs check",
279
- "validate": "node scripts/validate-package.mjs",
280
- "test:packed": "node test/packed-install.mjs",
281
- "prepack": "npm run build",
282
- "check:font-hotlinks": "node --test scripts/check-font-hotlinks.test.mjs && node scripts/check-font-hotlinks.mjs",
283
- "check:font-hotlinks:built": "node scripts/check-font-hotlinks.mjs --built dist artifacts/playground",
284
- "build:playground": "node scripts/build-playground.mjs",
285
- "test:playground": "npm run build:playground && npm run check:font-hotlinks:built && node test/playground-pptx.mjs && node test/playground-script-fonts.mjs artifacts/playground-script-fonts && node test/playground-lazy-fonts.mjs artifacts/playground-lazy-fonts && node test/playground-base-fonts.mjs artifacts/playground-base-fonts && node test/playground-source.mjs && node test/design-controls-browser.mjs && node test/design-gaps-browser.mjs && node test/chart-options-browser.mjs && node test/persistence-browser.mjs && node test/slides-browser.mjs && node test/slide-navigator-browser.mjs && node test/layout-templates-browser.mjs && node test/layout-editor-browser.mjs && node test/template-panel-browser.mjs && node test/numbering-panel-browser.mjs && node test/playground-ensure-fonts.mjs artifacts/playground-ensure-fonts && node test/canvas-fonts-browser.mjs artifacts/canvas-fonts && node test/find-replace-browser.mjs && node test/image-crop-browser.mjs && node test/mobile-browser.mjs && node test/review-panel-browser.mjs && node test/review-hook-browser.mjs && node test/source-pane-browser.mjs && node test/playground-download.mjs artifacts/playground-download && node test/export-menu-browser.mjs && node test/agent-handoff-browser.mjs && node test/presenter-browser.mjs && node test/present-button-browser.mjs",
286
- "test:code-browser": "node test/code-browser.mjs",
287
- "test:selection-browser": "node test/selection-browser.mjs",
288
- "test:click-entry-browser": "node test/click-entry-browser.mjs",
289
- "test:canvas-a11y-browser": "node test/canvas-a11y-browser.mjs",
290
- "test:metric-browser": "node test/metric-browser.mjs",
291
- "test:rich-input-browser": "node test/rich-input-browser.mjs",
292
- "test:json": "npm run build && node test/json-source.mjs && node test/json-options.mjs",
293
- "test:json-browser": "node test/json-editor-browser.mjs",
294
- "test:design-controls-browser": "node test/design-controls-browser.mjs",
295
- "test:template-panel-browser": "node test/template-panel-browser.mjs",
296
- "test:design-gaps-browser": "node test/design-gaps-browser.mjs",
297
- "test:data-grid-browser": "node test/data-grid-browser.mjs",
298
- "test:data-grid-datasets-browser": "node test/data-grid-datasets-browser.mjs",
299
- "test:data-import-dataset-browser": "node test/data-import-dataset-browser.mjs",
300
- "test:slides-browser": "node test/slides-browser.mjs",
301
- "test:slide-navigator-browser": "node test/slide-navigator-browser.mjs",
302
- "test:persistence-browser": "node test/persistence-browser.mjs",
303
- "test:find-browser": "node test/find-replace-browser.mjs",
304
- "test:crop-browser": "node test/image-crop-browser.mjs",
305
- "test:mobile-browser": "node test/mobile-browser.mjs",
306
- "test:review-panel-browser": "node test/review-panel-browser.mjs",
307
- "test:review-hook-browser": "node test/review-hook-browser.mjs",
308
- "test:source-pane-browser": "node test/source-pane-browser.mjs",
309
- "test:layout-editor-browser": "node test/layout-editor-browser.mjs",
310
- "test:export-license-browser": "node test/export-license-browser.mjs",
311
- "test:chart-options-browser": "node test/chart-options-browser.mjs",
312
- "test:numbering-panel-browser": "node test/numbering-panel-browser.mjs",
313
- "test:presenter-browser": "node test/presenter-browser.mjs",
314
- "test:present-button-browser": "node test/present-button-browser.mjs",
315
- "test:export-menu-browser": "node test/export-menu-browser.mjs",
316
- "test:agent-handoff-browser": "node test/agent-handoff-browser.mjs"
317
- },
318
273
  "dependencies": {
319
274
  "@codemirror/autocomplete": "6.20.3",
320
275
  "@codemirror/commands": "6.11.1",
@@ -326,11 +281,11 @@
326
281
  "@codemirror/state": "6.7.6",
327
282
  "@codemirror/view": "6.43.14",
328
283
  "@lezer/highlight": "1.2.5",
329
- "@openpresentation/opf": "^0.25.0",
330
- "jsonc-parser": "3.3.1"
284
+ "jsonc-parser": "3.3.1",
285
+ "@openpresentation/opf": "^0.26.0"
331
286
  },
332
287
  "peerDependencies": {
333
- "@openpresentation/opf-render": "^0.25.0"
288
+ "@openpresentation/opf-render": "^0.26.0"
334
289
  },
335
290
  "peerDependenciesMeta": {
336
291
  "@openpresentation/opf-render": {
@@ -338,7 +293,6 @@
338
293
  }
339
294
  },
340
295
  "devDependencies": {
341
- "@openpresentation/gallery": "^5.0.0",
342
296
  "@expo-google-fonts/arimo": "0.4.3",
343
297
  "@expo-google-fonts/caladea": "0.4.2",
344
298
  "@expo-google-fonts/cousine": "0.4.3",
@@ -383,14 +337,60 @@
383
337
  "@expo-google-fonts/roboto-mono": "0.4.2",
384
338
  "@expo-google-fonts/stix-two-math": "0.4.0",
385
339
  "@expo-google-fonts/tinos": "0.4.2",
386
- "@openpresentation/opf-pptx": "^0.25.0",
387
- "@openpresentation/opf-render": "^0.25.0",
388
340
  "@resvg/resvg-js": "2.6.2",
389
341
  "axe-core": "4.14.0",
390
342
  "esbuild": "0.28.2",
391
343
  "jszip": "3.10.2",
392
344
  "pdf-lib": "1.17.1",
393
345
  "pdfjs-dist": "6.4.299",
394
- "playwright": "1.64.0"
395
- }
346
+ "playwright": "1.64.0",
347
+ "@openpresentation/gallery": "0.26.0",
348
+ "@openpresentation/opf-pptx": "0.26.0",
349
+ "@openpresentation/opf-render": "0.26.0"
350
+ },
351
+ "scripts": {
352
+ "build": "node scripts/build.mjs",
353
+ "build:deps": "pnpm --filter \"@openpresentation/opf-editor^...\" --fail-if-no-match run build",
354
+ "typecheck": "node scripts/check-syntax.mjs src test scripts examples",
355
+ "test": "pnpm run build:deps && pnpm run build && node ../../scripts/run-tests.mjs && pnpm run check:scripts",
356
+ "test:contract": "pnpm run build:deps && pnpm run build && node ../../scripts/run-tests.mjs --suite contract",
357
+ "validate": "node scripts/validate-package.mjs",
358
+ "check:scripts": "node --test scripts/check-syntax.test.mjs scripts/browser-suites.test.mjs",
359
+ "test:packed": "pnpm run build:deps && node test/packed-install.mjs",
360
+ "check:font-hotlinks:built": "node ../../scripts/check-font-hotlinks.mjs --built dist artifacts/playground",
361
+ "build:playground": "node scripts/build-playground.mjs",
362
+ "test:playground": "pnpm run build:deps && pnpm run build && pnpm run build:playground && pnpm run check:font-hotlinks:built && node test/playground-pptx.mjs && node test/playground-script-fonts.mjs artifacts/playground-script-fonts && node test/playground-lazy-fonts.mjs artifacts/playground-lazy-fonts && node test/playground-base-fonts.mjs artifacts/playground-base-fonts && node test/playground-source.mjs && node test/design-controls-browser.mjs && node test/design-gaps-browser.mjs && node test/chart-options-browser.mjs && node test/persistence-browser.mjs && node test/slides-browser.mjs && node test/slide-navigator-browser.mjs && node test/layout-templates-browser.mjs && node test/layout-editor-browser.mjs && node test/template-panel-browser.mjs && node test/numbering-panel-browser.mjs && node test/playground-ensure-fonts.mjs artifacts/playground-ensure-fonts && node test/canvas-fonts-browser.mjs artifacts/canvas-fonts && node test/find-replace-browser.mjs && node test/image-crop-browser.mjs && node test/mobile-browser.mjs && node test/review-panel-browser.mjs && node test/review-hook-browser.mjs && node test/source-pane-browser.mjs && node test/playground-download.mjs artifacts/playground-download && node test/export-menu-browser.mjs && node test/agent-handoff-browser.mjs && node test/presenter-browser.mjs && node test/present-button-browser.mjs",
363
+ "test:code-browser": "node test/code-browser.mjs",
364
+ "test:selection-browser": "node test/selection-browser.mjs",
365
+ "test:click-entry-browser": "node test/click-entry-browser.mjs",
366
+ "test:canvas-a11y-browser": "node test/canvas-a11y-browser.mjs",
367
+ "test:metric-browser": "node test/metric-browser.mjs",
368
+ "test:rich-input-browser": "node test/rich-input-browser.mjs",
369
+ "test:json": "pnpm run build:deps && pnpm run build && node test/json-source.mjs && node test/json-options.mjs",
370
+ "test:json-browser": "node test/json-editor-browser.mjs",
371
+ "test:design-controls-browser": "node test/design-controls-browser.mjs",
372
+ "test:template-panel-browser": "node test/template-panel-browser.mjs",
373
+ "test:design-gaps-browser": "node test/design-gaps-browser.mjs",
374
+ "test:data-grid-browser": "node test/data-grid-browser.mjs",
375
+ "test:data-grid-datasets-browser": "node test/data-grid-datasets-browser.mjs",
376
+ "test:data-import-dataset-browser": "node test/data-import-dataset-browser.mjs",
377
+ "test:slides-browser": "node test/slides-browser.mjs",
378
+ "test:slide-navigator-browser": "node test/slide-navigator-browser.mjs",
379
+ "test:persistence-browser": "node test/persistence-browser.mjs",
380
+ "test:find-browser": "node test/find-replace-browser.mjs",
381
+ "test:crop-browser": "node test/image-crop-browser.mjs",
382
+ "test:mobile-browser": "node test/mobile-browser.mjs",
383
+ "test:review-panel-browser": "node test/review-panel-browser.mjs",
384
+ "test:review-hook-browser": "node test/review-hook-browser.mjs",
385
+ "test:source-pane-browser": "node test/source-pane-browser.mjs",
386
+ "test:layout-editor-browser": "node test/layout-editor-browser.mjs",
387
+ "test:export-license-browser": "node test/export-license-browser.mjs",
388
+ "test:chart-options-browser": "node test/chart-options-browser.mjs",
389
+ "test:numbering-panel-browser": "node test/numbering-panel-browser.mjs",
390
+ "test:presenter-browser": "node test/presenter-browser.mjs",
391
+ "test:present-button-browser": "node test/present-button-browser.mjs",
392
+ "test:export-menu-browser": "node test/export-menu-browser.mjs",
393
+ "test:agent-handoff-browser": "node test/agent-handoff-browser.mjs"
394
+ },
395
+ "gitHead": "ae4ddd76e40b5778c1fdc255e4e3b24334748d7e"
396
396
  }