@openpresentation/opf-editor 0.27.0 → 0.29.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 +23 -9
- package/dist/canvas.d.ts +13 -1
- package/dist/canvas.js +39 -9
- package/dist/chart-options-panel.js +16 -16
- package/dist/codemirror-guard.js +69 -0
- package/dist/content-controls.js +127 -74
- package/dist/data-grid.js +15 -7
- package/dist/design-controls.d.ts +13 -0
- package/dist/design-controls.js +136 -125
- package/dist/design-options.js +1 -1
- package/dist/exact-source.d.ts +30 -0
- package/dist/font-gate.js +20 -1
- package/dist/json-editor.d.ts +33 -0
- package/dist/json-editor.js +91 -4
- package/dist/json-options.d.ts +2 -1
- package/dist/json-options.js +7 -6
- package/dist/layout-adapter.js +96 -0
- package/dist/layout-canvas.js +122 -232
- package/dist/layout-editor-ui.js +46 -185
- package/dist/layout-inspector.js +36 -99
- package/dist/layout-layers.js +75 -92
- package/dist/layout-model.js +62 -103
- package/dist/layout-templates.d.ts +8 -3
- package/dist/layout-templates.js +30 -16
- package/dist/numbering-panel.js +2 -3
- package/dist/react.d.ts +16 -4
- package/dist/react.js +47 -6
- package/dist/slide-adapter.d.ts +49 -0
- package/dist/slide-adapter.js +289 -0
- package/dist/slide-edits.d.ts +46 -0
- package/dist/slide-edits.js +629 -0
- package/dist/slide-manager.js +2 -1
- package/dist/slide-scene.d.ts +96 -0
- package/dist/slide-scene.js +413 -0
- package/dist/source-checker.js +45 -6
- package/dist/source-color-scheme.js +60 -0
- package/dist/source-completions.js +6 -4
- package/dist/source-pane.d.ts +103 -6
- package/dist/source-pane.js +196 -9
- package/dist/source-worker.js +8 -4
- package/dist/studio-canvas.d.ts +34 -0
- package/dist/studio-canvas.js +586 -0
- package/dist/studio-commands.d.ts +15 -0
- package/dist/studio-commands.js +155 -0
- package/dist/studio-design.d.ts +16 -0
- package/dist/studio-design.js +354 -0
- package/dist/studio-kit/commands.d.ts +38 -0
- package/dist/studio-kit/commands.js +148 -0
- package/dist/studio-kit/dom.d.ts +52 -0
- package/dist/studio-kit/dom.js +198 -0
- package/dist/studio-kit/drag.d.ts +26 -0
- package/dist/studio-kit/drag.js +127 -0
- package/dist/studio-kit/gesture.d.ts +29 -0
- package/dist/studio-kit/gesture.js +87 -0
- package/dist/studio-kit/index.d.ts +29 -0
- package/dist/studio-kit/index.js +12 -0
- package/dist/studio-kit/inspector.d.ts +22 -0
- package/dist/studio-kit/inspector.js +119 -0
- package/dist/studio-kit/overlay.d.ts +29 -0
- package/dist/studio-kit/overlay.js +182 -0
- package/dist/studio-kit/selection.d.ts +30 -0
- package/dist/studio-kit/selection.js +106 -0
- package/dist/studio-kit/tree.d.ts +9 -0
- package/dist/studio-kit/tree.js +82 -0
- package/dist/studio-kit/viewport.d.ts +29 -0
- package/dist/studio-kit/viewport.js +153 -0
- package/dist/studio-layers.d.ts +12 -0
- package/dist/studio-layers.js +218 -0
- package/dist/studio.d.ts +31 -0
- package/dist/studio.js +1608 -0
- package/dist/styles.css +1573 -123
- package/dist/thumbnail-cache.d.ts +2 -0
- package/dist/thumbnail-cache.js +10 -1
- package/dist/workspace-measure.js +6 -4
- package/dist/workspace-parts.js +20 -0
- package/dist/workspace-shell.js +25 -15
- package/dist/workspace-theme.js +3 -0
- package/dist/workspace.d.ts +114 -10
- package/dist/workspace.js +223 -49
- package/package.json +30 -19
|
@@ -17,6 +17,8 @@ export interface ThumbnailCache {
|
|
|
17
17
|
prepare(presentation: any, indices?: number[]): void;
|
|
18
18
|
/** The SVG markup (or the text "Preview unavailable") of one slide. Entries are keyed by the slide's index, the slide count and the slide's own content. */
|
|
19
19
|
html(presentation: any, index: number): string;
|
|
20
|
+
/** CE-20: the cached thumbnail of one slide, or undefined when it has not been drawn yet (a lazy strip calls `prepare` with the visible slides). */
|
|
21
|
+
peek(presentation: any, index: number): string | undefined;
|
|
20
22
|
/** Forget everything, for example after fonts load. */
|
|
21
23
|
clear(): void;
|
|
22
24
|
}
|
package/dist/thumbnail-cache.js
CHANGED
|
@@ -6,6 +6,7 @@ export function createThumbnailCache({toSvg, getOptions}) {
|
|
|
6
6
|
const cache = new Map();
|
|
7
7
|
let context;
|
|
8
8
|
let preparedDeck;
|
|
9
|
+
let peeked = { deck: null, same: false };
|
|
9
10
|
const key = (deck, index) => JSON.stringify([index, deck.slides.length, deck.slides[index]]);
|
|
10
11
|
const contextOf = (deck, options) => {
|
|
11
12
|
const {slides, ...metadata} = deck;
|
|
@@ -19,6 +20,7 @@ export function createThumbnailCache({toSvg, getOptions}) {
|
|
|
19
20
|
if (nextContext !== context) cache.clear();
|
|
20
21
|
context = nextContext;
|
|
21
22
|
preparedDeck = deck;
|
|
23
|
+
peeked = { deck: null, same: false };
|
|
22
24
|
const keys = deck.slides.map((_, index) => key(deck, index));
|
|
23
25
|
const wanted = indices === undefined ? keys.map((_, index) => index) : [...new Set(indices)].filter(index => Number.isInteger(index) && index >= 0 && index < keys.length);
|
|
24
26
|
const missing = wanted.filter(index => !cache.has(keys[index]));
|
|
@@ -45,6 +47,13 @@ export function createThumbnailCache({toSvg, getOptions}) {
|
|
|
45
47
|
if (deck !== preparedDeck || !cache.has(value)) prepare(deck);
|
|
46
48
|
return cache.get(value);
|
|
47
49
|
},
|
|
48
|
-
|
|
50
|
+
/** CE-20: the cached thumbnail of a slide, or undefined when it has not been drawn yet (a lazy strip draws it with `prepare`). */
|
|
51
|
+
peek(deck, index) {
|
|
52
|
+
// The context of a deck is read once per deck (a strip peeks at every slide of it in one render).
|
|
53
|
+
if (peeked.deck !== deck) peeked = { deck, same: contextOf(deck, getOptions()) === context };
|
|
54
|
+
if (!peeked.same) return undefined;
|
|
55
|
+
return cache.get(key(deck, index));
|
|
56
|
+
},
|
|
57
|
+
clear: () => { cache.clear(); preparedDeck = undefined; peeked = { deck: null, same: false }; },
|
|
49
58
|
};
|
|
50
59
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
// CE-06 (promoted from examples/playground.js): text measurement and font notes shared by the workspace parts.
|
|
2
|
-
|
|
1
|
+
// CE-06 (promoted from examples/playground.js): text measurement and font notes shared by the workspace parts. No renderer import: the script
|
|
2
|
+
// planner comes with the fonts handle (`textMeasurement.forScripts`, the renderer's font registry), so the `/workspace` entry, which re-exports
|
|
3
|
+
// `layoutOptionsFor`, loads no renderer code for a host that mounts only the source pane.
|
|
3
4
|
import { resolveScriptFonts } from "@openpresentation/opf/composition";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The layout options for composing slide `index` of `deck`: the fonts handle's measurement, made script-aware for this document (Japanese
|
|
7
8
|
* under Aptos measures with Noto Sans JP, where the plain strict measurement would throw "cannot display U+65E5" with every face loaded).
|
|
8
|
-
* A fonts handle without a measurement is passed through.
|
|
9
|
+
* A fonts handle without a measurement, or whose measurement has no script planner (`forScripts`), is passed through.
|
|
9
10
|
*/
|
|
10
11
|
export function layoutOptionsFor(fonts, deck, index, catalogs) {
|
|
11
12
|
if (!fonts?.textMeasurement) return fonts ? { fonts } : {};
|
|
13
|
+
if (typeof fonts.textMeasurement.forScripts !== "function") return { fonts };
|
|
12
14
|
try {
|
|
13
|
-
return { fonts: { textMeasurement:
|
|
15
|
+
return { fonts: { textMeasurement: fonts.textMeasurement.forScripts(resolveScriptFonts(deck, { slideIndex: index, catalogs })) } };
|
|
14
16
|
} catch {
|
|
15
17
|
return { fonts };
|
|
16
18
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The slide half of `createOpfEditor` (src/workspace.js), loaded on demand: the renderer, every part that shows or edits slides and the Studio. A host
|
|
2
|
+
// whose editor mounts only the source pane never loads this chunk (and so never loads the renderer); every other layout loads it once, before
|
|
3
|
+
// its parts mount. Internal: only workspace.js imports it.
|
|
4
|
+
export { toSvg } from "@openpresentation/opf-render/svg";
|
|
5
|
+
export { createCanvasEditor } from "./canvas.js";
|
|
6
|
+
export { createSlideNavigator } from "./slide-navigator.js";
|
|
7
|
+
export { createThumbnailStrip } from "./thumbnail-strip.js";
|
|
8
|
+
export { createThumbnailCache } from "./thumbnail-cache.js";
|
|
9
|
+
export { createSlideManager } from "./slide-manager.js";
|
|
10
|
+
export { createOutlineView } from "./outline-view.js";
|
|
11
|
+
export { createExportMenu } from "./export-menu.js";
|
|
12
|
+
export { bindPresentShortcut, createPresentButton, createPresenter } from "./presenter.js";
|
|
13
|
+
export { createReviewPanel } from "./review-panel.js";
|
|
14
|
+
export { createFindPanel, installFindShortcuts } from "./find-panel.js";
|
|
15
|
+
export { createDesignControls } from "./design-controls.js";
|
|
16
|
+
export { prepareDimensionSwitch } from "./switches.js";
|
|
17
|
+
export { mergeSlides, splitSlideByBlocks } from "./content-actions.js";
|
|
18
|
+
export { installCanvasVariableEditing } from "./canvas-variables.js";
|
|
19
|
+
export { createLayoutStudio } from "./workspace-layouts.js";
|
|
20
|
+
export { buildStudioShell, createStudio } from "./studio.js";
|
package/dist/workspace-shell.js
CHANGED
|
@@ -50,25 +50,35 @@ export function buildWorkspaceShell(root, { parts, views, layout, labels = {} })
|
|
|
50
50
|
if (parts.present) bar.append(slot("present", "div", { class: "opf-ws-present" }));
|
|
51
51
|
const hasBar = bar.children.length > 1;
|
|
52
52
|
|
|
53
|
-
// The main column: the slide (or another view) over the slide row.
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
53
|
+
// The main column: the slide (or another view) over the slide row, and the status line. A source-only layout has none: the pane has its own
|
|
54
|
+
// bar, problems and status.
|
|
55
|
+
const viewParts = ["sorter", "outline", "layouts"].filter((view) => parts[view]);
|
|
56
|
+
const hasMain = parts.canvas || parts.find || parts.navigator || parts.thumbnails || viewParts.length > 0;
|
|
57
|
+
let stage;
|
|
58
|
+
let frame;
|
|
59
|
+
let main;
|
|
60
|
+
if (hasMain) {
|
|
61
|
+
stage = make(doc, "div", { class: "opf-ws-stage" });
|
|
62
|
+
if (parts.canvas) {
|
|
63
|
+
frame = make(doc, "div", { class: "opf-ws-frame" }, slot("canvas", "div", { class: "opf-ws-canvas", "aria-label": "Slide preview" }));
|
|
64
|
+
stage.append(frame);
|
|
65
|
+
}
|
|
66
|
+
for (const view of viewParts) stage.append(slot(view, "div", { class: `opf-ws-view opf-ws-${view}`, hidden: true }));
|
|
67
|
+
main = make(doc, "section", { class: "opf-ws-main", "aria-label": "Slide workspace" });
|
|
68
|
+
if (parts.find) main.append(slot("find", "div", { class: "opf-ws-find", hidden: true }));
|
|
69
|
+
main.append(stage);
|
|
70
|
+
if (parts.navigator || parts.thumbnails) {
|
|
71
|
+
const dock = make(doc, "div", { class: "opf-ws-dock" });
|
|
72
|
+
if (parts.navigator) dock.append(slot("navigator", "div", { class: "opf-ws-navigator" }));
|
|
73
|
+
if (parts.thumbnails) dock.append(slot("thumbnails", "div", { class: "opf-ws-thumbnails" }));
|
|
74
|
+
main.append(dock);
|
|
75
|
+
}
|
|
76
|
+
main.append(slot("status", "p", { class: "opf-ws-status", role: "status" }));
|
|
66
77
|
}
|
|
67
|
-
main.append(slot("status", "p", { class: "opf-ws-status", role: "status" }));
|
|
68
78
|
|
|
69
79
|
const body = make(doc, "div", { class: "opf-ws-body" });
|
|
70
80
|
if (parts.source) body.append(make(doc, "section", { class: "opf-ws-source", "aria-label": "OPF source" }, slot("source", "div", { class: "opf-ws-source-host" })));
|
|
71
|
-
body.append(main);
|
|
81
|
+
if (main) body.append(main);
|
|
72
82
|
|
|
73
83
|
// The side panel: Review and Design as tabs.
|
|
74
84
|
const tabs = ["design", "review"].filter((name) => parts[name]);
|
package/dist/workspace-theme.js
CHANGED
|
@@ -23,6 +23,9 @@ export const THEME_TOKENS = Object.freeze({
|
|
|
23
23
|
success: "--opf-ui-success",
|
|
24
24
|
codeBackground: "--opf-ui-code-bg",
|
|
25
25
|
codeBorder: "--opf-ui-code-border",
|
|
26
|
+
selection: "--opf-ui-selection",
|
|
27
|
+
hover: "--opf-ui-hover",
|
|
28
|
+
canvasBackground: "--opf-ui-studio-canvas-bg",
|
|
26
29
|
font: "--opf-ui-font",
|
|
27
30
|
mono: "--opf-ui-mono",
|
|
28
31
|
radiusSmall: "--opf-ui-radius-sm",
|
package/dist/workspace.d.ts
CHANGED
|
@@ -11,9 +11,9 @@ import type { Presenter } from "./presenter.js";
|
|
|
11
11
|
import type { ReviewFinding, ReviewHook } from "./review.js";
|
|
12
12
|
import type { ReviewPanel, ReviewPanelOptions } from "./review-panel.js";
|
|
13
13
|
import type { SlideManager } from "./slide-manager.js";
|
|
14
|
-
import type { SourceFormat, SourceFile, SourcePane, SourcePaneOptions } from "./source-pane.js";
|
|
14
|
+
import type { SourceCursor, SourceFormat, SourceFile, SourcePane, SourcePaneOptions } from "./source-pane.js";
|
|
15
15
|
|
|
16
|
-
export type OpfEditorLayout = "full" | "canvas" | "source";
|
|
16
|
+
export type OpfEditorLayout = "full" | "canvas" | "source" | "studio" | "playground";
|
|
17
17
|
export type OpfEditorView = "slide" | "sorter" | "outline" | "layouts";
|
|
18
18
|
export type OpfEditorDensity = "comfortable" | "touch";
|
|
19
19
|
|
|
@@ -36,6 +36,9 @@ export declare const THEME_TOKENS: Readonly<{
|
|
|
36
36
|
success: "--opf-ui-success";
|
|
37
37
|
codeBackground: "--opf-ui-code-bg";
|
|
38
38
|
codeBorder: "--opf-ui-code-border";
|
|
39
|
+
selection: "--opf-ui-selection";
|
|
40
|
+
hover: "--opf-ui-hover";
|
|
41
|
+
canvasBackground: "--opf-ui-studio-canvas-bg";
|
|
39
42
|
font: "--opf-ui-font";
|
|
40
43
|
mono: "--opf-ui-mono";
|
|
41
44
|
radiusSmall: "--opf-ui-radius-sm";
|
|
@@ -77,6 +80,19 @@ export interface ThemeController {
|
|
|
77
80
|
/** Apply a theme to the editor mounted in `root`. `createOpfEditor` does this for `options.theme` and `handle.setTheme`. */
|
|
78
81
|
export declare function createThemeController(root: HTMLElement, theme?: OpfEditorTheme): ThemeController;
|
|
79
82
|
|
|
83
|
+
/**
|
|
84
|
+
* The options for composing slide `slideIndex` of `deck` with the fonts handle `fonts`: its text measurement, made script-aware for this document
|
|
85
|
+
* (Japanese under Aptos measures with Noto Sans JP, where the plain strict measurement would throw). Pass the result to the session's
|
|
86
|
+
* `composeSlide` and `paginateSlide`, and the same `catalogs` the editor was given. Without a handle it is `{}`, and a handle without a
|
|
87
|
+
* measurement is passed through.
|
|
88
|
+
*/
|
|
89
|
+
export declare function layoutOptionsFor(
|
|
90
|
+
fonts: EditorFonts | undefined,
|
|
91
|
+
deck: unknown,
|
|
92
|
+
slideIndex: number,
|
|
93
|
+
catalogs?: readonly Catalog[],
|
|
94
|
+
): { fonts?: EditorFonts };
|
|
95
|
+
|
|
80
96
|
/** What a host's own acquire function returns: the handle and the way to give it back. */
|
|
81
97
|
export interface OpfEditorFontsLease {
|
|
82
98
|
fonts: EditorFonts;
|
|
@@ -127,6 +143,42 @@ export interface OpfEditorSlots {
|
|
|
127
143
|
/** The status line: the editor writes its messages here. */
|
|
128
144
|
status?: HTMLElement;
|
|
129
145
|
overlay?: HTMLElement;
|
|
146
|
+
/** CE-20, the Studio: an element of the host placed at the end of the Studio's bar (Share, avatars). */
|
|
147
|
+
topbarEnd?: HTMLElement;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** CE-20: one item of the Studio's selection. `key` is the scene key (the id path, `/slides/@intro/blocks/@kpi`; a layout region `<slide key>#<name>`). */
|
|
151
|
+
export interface OpfStudioSelectionItem { key: string; path: string; idPath?: string; kind: "slide" | "heading" | "region" | "group" | "block" | "part" | "implicit" }
|
|
152
|
+
/** CE-20: a command of the Studio's registry (`studio.group`, `studio.insert.chart`, ...). `when` returns true, or a reason string that disables it. */
|
|
153
|
+
export interface OpfCommand<Ctx = unknown> {
|
|
154
|
+
id: string;
|
|
155
|
+
label: string;
|
|
156
|
+
group?: string;
|
|
157
|
+
/** CodeMirror-style keys ("Mod-g", "Shift-Mod-z", "F2"); Mod is Cmd on macOS and Ctrl elsewhere. */
|
|
158
|
+
keys?: string[];
|
|
159
|
+
/** "canvas": only while focus is on the slide, the layers or the filmstrip; "global" (default) anywhere outside a field. */
|
|
160
|
+
scope?: "canvas" | "global" | ("canvas" | "global")[];
|
|
161
|
+
when?(ctx: Ctx): boolean | string;
|
|
162
|
+
run(ctx: Ctx): boolean | void;
|
|
163
|
+
}
|
|
164
|
+
export interface OpfCommandInfo { id: string; label: string; group?: string; keys: string[]; shortcut: string; enabled: boolean; reason: string }
|
|
165
|
+
/** CE-20: a host's panel in the Studio: a tab of the right panel (default) or a section of the left (`side: "left"`); `mount` returns its cleanup. */
|
|
166
|
+
export interface OpfStudioHostPanel { id: string; label: string; icon?: SVGElement | string; side?: "left" | "right"; mount(element: HTMLElement, editor: OpfEditor): void | (() => void) }
|
|
167
|
+
/** CE-20: the Studio's options (`layout: "studio"` or `"playground"`). */
|
|
168
|
+
export interface OpfStudioOptions {
|
|
169
|
+
/** Which panels the Studio shows; `source` is where the source split opens ("split-right" by default on wide screens, "split-bottom" below 1100px). */
|
|
170
|
+
panels?: { source?: "split-right" | "split-bottom" | "tab" | false };
|
|
171
|
+
hostPanels?: OpfStudioHostPanel[];
|
|
172
|
+
/** Items added to the File menu. */
|
|
173
|
+
fileItems?: { id: string; label: string; run(editor: OpfEditor): void }[];
|
|
174
|
+
/** More commands for the registry (a host palette lists them with the Studio's). */
|
|
175
|
+
commands?: OpfCommand[];
|
|
176
|
+
/** Rebind commands: `{ "studio.source.toggle": ["Mod-Alt-s"] }`; `null` unbinds. */
|
|
177
|
+
keymap?: Record<string, string[] | null>;
|
|
178
|
+
/** Panel sizes stored per host key (nothing is stored without `storage`). */
|
|
179
|
+
sizes?: { key: string; storage?: { get(key: string): string | null; set(key: string, value: string): void } };
|
|
180
|
+
/** Give a deck without ids its ids when the Studio opens it (default true; one undoable change named "Add ids"). Never in the Playground. */
|
|
181
|
+
assignIds?: boolean;
|
|
130
182
|
}
|
|
131
183
|
|
|
132
184
|
export interface OpfEditorPanels {
|
|
@@ -162,12 +214,14 @@ export interface OpfEditorSourceOptions {
|
|
|
162
214
|
name?: string;
|
|
163
215
|
/** The text of the document as the author wrote it, so its spelling is kept. A string `document` is used when this is not given. */
|
|
164
216
|
text?: string;
|
|
165
|
-
/** The Web Worker that runs the pane's text checks off the main thread: `true`, a `Worker`,
|
|
217
|
+
/** The Web Worker that runs the pane's text checks off the main thread: `true`, a `Worker`, a function that returns one, or the URL of a worker script (docs/embedding.md, "The source worker"). Default: the main thread. */
|
|
166
218
|
worker?: SourcePaneOptions["worker"];
|
|
167
219
|
/** Core `validate` options for the verdict on the text (default the format and reference rules). */
|
|
168
220
|
checks?: { only?: readonly string[]; [key: string]: unknown };
|
|
169
221
|
outline?: SourcePaneOptions["outline"];
|
|
170
222
|
applyDelay?: number;
|
|
223
|
+
/** Milliseconds of quiet before a `cursor` event (default 50). */
|
|
224
|
+
cursorDelay?: number;
|
|
171
225
|
completions?: boolean;
|
|
172
226
|
label?: string;
|
|
173
227
|
catalogs?: SourcePaneOptions["catalogs"];
|
|
@@ -196,8 +250,15 @@ export interface OpfEditorOptions {
|
|
|
196
250
|
/** `"authored"` (default): the canvas shows `{{variables}}` as written. `"resolved"`: filled in, except in a template deck; a press on filled-in text opens its properties form. */
|
|
197
251
|
variables?: "authored" | "resolved";
|
|
198
252
|
|
|
199
|
-
/**
|
|
253
|
+
/**
|
|
254
|
+
* `"full"` (default), `"canvas"` or `"source"`: the editor builds the arrangement (ignored when `slots` is given). CE-20: `"studio"` is the
|
|
255
|
+
* Presentation and Slide Studio and `"playground"` its first-contact preset (a host's `slots` then add parts, such as `topbarEnd`).
|
|
256
|
+
*/
|
|
200
257
|
layout?: OpfEditorLayout;
|
|
258
|
+
/** CE-20: the Studio's options. */
|
|
259
|
+
studio?: OpfStudioOptions;
|
|
260
|
+
/** CE-20: `import.pptx(editor)` adds "Import PowerPoint…" to the Studio's File menu. */
|
|
261
|
+
import?: { pptx?(editor: OpfEditor): void };
|
|
201
262
|
slots?: OpfEditorSlots;
|
|
202
263
|
panels?: OpfEditorPanels;
|
|
203
264
|
/** The view shown first (default `"slide"`). */
|
|
@@ -240,6 +301,8 @@ export interface OpfEditorOptions {
|
|
|
240
301
|
|
|
241
302
|
onChange?(detail: OpfEditorEvents["change"]): void;
|
|
242
303
|
onSelection?(detail: OpfEditorEvents["selection"]): void;
|
|
304
|
+
/** The caret of the source pane moved to another place in the text. The same as `on: { cursor }`. */
|
|
305
|
+
onCursor?(detail: OpfEditorEvents["cursor"]): void;
|
|
243
306
|
onError?(error: Error, detail: Omit<OpfEditorEvents["error"], "error">): void;
|
|
244
307
|
onReady?(detail: OpfEditorEvents["ready"]): void;
|
|
245
308
|
/** Listeners by event name; the same as calling `on` before anything happens. */
|
|
@@ -260,7 +323,22 @@ export interface OpfEditorEvents {
|
|
|
260
323
|
ready: { editor: OpfEditor };
|
|
261
324
|
/** The document changed (an edit in the canvas or the source, undo, redo, a loaded document). Not fired for a catalogs change. */
|
|
262
325
|
change: { document: unknown; canUndo: boolean; canRedo: boolean; event: EditorEvent };
|
|
263
|
-
|
|
326
|
+
/** The canvas's selection; in the Studio, the list (`items`, the `primary` and what changed it: `canvas`, `layers`, `keyboard`, `source`, ...). */
|
|
327
|
+
selection: { path: string | undefined; value: unknown; slideIndex: number; element?: Element | undefined; items?: OpfStudioSelectionItem[]; primary?: OpfStudioSelectionItem | null; source?: string };
|
|
328
|
+
/** CE-20: the Studio's zoom changed (a factor of the fitted slide). */
|
|
329
|
+
zoom: { zoom: number };
|
|
330
|
+
/** CE-20: the Studio switched preset. */
|
|
331
|
+
layout: { layout: "studio" | "playground"; previous: "studio" | "playground" };
|
|
332
|
+
/** CE-20: a Studio command ran (`ok` false when it was off; `reason` says why). */
|
|
333
|
+
command: { id: string; ok: boolean; reason?: string };
|
|
334
|
+
/** CE-20: Layout Studio was opened from "Edit layout", or closed. */
|
|
335
|
+
layoutStudio: { open: boolean; recordId: string };
|
|
336
|
+
/**
|
|
337
|
+
* The caret or selection of the source pane moved, in JSON, YAML or Markdown, also while the pane has no focus: the path under it as a JSON Pointer
|
|
338
|
+
* and by id, and the selection in source offsets. Quiet for `source.cursorDelay` first and not repeated for a place already reported; the detail is
|
|
339
|
+
* frozen. For the rest of the pane (`revealPath`, `setDecorations`, `getCursor`) use `editor.sourcePane`.
|
|
340
|
+
*/
|
|
341
|
+
cursor: SourceCursor;
|
|
264
342
|
/** The slide changed (0-based). */
|
|
265
343
|
slide: { index: number; count: number };
|
|
266
344
|
view: { view: OpfEditorView; previous: OpfEditorView };
|
|
@@ -326,13 +404,26 @@ export interface OpfEditor {
|
|
|
326
404
|
readonly layoutStudio: LayoutStudio | undefined;
|
|
327
405
|
readonly fonts: EditorFonts | undefined;
|
|
328
406
|
readonly slideIndex: number;
|
|
329
|
-
/** The content last selected on the canvas. */
|
|
330
|
-
readonly selection: { path: string; value: unknown } | null;
|
|
407
|
+
/** The content last selected on the canvas; in the Studio, the selection list. */
|
|
408
|
+
readonly selection: { path: string; value: unknown } | OpfStudioSelectionItem[] | null;
|
|
409
|
+
/** CE-20: the arrangement; `setLayout` switches the Studio between "studio" and "playground". */
|
|
410
|
+
readonly layout: OpfEditorLayout | "slots";
|
|
411
|
+
setLayout(layout: "studio" | "playground"): boolean;
|
|
412
|
+
/** CE-20: the Studio's zoom (1 is the slide fitted), `setZoom` and `fit` ("slide" or "width"). */
|
|
413
|
+
readonly zoom: number;
|
|
414
|
+
setZoom(zoom: number): void;
|
|
415
|
+
fit(mode?: "slide" | "width"): void;
|
|
416
|
+
/** CE-20: "Edit layout": open a layout of the slide (default the current slide's) in Layout Studio, forked into the deck when it comes from a catalog. */
|
|
417
|
+
openLayout(layoutId?: string, options?: { slide?: number }): boolean;
|
|
418
|
+
/** CE-20: the Studio's command registry; empty outside the Studio. */
|
|
419
|
+
readonly commands: { list(): OpfCommandInfo[]; run(id: string): boolean; register(command: OpfCommand): () => void };
|
|
331
420
|
readonly view: OpfEditorView;
|
|
332
421
|
readonly views: OpfEditorView[];
|
|
333
422
|
readonly readOnly: boolean;
|
|
334
423
|
/** False while the text in the source pane is not a valid deck: the slide shows the last valid one. */
|
|
335
424
|
readonly inSync: boolean;
|
|
425
|
+
/** The latest `cursor` event, or `null` before the first (and without a source pane). The same object until the next event. */
|
|
426
|
+
readonly sourceCursor: SourceCursor | null;
|
|
336
427
|
/** The latest verdict on the text of the source pane (what the last `source` event carried), or `null` before the first. */
|
|
337
428
|
readonly sourceState: OpfEditorSourceState | null;
|
|
338
429
|
readonly lastError: Error | undefined;
|
|
@@ -344,6 +435,14 @@ export interface OpfEditor {
|
|
|
344
435
|
* as written. A document the session refuses is listed in the pane as a draft and `false` is returned. Throws before `ready`.
|
|
345
436
|
*/
|
|
346
437
|
setDocument(document: unknown, options?: OpfEditorSetDocumentOptions): boolean;
|
|
438
|
+
/**
|
|
439
|
+
* Load raw source text into the source pane without converting it (a file as it was read, text that does not parse): what pasting it over
|
|
440
|
+
* everything does. `options.format` is the text's format (the pane switches to it), `options.name` the file name, `options.rebase` as in
|
|
441
|
+
* `setDocument` (only when the text applied). Text that reads as a document the session accepts is applied as one undoable change; anything
|
|
442
|
+
* else stays in the pane as a draft with its problems (the slide keeps the last valid document) and `false` is returned. An open canvas edit
|
|
443
|
+
* is committed first. Throws before `ready`, without a source pane, and while read-only.
|
|
444
|
+
*/
|
|
445
|
+
setSourceText(text: string, options?: Omit<OpfEditorSetDocumentOptions, "text">): boolean;
|
|
347
446
|
/** Switch the view. Commits an open canvas edit first; false when that failed or the view is not available. */
|
|
348
447
|
setView(view: OpfEditorView, options?: { focus?: boolean }): boolean;
|
|
349
448
|
/** Show slide `index` (0-based). Commits an open canvas edit first. */
|
|
@@ -355,10 +454,12 @@ export interface OpfEditor {
|
|
|
355
454
|
/** Show a slide and select the content at `path` on it. */
|
|
356
455
|
goTo(index: number, path?: string): boolean;
|
|
357
456
|
/** Select the content at `path` on the current slide (or the closest content that can be selected); returns the path selected. */
|
|
358
|
-
|
|
457
|
+
/** Select content by path (the canvas: returns the path it selected). In the Studio: scene keys or paths, several siblings at once; returns whether all were found. */
|
|
458
|
+
select(path: string | string[], options?: { focus?: boolean }): string | null | boolean;
|
|
359
459
|
showPanel(panel: "review" | "design", focus?: boolean): boolean;
|
|
360
460
|
/** Start the full-screen presentation at the slide on show. False when it cannot start (invalid source, no slides, already running). */
|
|
361
|
-
|
|
461
|
+
/** Present from the slide on show (or from `from`, 0-based). */
|
|
462
|
+
present(from?: number): boolean;
|
|
362
463
|
undo(): boolean;
|
|
363
464
|
redo(): boolean;
|
|
364
465
|
/** Commit an open canvas edit. False when it could not be committed. */
|
|
@@ -382,7 +483,10 @@ export interface OpfEditor {
|
|
|
382
483
|
destroy(): void;
|
|
383
484
|
}
|
|
384
485
|
|
|
385
|
-
/**
|
|
486
|
+
/**
|
|
487
|
+
* Mount the editor in `element` (its content is replaced). The parts mount once the fonts have arrived and, for a layout that shows slides,
|
|
488
|
+
* once the slide chunk (the renderer and the slide parts, imported on demand) has loaded; await `ready`. A source-only editor never loads that chunk.
|
|
489
|
+
*/
|
|
386
490
|
export declare function createOpfEditor(element: HTMLElement, options?: OpfEditorOptions): OpfEditor;
|
|
387
491
|
|
|
388
492
|
export type { LayoutStudio } from "./workspace-layouts.js";
|