@web-ppt/editor 0.5.0-beta.1 → 0.5.0-beta.2

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.
@@ -36,6 +36,8 @@ export interface WebPptViewState {
36
36
  readonly zoom: number;
37
37
  readonly snapping: boolean;
38
38
  }
39
+ /** 公开输入格式供产品层决定是否需要另存提示;adapter 本身不拥有确认状态。 */
40
+ export type WebPptDocumentKind = 'pptx' | 'ppt';
39
41
  export interface WebPptFormatPainterState extends FormatPainterSnapshot {
40
42
  /** 文档未就绪、只读或当前为查看模式时为 true。 */
41
43
  readonly readonly: boolean;
@@ -73,6 +75,7 @@ export interface WebPptAdapterSnapshot extends WebPptViewState {
73
75
  readonly progress: number;
74
76
  readonly error: unknown | null;
75
77
  readonly session: EditorSession | null;
78
+ readonly documentKind: WebPptDocumentKind | null;
76
79
  readonly view: SlideEditor | null;
77
80
  readonly selectionPane: SelectionPane | null;
78
81
  readonly recovery: RecoveryCandidate | null;
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export type { SelectionPane, SelectionPaneOptions } from './selection-pane-types
15
15
  export type { WebPptSourceIdentity } from './source-fingerprint';
16
16
  export type { EditorRecovery, RecoveryCandidate, RecoveryDecision, RecoveryDecisionHandler, RecoveryOptions, RecoveryStore, RecoveryStoreAppend, RecoveryStoreJournal, RecoveryStoreReset, } from './recovery-store';
17
17
  export type { IndexedDbRecoveryStore, IndexedDbRecoveryStoreOptions, RecoveryCleanupResult, RecoveryStoreStats, } from './indexeddb-recovery-store';
18
- export type { WebPptAdapter, WebPptAdapterBinding, WebPptAdapterCallbacks, WebPptAdapterProgress, WebPptAdapterSnapshot, WebPptAdapterSubscriber, WebPptDocument, WebPptFormatPainterState, WebPptTextSearchState, WebPptViewOptions, WebPptViewState, } from './framework-adapter-types';
18
+ export type { WebPptAdapter, WebPptAdapterBinding, WebPptAdapterCallbacks, WebPptAdapterProgress, WebPptAdapterSnapshot, WebPptAdapterSubscriber, WebPptDocument, WebPptDocumentKind, WebPptFormatPainterState, WebPptTextSearchState, WebPptViewOptions, WebPptViewState, } from './framework-adapter-types';
19
19
  export type { WebPptSource } from './source-fingerprint';
20
20
  export type { EditorMode, LinkFollowContext, LinkFollowHandler, LinkFollowSource, SlideEditor, SlideEditorOptions, } from './slide-editor-types';
21
21
  export type { ImageInsertOptions } from './image-insertion';
@@ -5,4 +5,5 @@ export interface KeyboardControllerOptions {
5
5
  slideId(): SlideId;
6
6
  revealSlide(slideId: SlideId): void;
7
7
  gestureActive(): boolean;
8
+ onError?(error: unknown): void;
8
9
  }
@@ -0,0 +1,8 @@
1
+ import type { KeyboardControllerOptions } from './keyboard-context';
2
+ /** 文档级键位只组合既有选择、页面命令和视图回显,不引入第二条事件通道。 */
3
+ export declare class DocumentKeyboardController {
4
+ private readonly options;
5
+ constructor(options: KeyboardControllerOptions);
6
+ keyDown(event: KeyboardEvent, textOwner?: boolean): boolean;
7
+ private report;
8
+ }
@@ -0,0 +1,7 @@
1
+ import type { KeyboardControllerOptions } from './keyboard-context';
2
+ /** 组合快捷键只编排公开 Group/Ungroup;不可逆原因由 headless 命令原样上报宿主。 */
3
+ export declare class GroupKeyboardController {
4
+ private readonly options;
5
+ constructor(options: KeyboardControllerOptions);
6
+ keyDown(event: KeyboardEvent): boolean;
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { Editor, SlideId } from '@web-ppt/edit-core';
2
+ /** “全页”始终退出组上下文,只选择当前页直属且可交互的根元素。 */
3
+ export declare function selectAllSlideElements(editor: Editor, slideId: SlideId): readonly string[];
@@ -24,6 +24,8 @@ export interface SlideEditorOptions {
24
24
  snapMargins?: SnapMargins;
25
25
  /** React/Vue 等宿主可接管路由;返回 true 阻止内置页跳转或安全新窗口。 */
26
26
  onLinkFollow?: LinkFollowHandler;
27
+ /** 页面级快捷键或内部链接切页后通知宿主同步侧栏、分页器和受控状态。 */
28
+ onSlideChange?: (slideId: SlideId) => void;
27
29
  /** 与自定义事件 webpptformaterror 同源,adapter 用它接入全局 onError。 */
28
30
  onError?: (error: unknown) => void;
29
31
  }
@@ -10,6 +10,8 @@ export interface TextEditorControllerOptions {
10
10
  claim: () => void;
11
11
  release: () => void;
12
12
  syncStatic: (id: ElementId) => void;
13
+ selectAllElements: () => void;
14
+ documentKeyDown: (event: KeyboardEvent) => boolean;
13
15
  }
14
16
  export interface CompositionSnapshot {
15
17
  domText: string;
@@ -4,6 +4,7 @@ export declare class TextEditorController {
4
4
  private readonly options;
5
5
  private readonly clipboard;
6
6
  private readonly autofit;
7
+ private readonly keyboard;
7
8
  private activeId;
8
9
  private activeCell;
9
10
  private root;
@@ -0,0 +1,5 @@
1
+ import type { Editor, RunPropertyOverrides, TextPosition } from '@web-ppt/edit-core';
2
+ import type { TextEditorContext } from './text-editor-context';
3
+ /** 混合字号必须逐 run 跨档,不能把整段拉平为选区首个字号。 */
4
+ export declare function stepMixedFontSizes(editor: Editor, context: TextEditorContext, direction: -1 | 1): boolean;
5
+ export declare function stepSelectedFontSize(editor: Editor, context: TextEditorContext | null, direction: -1 | 1, setUniform: (props: RunPropertyOverrides) => boolean, restoreMixed: (from: TextPosition, to: TextPosition) => void): boolean;
@@ -0,0 +1,28 @@
1
+ import type { Editor, ParagraphPropertyOverrides, TableCellAddress, TextPosition } from '@web-ppt/edit-core';
2
+ import type { TextEditorContext } from './text-editor-context';
3
+ interface TextKeyboardOptions {
4
+ editor: Editor;
5
+ composing(): boolean;
6
+ activeCell(): TableCellAddress | null;
7
+ context(): TextEditorContext | null;
8
+ close(selectElement?: boolean): void;
9
+ navigateTableCell(reverse: boolean): void;
10
+ changeListLevel(delta: -1 | 1): void;
11
+ formatSelection(field: 'b' | 'i' | 'u'): boolean;
12
+ stepFontSize(direction: -1 | 1): boolean;
13
+ setParaProps(props: ParagraphPropertyOverrides): boolean;
14
+ restoreSelection(from: TextPosition, to: TextPosition): void;
15
+ selectAllElements(): void;
16
+ documentKeyDown(event: KeyboardEvent): boolean;
17
+ }
18
+ /** contenteditable 保留唯一 keydown 监听;这里只把已承诺键位路由到模型 seam。 */
19
+ export declare class TextKeyboardController {
20
+ private readonly options;
21
+ constructor(options: TextKeyboardOptions);
22
+ bind(root: HTMLDivElement): void;
23
+ private finish;
24
+ private forwardDocumentKey;
25
+ private selectAll;
26
+ private keyDown;
27
+ }
28
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { Editor } from '@web-ppt/edit-core';
2
+ import type { TextEditorContext } from './text-editor-context';
3
+ /** 多段选区逐段保留相对级别,并合并为一次历史事务。 */
4
+ export declare function changeTextListLevel(editor: Editor, context: TextEditorContext | null, delta: -1 | 1): boolean;
@@ -0,0 +1,2 @@
1
+ export { createVertexEditor } from './vertex-editor';
2
+ export type { VertexEditor, VertexEditorFactory, VertexEditorOptions } from './types';
@@ -0,0 +1,21 @@
1
+ import type { CustomGeometry } from '@web-ppt/core';
2
+ import type { ElementId } from '@web-ppt/edit-core';
3
+ import type { EditorSession } from '../session';
4
+ import type { SlideEditor } from '../slide-editor-types';
5
+ export interface VertexEditorOptions {
6
+ onError?: (error: unknown) => void;
7
+ }
8
+ export interface VertexEditor {
9
+ readonly elementId: ElementId | null;
10
+ readonly geometry: CustomGeometry | null;
11
+ readonly destroyed: boolean;
12
+ /** 省略 id 时只接受当前单元素选区;预设形状必须先显式 convert。 */
13
+ start(id?: ElementId): boolean;
14
+ end(): void;
15
+ convert(id?: ElementId): boolean;
16
+ setClosed(pathId: string, closed: boolean): void;
17
+ setSegmentType(pathId: string, commandId: string, type: 'line' | 'cubic'): void;
18
+ refresh(): void;
19
+ destroy(): void;
20
+ }
21
+ export type VertexEditorFactory = (session: EditorSession, view: SlideEditor, options?: VertexEditorOptions) => VertexEditor;
@@ -0,0 +1,4 @@
1
+ import type { EditorSession } from '../session';
2
+ import type { SlideEditor } from '../slide-editor-types';
3
+ import type { VertexEditor, VertexEditorOptions } from './types';
4
+ export declare function createVertexEditor(session: EditorSession, view: SlideEditor, options?: VertexEditorOptions): VertexEditor;
package/dist/vertex.js ADDED
@@ -0,0 +1,338 @@
1
+ import { queryElementCustomGeometry as f, slideOfElement as v, setCustomGeometryClosed as E, setCustomGeometrySegmentType as S, elementFrameToSlidePoint as b, screenToSlidePoint as A, slideToElementFramePoint as x, moveCustomGeometryPoint as D } from "@web-ppt/edit-core";
2
+ const I = 3, m = (u) => u.pointerId ?? 0;
3
+ class K {
4
+ constructor(t) {
5
+ this.active = null, this.root = t;
6
+ }
7
+ get isActive() {
8
+ return this.active !== null;
9
+ }
10
+ begin(t, e) {
11
+ var i, o;
12
+ this.cancel();
13
+ const r = { x: t.clientX, y: t.clientY };
14
+ this.active = {
15
+ pointerId: m(t),
16
+ startScreen: r,
17
+ snapshot: {
18
+ screen: r,
19
+ altKey: t.altKey,
20
+ ctrlKey: t.ctrlKey,
21
+ metaKey: t.metaKey,
22
+ shiftKey: t.shiftKey
23
+ },
24
+ gesture: e,
25
+ started: !1,
26
+ frame: null,
27
+ cursor: this.root.style.cursor
28
+ };
29
+ try {
30
+ (o = (i = this.root).setPointerCapture) == null || o.call(i, m(t));
31
+ } catch {
32
+ }
33
+ }
34
+ move(t) {
35
+ var r, i;
36
+ const e = this.active;
37
+ if (!(!e || m(t) !== e.pointerId)) {
38
+ this.updateSnapshot(e, t);
39
+ try {
40
+ (i = (r = e.gesture).observePointer) == null || i.call(r, e.snapshot);
41
+ } catch (o) {
42
+ throw this.clear(e), o;
43
+ }
44
+ if (!e.started) {
45
+ if (Math.hypot(
46
+ e.snapshot.screen.x - e.startScreen.x,
47
+ e.snapshot.screen.y - e.startScreen.y
48
+ ) < I) return;
49
+ e.started = !0;
50
+ try {
51
+ e.gesture.start();
52
+ } catch (h) {
53
+ throw this.clear(e), h;
54
+ }
55
+ this.root.style.cursor = e.gesture.cursor, this.root.dataset[e.gesture.dataset.name] = e.gesture.dataset.value;
56
+ }
57
+ t.preventDefault(), this.scheduleFrame(e);
58
+ }
59
+ }
60
+ finish(t) {
61
+ var i, o;
62
+ const e = this.active;
63
+ if (!e || m(t) !== e.pointerId) return "ignored";
64
+ this.updateSnapshot(e, t);
65
+ let r;
66
+ try {
67
+ (o = (i = e.gesture).observePointer) == null || o.call(i, e.snapshot), r = e.started ? e.gesture.finish(e.snapshot) : null;
68
+ } catch (h) {
69
+ throw this.clear(e), h;
70
+ }
71
+ return this.clear(e), r == null || r(), r && t.preventDefault(), e.started ? "gesture" : "click";
72
+ }
73
+ /** 键盘确认使用最后一次指针快照;先清理 capture/rAF,再执行提交,避免订阅回调重入活动手势。 */
74
+ commit() {
75
+ const t = this.active;
76
+ if (!t) return !1;
77
+ let e = null;
78
+ try {
79
+ e = t.started ? t.gesture.finish(t.snapshot) : null;
80
+ } catch (r) {
81
+ throw this.clear(t), r;
82
+ }
83
+ return this.clear(t), e == null || e(), t.started;
84
+ }
85
+ modifier(t) {
86
+ const e = this.active;
87
+ return !e || !["Shift", "Alt", "Control", "Meta"].includes(t.key) ? !1 : (e.snapshot = {
88
+ ...e.snapshot,
89
+ altKey: t.altKey,
90
+ ctrlKey: t.ctrlKey,
91
+ metaKey: t.metaKey,
92
+ shiftKey: t.shiftKey
93
+ }, e.started && this.scheduleFrame(e), !0);
94
+ }
95
+ cancel() {
96
+ this.active && this.clear(this.active);
97
+ }
98
+ cancelPointer(t) {
99
+ this.active && m(t) === this.active.pointerId && this.clear(this.active);
100
+ }
101
+ updateSnapshot(t, e) {
102
+ t.snapshot = {
103
+ screen: { x: e.clientX, y: e.clientY },
104
+ altKey: e.altKey,
105
+ ctrlKey: e.ctrlKey,
106
+ metaKey: e.metaKey,
107
+ shiftKey: e.shiftKey
108
+ };
109
+ }
110
+ scheduleFrame(t) {
111
+ if (t.frame !== null) return;
112
+ const e = this.root.ownerDocument.defaultView;
113
+ if (!(e != null && e.requestAnimationFrame)) {
114
+ try {
115
+ t.gesture.frame(t.snapshot);
116
+ } catch (r) {
117
+ throw this.clear(t), r;
118
+ }
119
+ return;
120
+ }
121
+ t.frame = e.requestAnimationFrame(() => {
122
+ if (t.frame = null, this.active === t)
123
+ try {
124
+ t.gesture.frame(t.snapshot);
125
+ } catch (r) {
126
+ throw this.clear(t), r;
127
+ }
128
+ });
129
+ }
130
+ clear(t) {
131
+ var r, i;
132
+ this.active = null;
133
+ const e = this.root.ownerDocument.defaultView;
134
+ t.frame !== null && (e != null && e.cancelAnimationFrame) && e.cancelAnimationFrame(t.frame);
135
+ try {
136
+ t.started && t.gesture.clear();
137
+ } finally {
138
+ this.root.style.cursor = t.cursor, delete this.root.dataset[t.gesture.dataset.name];
139
+ try {
140
+ (i = (r = this.root).hasPointerCapture) != null && i.call(r, t.pointerId) && this.root.releasePointerCapture(t.pointerId);
141
+ } catch {
142
+ }
143
+ }
144
+ }
145
+ }
146
+ const P = "http://www.w3.org/2000/svg";
147
+ function g(u, t) {
148
+ return u.createElementNS(P, t);
149
+ }
150
+ class C {
151
+ constructor(t, e, r) {
152
+ var l;
153
+ if (this.session = t, this.view = e, this.options = r, this.activeId = null, this.preview = null, this.isDestroyed = !1, this.pointerDown = (s) => {
154
+ const c = s.target instanceof Element ? s.target.closest("[data-ppt-vertex-point]") : null;
155
+ if (!(!c || s.button !== 0 || s.isPrimary === !1))
156
+ try {
157
+ const n = c.dataset.pptVertexPoint;
158
+ this.lifecycle.begin(s, this.gesture(n, this.requireGeometry())), this.stop(s);
159
+ } catch (n) {
160
+ this.report(n);
161
+ }
162
+ }, this.pointerMove = (s) => {
163
+ if (this.lifecycle.isActive)
164
+ try {
165
+ this.lifecycle.move(s), this.stop(s);
166
+ } catch (c) {
167
+ this.report(c);
168
+ }
169
+ }, this.pointerUp = (s) => {
170
+ if (this.lifecycle.isActive)
171
+ try {
172
+ this.lifecycle.finish(s), this.stop(s);
173
+ } catch (c) {
174
+ this.report(c);
175
+ }
176
+ }, this.pointerCancel = (s) => {
177
+ this.lifecycle.isActive && (this.lifecycle.cancelPointer(s), this.stop(s));
178
+ }, this.keyDown = (s) => {
179
+ s.key !== "Escape" || !this.lifecycle.isActive || (this.lifecycle.cancel(), this.stop(s));
180
+ }, t.disposed || e.destroyed) throw new Error("不能挂载到已释放的编辑视图");
181
+ this.root = e.element;
182
+ const i = this.root.querySelector("[data-ppt-stage]"), o = this.root.querySelector('[data-ppt-layer="interaction"]'), h = this.root.querySelector('[data-ppt-layer="static"]');
183
+ if (!i || !o || !h) throw new Error("编辑视图缺少三层 DOM");
184
+ this.stage = i, this.layer = o, this.lifecycle = new K(this.root), this.root.addEventListener("pointerdown", this.pointerDown, !0), this.root.addEventListener("pointermove", this.pointerMove, !0), this.root.addEventListener("pointerup", this.pointerUp, !0), this.root.addEventListener("pointercancel", this.pointerCancel, !0), this.root.addEventListener("keydown", this.keyDown, !0), this.unsubscribe = t.editor.subscribe(() => this.render());
185
+ const y = ((l = this.root.ownerDocument.defaultView) == null ? void 0 : l.MutationObserver) ?? MutationObserver;
186
+ this.observer = new y(() => this.render()), this.observer.observe(h, { childList: !0 });
187
+ }
188
+ get elementId() {
189
+ return this.activeId;
190
+ }
191
+ get geometry() {
192
+ return this.activeId ? f(this.session.editor.doc, this.activeId) : null;
193
+ }
194
+ get destroyed() {
195
+ return this.isDestroyed;
196
+ }
197
+ start(t) {
198
+ this.assertAlive();
199
+ const e = this.session.editor.selection, r = t ?? (e.kind === "elements" && e.ids.length === 1 ? e.ids[0] : null);
200
+ return !r || this.view.mode !== "edit" || v(this.session.editor.doc, r) !== this.view.slideId || !f(this.session.editor.doc, r) ? !1 : (this.activeId = r, this.preview = null, this.render(), !0);
201
+ }
202
+ end() {
203
+ var t;
204
+ this.lifecycle.cancel(), this.activeId = null, this.preview = null, (t = this.group()) == null || t.remove();
205
+ }
206
+ convert(t) {
207
+ this.assertAlive();
208
+ const e = this.session.editor.selection, r = t ?? (e.kind === "elements" && e.ids.length === 1 ? e.ids[0] : null);
209
+ if (!r || this.view.mode !== "edit") return !1;
210
+ try {
211
+ return this.session.editor.exec({ type: "ConvertToCustomGeometry", id: r }), this.start(r);
212
+ } catch (i) {
213
+ return this.report(i), !1;
214
+ }
215
+ }
216
+ setClosed(t, e) {
217
+ const r = this.requireGeometry();
218
+ this.session.editor.exec({
219
+ type: "SetGeometry",
220
+ id: this.activeId,
221
+ geometry: E(r, t, e)
222
+ });
223
+ }
224
+ setSegmentType(t, e, r) {
225
+ const i = this.requireGeometry();
226
+ this.session.editor.exec({
227
+ type: "SetGeometry",
228
+ id: this.activeId,
229
+ geometry: S(i, t, e, r)
230
+ });
231
+ }
232
+ refresh() {
233
+ this.assertAlive(), this.render();
234
+ }
235
+ destroy() {
236
+ var t;
237
+ this.isDestroyed || (this.isDestroyed = !0, this.lifecycle.cancel(), this.unsubscribe(), this.observer.disconnect(), this.root.removeEventListener("pointerdown", this.pointerDown, !0), this.root.removeEventListener("pointermove", this.pointerMove, !0), this.root.removeEventListener("pointerup", this.pointerUp, !0), this.root.removeEventListener("pointercancel", this.pointerCancel, !0), this.root.removeEventListener("keydown", this.keyDown, !0), (t = this.group()) == null || t.remove(), this.activeId = null, this.preview = null);
238
+ }
239
+ assertAlive() {
240
+ if (this.isDestroyed || this.session.disposed || this.view.destroyed)
241
+ throw new Error("顶点编辑扩展已经释放");
242
+ }
243
+ requireGeometry() {
244
+ this.assertAlive();
245
+ const t = this.geometry;
246
+ if (!t || !this.activeId) throw new Error("当前没有正在编辑的自由形状");
247
+ return t;
248
+ }
249
+ group() {
250
+ return this.layer.querySelector("[data-ppt-vertex-editor]");
251
+ }
252
+ slidePoint(t, e) {
253
+ const r = this.activeId, i = this.session.editor.effectiveElement(r);
254
+ return b(this.session.editor.doc, r, {
255
+ x: t.x.value / e.width * i.w,
256
+ y: t.y.value / e.height * i.h
257
+ });
258
+ }
259
+ render() {
260
+ var i;
261
+ (i = this.group()) == null || i.remove();
262
+ const t = this.activeId;
263
+ if (!t || this.isDestroyed || this.view.destroyed || this.view.mode !== "edit" || !this.session.editor.doc.elements[t] || v(this.session.editor.doc, t) !== this.view.slideId) return;
264
+ const e = this.preview ?? f(this.session.editor.doc, t);
265
+ if (!e) return;
266
+ const r = g(this.layer.ownerDocument, "g");
267
+ r.dataset.pptVertexEditor = "", r.dataset.pptVertexElement = t;
268
+ for (const o of e.paths) {
269
+ let h = null, y = null;
270
+ const l = (s, c) => {
271
+ const n = g(this.layer.ownerDocument, "line");
272
+ n.setAttribute("x1", String(s.x)), n.setAttribute("y1", String(s.y)), n.setAttribute("x2", String(c.x)), n.setAttribute("y2", String(c.y)), n.setAttribute("stroke", "#f59e0b"), n.setAttribute("stroke-width", String(1 / this.view.zoom)), n.style.pointerEvents = "none", r.append(n);
273
+ };
274
+ for (const s of o.commands) {
275
+ if (s.type === "arc") throw new Error("顶点查询未物化圆弧命令");
276
+ if (s.type === "close") {
277
+ h = y;
278
+ continue;
279
+ }
280
+ const c = s.points[s.points.length - 1], n = this.slidePoint(c, o), p = s.points.slice(0, -1).map((d) => this.slidePoint(d, o));
281
+ h && p.length && l(h, p[0]), p.length && l(p[p.length - 1], n), s.type === "move" && (y = n);
282
+ for (const d of s.points) {
283
+ const w = this.slidePoint(d, o), a = g(this.layer.ownerDocument, "circle");
284
+ a.dataset.pptVertexPoint = d.id, a.dataset.pptVertexPath = o.id, a.dataset.pptVertexRole = d.role, a.setAttribute("cx", String(w.x)), a.setAttribute("cy", String(w.y)), a.setAttribute("r", String((d.role === "anchor" ? 5 : 4) / this.view.zoom)), a.setAttribute("fill", d.role === "anchor" ? "#fff" : "#fef3c7"), a.setAttribute("stroke", d.role === "anchor" ? "#2563eb" : "#d97706"), a.setAttribute("stroke-width", String(1.5 / this.view.zoom)), a.style.pointerEvents = "all", a.style.cursor = "crosshair", r.append(a);
285
+ }
286
+ h = n;
287
+ }
288
+ }
289
+ this.layer.append(r);
290
+ }
291
+ geometryAt(t, e, r) {
292
+ const i = this.activeId, o = r.paths.find((c) => c.commands.some((n) => n.points.some((p) => p.id === e)));
293
+ if (!o) throw new Error(`找不到顶点路径:${e}`);
294
+ const h = this.stage.getBoundingClientRect(), y = A(t.screen, { left: h.left, top: h.top, zoom: this.view.zoom }), l = x(this.session.editor.doc, i, y), s = this.session.editor.effectiveElement(i);
295
+ return D(r, e, {
296
+ x: l.x / s.w * o.width,
297
+ y: l.y / s.h * o.height
298
+ });
299
+ }
300
+ gesture(t, e) {
301
+ let r = e;
302
+ const i = (o) => {
303
+ r = this.geometryAt(o, t, e), this.preview = r, this.render();
304
+ };
305
+ return {
306
+ cursor: "crosshair",
307
+ dataset: { name: "pptVertexDragging", value: t },
308
+ start: () => {
309
+ },
310
+ frame: i,
311
+ finish: (o) => {
312
+ i(o);
313
+ const h = this.activeId;
314
+ return () => {
315
+ this.preview = null, this.session.editor.exec({ type: "SetGeometry", id: h, geometry: r });
316
+ };
317
+ },
318
+ clear: () => {
319
+ this.preview = null, this.render();
320
+ }
321
+ };
322
+ }
323
+ stop(t) {
324
+ t.preventDefault(), t.stopImmediatePropagation();
325
+ }
326
+ report(t) {
327
+ var e, r;
328
+ this.lifecycle.cancel(), (r = (e = this.options).onError) == null || r.call(e, t), this.options.onError || queueMicrotask(() => {
329
+ throw t;
330
+ });
331
+ }
332
+ }
333
+ function G(u, t, e = {}) {
334
+ return new C(u, t, e);
335
+ }
336
+ export {
337
+ G as createVertexEditor
338
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@web-ppt/editor",
3
- "version": "0.5.0-beta.1",
3
+ "version": "0.5.0-beta.2",
4
4
  "description": "Framework-agnostic browser editing session and DOM view for Web-PPT.",
5
5
  "keywords": [
6
6
  "pptx",
@@ -30,6 +30,10 @@
30
30
  "types": "./dist/index.d.ts",
31
31
  "import": "./dist/editor.js"
32
32
  },
33
+ "./vertex": {
34
+ "types": "./dist/vertex/index.d.ts",
35
+ "import": "./dist/vertex.js"
36
+ },
33
37
  "./package.json": "./package.json"
34
38
  },
35
39
  "files": [
@@ -39,14 +43,14 @@
39
43
  "LICENSE"
40
44
  ],
41
45
  "scripts": {
42
- "build": "vite build && tsc -p tsconfig.build.json",
46
+ "build": "vite build && node ../../tooling/check-editor-main-size.mjs && vite build --config vite.vertex.config.ts && tsc -p tsconfig.build.json",
43
47
  "prepublishOnly": "npm run build",
44
48
  "prepack": "node ../../tooling/sync-package-docs.mjs"
45
49
  },
46
50
  "peerDependencies": {
47
- "@web-ppt/core": "^0.5.0-beta.1",
48
- "@web-ppt/edit-core": "^0.5.0-beta.1",
49
- "@web-ppt/viewer-core": "^0.5.0-beta.1"
51
+ "@web-ppt/core": "^0.5.0-beta.2",
52
+ "@web-ppt/edit-core": "^0.5.0-beta.2",
53
+ "@web-ppt/viewer-core": "^0.5.0-beta.2"
50
54
  },
51
55
  "publishConfig": {
52
56
  "access": "public"