@web-ppt/edit-core 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.
- package/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/dist/collaboration-identity.d.ts +3 -0
- package/dist/commands/add-slide-identity.d.ts +2 -0
- package/dist/commands/convert-to-custom-geometry.d.ts +4 -0
- package/dist/commands/element-geometry.d.ts +6 -0
- package/dist/commands/element-hierarchy.d.ts +6 -0
- package/dist/commands/element-table-style.d.ts +5 -0
- package/dist/commands/frame-decomposition.d.ts +10 -0
- package/dist/commands/generated-creation-defaults.d.ts +4 -0
- package/dist/commands/geometry-types.d.ts +22 -0
- package/dist/commands/group-types.d.ts +24 -0
- package/dist/commands/group.d.ts +4 -0
- package/dist/commands/insertion-host.d.ts +3 -0
- package/dist/commands/insertion-rect.d.ts +2 -0
- package/dist/commands/patch-invalidation.d.ts +4 -0
- package/dist/commands/patch.d.ts +4 -0
- package/dist/commands/record-clone.d.ts +3 -0
- package/dist/commands/set-geometry.d.ts +4 -0
- package/dist/commands/set-table-style.d.ts +3 -0
- package/dist/commands/spid.d.ts +1 -0
- package/dist/commands/table-style-types.d.ts +28 -0
- package/dist/commands/text-target.d.ts +1 -0
- package/dist/commands/types.d.ts +29 -4
- package/dist/commands/ungroup.d.ts +4 -0
- package/dist/custom-geometry-path.d.ts +3 -0
- package/dist/custom-geometry.d.ts +12 -0
- package/dist/document-B1jjN-QB.js +274 -0
- package/dist/edit-core.js +3597 -2639
- package/dist/editor.d.ts +6 -1
- package/dist/generate/custom-geometry.d.ts +2 -0
- package/dist/generate/index.d.ts +12 -0
- package/dist/generate/links.d.ts +3 -0
- package/dist/generate/materialize.d.ts +2 -0
- package/dist/generate/media.d.ts +13 -0
- package/dist/generate/table.d.ts +4 -0
- package/dist/generate/template.d.ts +3 -0
- package/dist/generate.js +744 -0
- package/dist/hyperlink.d.ts +2 -0
- package/dist/identity-allocation.d.ts +12 -0
- package/dist/identity-watermark.d.ts +4 -0
- package/dist/image-resource-DbgJS9n-.js +24 -0
- package/dist/{index-D4ZTaYOa.js → index-D2JizcOQ.js} +7 -7
- package/dist/index.d.ts +11 -3
- package/dist/insertion-CGpb504L.js +6152 -0
- package/dist/layout-projection.d.ts +2 -0
- package/dist/opc/patch.d.ts +2 -0
- package/dist/opc.js +1 -1
- package/dist/paragraph-level.d.ts +11 -0
- package/dist/paragraph-property-schema.d.ts +1 -1
- package/dist/{patch-DO8497wO.js → patch-D7lZelRa.js} +111 -94
- package/dist/patch-change.d.ts +4 -0
- package/dist/patch-events.d.ts +12 -0
- package/dist/recovery-identity.d.ts +2 -1
- package/dist/run-property-schema.d.ts +1 -1
- package/dist/save/geometry.d.ts +5 -0
- package/dist/save/insertion.d.ts +3 -0
- package/dist/save/notes.d.ts +2 -0
- package/dist/save/run-overrides.d.ts +10 -0
- package/dist/save/shape-format.d.ts +3 -0
- package/dist/save/table-style-part.d.ts +11 -0
- package/dist/save/table.d.ts +3 -0
- package/dist/save/text-source-less.d.ts +6 -0
- package/dist/save.js +468 -1441
- package/dist/table-direct-markup.d.ts +7 -1
- package/dist/table-style-part-DBtpxmuo.js +1042 -0
- package/dist/table-style.d.ts +20 -0
- package/dist/text-model.d.ts +1 -1
- package/dist/types.d.ts +44 -1
- package/dist/xml.js +1 -1
- package/package.json +6 -2
- package/dist/insertion-DabLme_U.js +0 -5471
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
## 未发布
|
|
6
6
|
|
|
7
|
+
## 0.5.0-beta.2 - 2026-08-30
|
|
8
|
+
|
|
9
|
+
### 新增
|
|
10
|
+
|
|
11
|
+
- 无原包文档现在可确定性生成完整 PPTX;`.ppt` 编辑后可明确另存为 `.pptx`,官网同时贯通空白新建、
|
|
12
|
+
真实版式加页、保存下载与本机恢复。
|
|
13
|
+
- 编辑模型与无框架 DOM 层新增组合/解组、九级文本列表升降级、附录 B 快捷键、上下文工具栏、
|
|
14
|
+
顶点编辑扩展和表格样式应用/写回。
|
|
15
|
+
- 新增可选的 `@web-ppt/collab`:字段级 LWW、分数序与确定性页序重物化把 `Editor` 补丁流接到
|
|
16
|
+
可插拔 provider,支持离线幂等回放、remove-wins、远端历史 rebase 和 BroadcastChannel 双标签页。
|
|
17
|
+
OOXML 元素身份由 provider 分配的副本 slot 精确分区;协同包不进入单机 `editor` 入口。
|
|
18
|
+
|
|
19
|
+
### 改进
|
|
20
|
+
|
|
21
|
+
- 官网延后加载编辑引擎,样本在构建期预渲染并内联关键 CSS,同时补齐 WCAG 对比度与稳定 chunk 命名。
|
|
22
|
+
- 浏览器性能契约将功能失败与预算超标分离,并在检测到并行负载时只允许一次全新 Chrome 重测。
|
|
23
|
+
|
|
7
24
|
## 0.5.0-beta.1 - 2026-08-27
|
|
8
25
|
|
|
9
26
|
### 新增
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ It keeps parsed source values separate from user overrides, assigns stable sessi
|
|
|
7
7
|
an editable document back to the existing high-fidelity `Slide` schema. It has no DOM dependency.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm i @web-ppt/core @web-ppt/edit-core
|
|
10
|
+
npm i @web-ppt/core@next @web-ppt/edit-core@next
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
```ts
|
|
@@ -5,4 +5,6 @@ export declare function allocateSlideOpcIdentity(doc: EditDoc): {
|
|
|
5
5
|
presentationRelationshipId: string;
|
|
6
6
|
};
|
|
7
7
|
export declare function allocateNotesPart(doc: EditDoc): string;
|
|
8
|
+
/** 协同绑定期固化全部全局 OPC 数值区间,后续远端补丁不会改变本副本的分配边界。 */
|
|
9
|
+
export declare function prepareSlideOpcNamespaces(doc: EditDoc): void;
|
|
8
10
|
export declare function presentationSlideIdForPart(doc: EditDoc, part: string): number | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EditDoc } from '../types';
|
|
2
|
+
import type { CommandPatches } from './types';
|
|
3
|
+
import type { ConvertToCustomGeometryCommand } from './geometry-types';
|
|
4
|
+
export declare function convertToCustomGeometryPatches(doc: EditDoc, command: ConvertToCustomGeometryCommand, origin: string): CommandPatches;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { EditDoc } from '../types';
|
|
2
|
+
import type { Patch } from './types';
|
|
3
|
+
import type { ElementGeometryPatch } from './geometry-types';
|
|
4
|
+
export declare function isElementGeometryPatch(patch: Patch): patch is ElementGeometryPatch;
|
|
5
|
+
export declare function validateElementGeometryPatch(doc: EditDoc, patch: ElementGeometryPatch, index: number): void;
|
|
6
|
+
export declare function applyElementGeometryPatch(doc: EditDoc, patch: ElementGeometryPatch): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { EditDoc } from '../types';
|
|
2
|
+
import type { ElementHierarchyPatch, ElementHierarchyState, Patch } from './types';
|
|
3
|
+
export declare function isElementHierarchyPatch(patch: Patch): patch is ElementHierarchyPatch;
|
|
4
|
+
export declare function validateElementHierarchyPatch(doc: EditDoc, patch: ElementHierarchyPatch, index: number): void;
|
|
5
|
+
export declare function applyElementHierarchyPatch(doc: EditDoc, patch: ElementHierarchyPatch): void;
|
|
6
|
+
export declare function elementHierarchySlide(doc: EditDoc, state: ElementHierarchyState): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { EditDoc } from '../types';
|
|
2
|
+
import type { ElementTableStylePatch, Patch } from './types';
|
|
3
|
+
export declare function isElementTableStylePatch(patch: Patch): patch is ElementTableStylePatch;
|
|
4
|
+
export declare function validateElementTableStylePatch(doc: EditDoc, patch: ElementTableStylePatch, index: number): void;
|
|
5
|
+
export declare function applyElementTableStylePatch(doc: EditDoc, patch: ElementTableStylePatch): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AffineMatrix } from '../space';
|
|
2
|
+
/** PPTX frame 只能表达旋转、缩放与镜像;仿射矩阵含斜切时必须由调用者拒绝。 */
|
|
3
|
+
export declare function decomposeFrameMatrix(matrix: AffineMatrix, width: number, height: number, shearError: string): {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
w: number;
|
|
7
|
+
h: number;
|
|
8
|
+
rot: number;
|
|
9
|
+
reflectH: boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ShapeCreationDefaults, TableCreationDefaults } from '@web-ppt/core';
|
|
2
|
+
/** `.ppt` 没有 OOXML 主题创建默认值;生成包因此用与固定骨架配套的显式中性值。 */
|
|
3
|
+
export declare const GENERATED_SHAPE_DEFAULTS: ShapeCreationDefaults;
|
|
4
|
+
export declare const GENERATED_TABLE_DEFAULTS: TableCreationDefaults;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CustomGeometry } from '@web-ppt/core';
|
|
2
|
+
import type { ElementId } from '../types';
|
|
3
|
+
export interface SetGeometryCommand {
|
|
4
|
+
readonly type: 'SetGeometry';
|
|
5
|
+
readonly id: ElementId;
|
|
6
|
+
/** null 恢复来源几何;预设形状必须先走显式自由形状转换命令。 */
|
|
7
|
+
readonly geometry: CustomGeometry | null;
|
|
8
|
+
}
|
|
9
|
+
export interface ConvertToCustomGeometryCommand {
|
|
10
|
+
readonly type: 'ConvertToCustomGeometry';
|
|
11
|
+
readonly id: ElementId;
|
|
12
|
+
}
|
|
13
|
+
export type ElementGeometryPatch = {
|
|
14
|
+
readonly op: 'set';
|
|
15
|
+
readonly path: readonly ['elements', ElementId, 'ovr', 'geometry'];
|
|
16
|
+
readonly value: CustomGeometry;
|
|
17
|
+
readonly origin: string;
|
|
18
|
+
} | {
|
|
19
|
+
readonly op: 'del';
|
|
20
|
+
readonly path: readonly ['elements', ElementId, 'ovr', 'geometry'];
|
|
21
|
+
readonly origin: string;
|
|
22
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ElementId, ElementRecord, RemovedElementRecord, SlideId } from '../types';
|
|
2
|
+
export interface GroupCommand {
|
|
3
|
+
readonly type: 'Group';
|
|
4
|
+
readonly ids: readonly ElementId[];
|
|
5
|
+
}
|
|
6
|
+
export interface UngroupCommand {
|
|
7
|
+
readonly type: 'Ungroup';
|
|
8
|
+
readonly id: ElementId;
|
|
9
|
+
}
|
|
10
|
+
export interface ElementHierarchyState {
|
|
11
|
+
/** 结构变化发生前后都存在的外部父级,用于精确失效所属页或祖先。 */
|
|
12
|
+
readonly parent: SlideId | ElementId;
|
|
13
|
+
readonly affected: readonly ElementId[];
|
|
14
|
+
readonly records: Readonly<Record<ElementId, ElementRecord | null>>;
|
|
15
|
+
readonly children: Readonly<Record<SlideId | ElementId, readonly ElementId[]>>;
|
|
16
|
+
readonly removed: Readonly<Record<ElementId, RemovedElementRecord | null>>;
|
|
17
|
+
}
|
|
18
|
+
/** 组合/解组同时改变多个父链,必须作为一个不可见中间态的结构原子落模。 */
|
|
19
|
+
export type ElementHierarchyPatch = {
|
|
20
|
+
readonly op: 'set';
|
|
21
|
+
readonly path: readonly ['elements', ElementId, 'hierarchy'];
|
|
22
|
+
readonly value: ElementHierarchyState;
|
|
23
|
+
readonly origin: string;
|
|
24
|
+
};
|
|
@@ -7,3 +7,5 @@ export interface InsertionRect {
|
|
|
7
7
|
export declare const EMU_PER_PX = 9525;
|
|
8
8
|
export declare const pxToEmu: (value: number) => number;
|
|
9
9
|
export declare function assertInsertionRect(value: unknown, label: string): asserts value is InsertionRect;
|
|
10
|
+
/** OOXML 允许线条的单轴尺寸为零;已有元素 frame 的约束不同于新增实体的正尺寸。 */
|
|
11
|
+
export declare function assertFrameRect(value: unknown, label: string): asserts value is InsertionRect;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EditDoc } from '../types';
|
|
2
|
+
import type { Patch } from './types';
|
|
3
|
+
export declare function collectPatchInvalidation(doc: EditDoc, patch: Patch, dirtyElements: Set<string>, dirtySlides: Set<string>): void;
|
|
4
|
+
export declare function canInvalidateAgainst(doc: EditDoc, patch: Patch): boolean;
|
package/dist/commands/patch.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { EditDoc, ProjectionInvalidation } from '../types';
|
|
2
2
|
import type { Patch } from './types';
|
|
3
|
+
/** 协同等调用方可在不触碰真实模型的前提下验真一批外部 Patch。 */
|
|
4
|
+
export declare function assertPatchesApplicable(doc: EditDoc, patches: readonly Patch[]): void;
|
|
5
|
+
/** 返回写时复制的外部 Patch 预演模型;调用方只能读取,真实文档始终不变。 */
|
|
6
|
+
export declare function stageExternalPatches(doc: EditDoc, patches: readonly Patch[]): EditDoc;
|
|
3
7
|
/** JSON/协同 seam:结构快照必须先在写时复制的完整模型上验真。 */
|
|
4
8
|
export declare function applyPatches(doc: EditDoc, patches: readonly Patch[]): ProjectionInvalidation;
|
|
5
9
|
/** 仅供同一事务内刚生成的命令 Patch;事务末尾由 Editor 统一校验完整模型。 */
|
package/dist/commands/spid.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EditDoc } from '../types';
|
|
2
|
+
export declare function prepareElementSpidNamespaces(doc: EditDoc): void;
|
|
2
3
|
/** 来源 XML 里还有不进入 Schema 的 cNvPr;只扫模型会在空页或未知宿主上复用 spid。 */
|
|
3
4
|
export declare function allocateElementSpid(doc: EditDoc, part: string): number;
|
|
4
5
|
export declare function partSpidAllocator(doc: EditDoc, part: string): () => number;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TableStyleSettings } from '@web-ppt/core';
|
|
2
|
+
import type { ElementId } from '../types';
|
|
3
|
+
type TableStyleSwitches = Omit<TableStyleSettings, 'styleId'>;
|
|
4
|
+
export type SetTableStyleCommand = {
|
|
5
|
+
readonly type: 'SetTableStyle';
|
|
6
|
+
readonly id: ElementId;
|
|
7
|
+
} & ({
|
|
8
|
+
readonly styleId: null;
|
|
9
|
+
readonly firstRow?: never;
|
|
10
|
+
readonly lastRow?: never;
|
|
11
|
+
readonly bandRow?: never;
|
|
12
|
+
readonly firstCol?: never;
|
|
13
|
+
readonly lastCol?: never;
|
|
14
|
+
readonly bandCol?: never;
|
|
15
|
+
} | ({
|
|
16
|
+
readonly styleId: string;
|
|
17
|
+
} & TableStyleSwitches));
|
|
18
|
+
export type ElementTableStylePatch = {
|
|
19
|
+
readonly op: 'set';
|
|
20
|
+
readonly path: readonly ['elements', ElementId, 'ovr', 'tableStyle'];
|
|
21
|
+
readonly value: TableStyleSettings;
|
|
22
|
+
readonly origin: string;
|
|
23
|
+
} | {
|
|
24
|
+
readonly op: 'del';
|
|
25
|
+
readonly path: readonly ['elements', ElementId, 'ovr', 'tableStyle'];
|
|
26
|
+
readonly origin: string;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -8,6 +8,7 @@ export interface TextTarget {
|
|
|
8
8
|
export interface TextTargetContext {
|
|
9
9
|
readonly record: ElementRecord;
|
|
10
10
|
readonly body: TextBody;
|
|
11
|
+
readonly levelTemplate?: TextBody;
|
|
11
12
|
readonly before: TextOverride | undefined;
|
|
12
13
|
readonly patchTarget: TextPatchTarget;
|
|
13
14
|
readonly empty: boolean;
|
package/dist/commands/types.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import type { Effects, Fill, Stroke } from '@web-ppt/core';
|
|
2
|
-
import type { ElementId, ElementImageReplacement, ElementInsertionResource, ElementRecord, ImageCrop, LinkOverride, LinkTarget, ParagraphPropertyOverrides, ProjectionInvalidation, RunPropertyOverrides, SlideId, TextFragment, TextOverride, SlideRecord, TableCellAddress, TextBodyPropertyOverrides } from '../types';
|
|
2
|
+
import type { EditIdentity, ElementId, ElementImageReplacement, ElementInsertionResource, ElementRecord, ImageCrop, LinkOverride, LinkTarget, ParagraphPropertyOverrides, ProjectionInvalidation, RunPropertyOverrides, SlideId, TextFragment, TextOverride, SlideRecord, TableCellAddress, TextBodyPropertyOverrides } from '../types';
|
|
3
3
|
import type { ElementClipboardPayload } from './clipboard-types';
|
|
4
|
+
import type { ElementHierarchyPatch, GroupCommand, UngroupCommand } from './group-types';
|
|
5
|
+
import type { ConvertToCustomGeometryCommand, ElementGeometryPatch, SetGeometryCommand } from './geometry-types';
|
|
4
6
|
import type { SetBackgroundCommand, SetBackgroundCropCommand, SetBackgroundImageCommand, SetHiddenCommand, SetAnimationsCommand, SetTransitionCommand, SetLayoutCommand, SetNotesCommand, SlideLayoutPatch, SlideNotesPatch, SlidePropertyPatch } from './slide-property-types';
|
|
5
7
|
import type { ApplyFormatCommand } from './format-painter-types';
|
|
6
8
|
import type { ReplaceTextCommand } from '../text-search-types';
|
|
9
|
+
import type { ElementTableStylePatch, SetTableStyleCommand } from './table-style-types';
|
|
7
10
|
export type { ClipboardElementRecord, ClipboardPortableLink, ClipboardRelationship, ClipboardResource, ClipboardTextLink, ClipboardXmlRoot, ElementClipboardPayload, ElementClipboardRecordMeta, } from './clipboard-types';
|
|
8
11
|
export type { SetBackgroundCommand, SetBackgroundCropCommand, SetBackgroundImageCommand, SetHiddenCommand, SetAnimationsCommand, SetTransitionCommand, SetLayoutCommand, SlideAnimationsPatch, SlideBackgroundImagePatch, SlideBackgroundPatch, SlideHiddenPatch, SlideTransitionPatch, SetNotesCommand, SlideLayoutPatch, SlideNotesPatch, SlidePropertyPatch, } from './slide-property-types';
|
|
9
12
|
export type { ApplyFormatCommand, FormatMaskField } from './format-painter-types';
|
|
13
|
+
export type { ElementHierarchyPatch, ElementHierarchyState, GroupCommand, UngroupCommand, } from './group-types';
|
|
10
14
|
export type { ReplaceTextCommand, ReplaceTextScope } from '../text-search-types';
|
|
15
|
+
export type { ElementTableStylePatch, SetTableStyleCommand } from './table-style-types';
|
|
11
16
|
export type NumericXfrmField = 'x' | 'y' | 'w' | 'h' | 'rot';
|
|
12
17
|
export type FlipField = 'flipH' | 'flipV';
|
|
13
18
|
export type XfrmField = NumericXfrmField | FlipField;
|
|
@@ -239,7 +244,7 @@ export interface InsertRowCommand {
|
|
|
239
244
|
readonly type: 'InsertRow';
|
|
240
245
|
readonly id: ElementId;
|
|
241
246
|
}
|
|
242
|
-
export type Command = SetXfrmCommand | SetFlipCommand | RemoveElementCommand | SetZCommand | SetNameCommand | SetLockedCommand | SetElementHiddenCommand | ApplyFormatCommand | ReplaceTextCommand | AlignElementsCommand | PasteElementsCommand | AddShapeCommand | AddImageCommand | ReplaceImageCommand | SetCropCommand | AddTableCommand | AddSlideCommand | MoveSlideCommand | RemoveSlideCommand | DuplicateSlideCommand | EditTextCommand | SetRunPropsCommand | SetParaPropsCommand | FitTextShapeCommand | SetBodyPropsCommand | InsertRowCommand | SetFillCommand | SetStrokeCommand | SetEffectsCommand | SetLinkCommand | SetBackgroundCommand | SetBackgroundCropCommand | SetBackgroundImageCommand | SetHiddenCommand | SetTransitionCommand | SetAnimationsCommand | SetLayoutCommand | SetNotesCommand;
|
|
247
|
+
export type Command = SetXfrmCommand | SetFlipCommand | RemoveElementCommand | SetZCommand | SetNameCommand | SetLockedCommand | SetElementHiddenCommand | ApplyFormatCommand | ReplaceTextCommand | AlignElementsCommand | GroupCommand | UngroupCommand | PasteElementsCommand | AddShapeCommand | AddImageCommand | ReplaceImageCommand | SetCropCommand | SetGeometryCommand | ConvertToCustomGeometryCommand | AddTableCommand | AddSlideCommand | MoveSlideCommand | RemoveSlideCommand | DuplicateSlideCommand | EditTextCommand | SetRunPropsCommand | SetParaPropsCommand | FitTextShapeCommand | SetBodyPropsCommand | InsertRowCommand | SetFillCommand | SetStrokeCommand | SetEffectsCommand | SetLinkCommand | SetBackgroundCommand | SetBackgroundCropCommand | SetBackgroundImageCommand | SetHiddenCommand | SetTransitionCommand | SetAnimationsCommand | SetLayoutCommand | SetNotesCommand | SetTableStyleCommand;
|
|
243
248
|
type SetXfrmPatch = {
|
|
244
249
|
[F in XfrmField]: {
|
|
245
250
|
readonly op: 'set';
|
|
@@ -416,10 +421,11 @@ export type TableRowPatch = {
|
|
|
416
421
|
readonly value: import('../types').TableRowInsertion;
|
|
417
422
|
readonly origin: string;
|
|
418
423
|
};
|
|
419
|
-
export type Patch = ElementTransformPatch | ElementFillPatch | ElementStrokePatch | ElementEffectsPatch | ElementLinkPatch | ElementCropPatch | ElementImageReplacementPatch | ImageResourcePatch | ElementTextPatch | ElementOrderPatch | ElementNamePatch | ElementInteractionPatch | ElementTreePatch | SlideTreePatch | SlideOrderPatch | SlidePropertyPatch | SlideLayoutPatch | SlideNotesPatch | TableRowPatch;
|
|
424
|
+
export type Patch = ElementTransformPatch | ElementFillPatch | ElementStrokePatch | ElementEffectsPatch | ElementLinkPatch | ElementCropPatch | ElementGeometryPatch | ElementImageReplacementPatch | ImageResourcePatch | ElementTextPatch | ElementOrderPatch | ElementNamePatch | ElementInteractionPatch | ElementTreePatch | ElementHierarchyPatch | SlideTreePatch | SlideOrderPatch | SlidePropertyPatch | SlideLayoutPatch | SlideNotesPatch | TableRowPatch | ElementTableStylePatch;
|
|
420
425
|
export interface CommandPatches {
|
|
421
426
|
readonly forward: Patch[];
|
|
422
427
|
readonly inverse: Patch[];
|
|
428
|
+
readonly selection?: Selection;
|
|
423
429
|
}
|
|
424
430
|
export interface TextPosition {
|
|
425
431
|
readonly p: number;
|
|
@@ -474,7 +480,7 @@ export interface TransactionResult extends ProjectionInvalidation, CommandPatche
|
|
|
474
480
|
readonly renderSlides: Set<SlideId>;
|
|
475
481
|
}
|
|
476
482
|
export interface EditorChange extends ProjectionInvalidation, SlideChangeSets {
|
|
477
|
-
readonly source: 'transaction' | 'undo' | 'redo' | 'selection';
|
|
483
|
+
readonly source: 'transaction' | 'undo' | 'redo' | 'external' | 'selection';
|
|
478
484
|
readonly selection: Selection;
|
|
479
485
|
/** dirtyElements 含投影缓存祖先;DOM 增量分区必须以真正被 patch 的元素为准。 */
|
|
480
486
|
readonly touchedElements: Set<ElementId>;
|
|
@@ -490,6 +496,25 @@ export interface EditorChange extends ProjectionInvalidation, SlideChangeSets {
|
|
|
490
496
|
readonly paneElements: Set<ElementId>;
|
|
491
497
|
}
|
|
492
498
|
export type EditorSubscriber = (change: EditorChange) => void;
|
|
499
|
+
export interface EditorPatchEvent {
|
|
500
|
+
readonly source: Exclude<EditorChange['source'], 'selection'>;
|
|
501
|
+
readonly patches: readonly Patch[];
|
|
502
|
+
readonly identity: EditIdentity;
|
|
503
|
+
readonly origin: string;
|
|
504
|
+
readonly label: string;
|
|
505
|
+
readonly time: number;
|
|
506
|
+
}
|
|
507
|
+
export type EditorPatchSubscriber = (event: EditorPatchEvent) => void;
|
|
508
|
+
export interface EditorPatchSubscribeOptions {
|
|
509
|
+
/** 协同 checkpoint 必须先于 recovery 观察者看到同一事务;该阶段的订阅者不得重入编辑器。 */
|
|
510
|
+
readonly phase?: 'before-recovery' | 'after-observers';
|
|
511
|
+
}
|
|
512
|
+
export interface ExternalPatchOptions {
|
|
513
|
+
readonly identity?: EditIdentity;
|
|
514
|
+
readonly origin?: string;
|
|
515
|
+
readonly label?: string;
|
|
516
|
+
readonly time?: number;
|
|
517
|
+
}
|
|
493
518
|
export interface Transaction {
|
|
494
519
|
exec(...commands: Command[]): void;
|
|
495
520
|
select(selection: Selection): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CustomGeometry } from '@web-ppt/core';
|
|
2
|
+
import type { EditDoc, ElementId } from './types';
|
|
3
|
+
export declare function assertCustomGeometry(value: unknown, label: string): asserts value is CustomGeometry;
|
|
4
|
+
/** 投影读 value、保存写 expression;覆盖边界必须保证二者不会形成两套真相。 */
|
|
5
|
+
export declare function assertCustomGeometryOverride(current: CustomGeometry | null, value: unknown, label: string): asserts value is CustomGeometry;
|
|
6
|
+
export declare function queryElementCustomGeometry(doc: EditDoc, id: ElementId): CustomGeometry | null;
|
|
7
|
+
export declare function moveCustomGeometryPoint(geometry: CustomGeometry, pointId: string, position: {
|
|
8
|
+
readonly x: number;
|
|
9
|
+
readonly y: number;
|
|
10
|
+
}): CustomGeometry;
|
|
11
|
+
export declare function setCustomGeometryClosed(geometry: CustomGeometry, pathId: string, closed: boolean): CustomGeometry;
|
|
12
|
+
export declare function setCustomGeometrySegmentType(geometry: CustomGeometry, pathId: string, commandId: string, type: 'line' | 'cubic'): CustomGeometry;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { a as U, r as J, c as K, i as Q, h as Y, d as Z, e as ee, f as te } from "./insertion-CGpb504L.js";
|
|
2
|
+
const S = 4294967295, x = 4294967295, F = (e) => e.startsWith("spid:") || e.startsWith("relationship:");
|
|
3
|
+
function G(e) {
|
|
4
|
+
return [...new TextEncoder().encode(e)].map((o) => o.toString(16).padStart(2, "0")).join("");
|
|
5
|
+
}
|
|
6
|
+
function ne(e, o = "身份分配命名空间", a) {
|
|
7
|
+
const t = e, r = t != null && t.ranges && typeof t.ranges == "object" && !Array.isArray(t.ranges) ? Object.entries(t.ranges) : null;
|
|
8
|
+
if (!t || typeof t != "object" || typeof t.replicaId != "string" || !t.replicaId || typeof t.prefix != "string" || !t.prefix || a !== void 0 && t.prefix !== `${a}c${G(t.replicaId)}_` || !Number.isSafeInteger(t.slot) || t.slot < 0 || !Number.isSafeInteger(t.count) || t.count < 2 || t.slot >= t.count || t.count > 65536 || !Number.isSafeInteger(t.clock) || t.clock < 0 || t.clock > x || !Number.isSafeInteger(t.sequence) || t.sequence < 0 || t.sequence > x || !r || r.length > 2e4 || r.some(([n, s]) => !n || !s || !Number.isSafeInteger(s.base) || s.base <= 0 || !Number.isSafeInteger(s.maximum) || s.maximum < s.base || s.maximum > S || !Number.isSafeInteger(s.next) || !Number.isSafeInteger(s.end) || !Number.isSafeInteger(s.step) || s.step <= 0 || s.next <= 0 || s.end <= 0 || s.end > s.maximum + 1 || s.next > s.end + s.step - 1 || (F(n) ? s.base !== t.slot + 1 || s.maximum !== S || s.step !== t.count || s.end !== S + 1 || (s.next - s.base) % t.count !== 0 : (() => {
|
|
9
|
+
const d = Math.floor((s.maximum - s.base + 1) / t.count), m = s.base + t.slot * d, u = t.slot === t.count - 1 ? s.maximum + 1 : m + d;
|
|
10
|
+
return d < 1 || s.step !== 1 || s.end !== u || s.next < m || s.next > u;
|
|
11
|
+
})())))
|
|
12
|
+
throw new Error(`${o}无效`);
|
|
13
|
+
}
|
|
14
|
+
function le(e, o, a, t = 4096) {
|
|
15
|
+
const r = e.allocation;
|
|
16
|
+
if (r) {
|
|
17
|
+
if (ne(r, "身份分配命名空间", e.prefix), r.replicaId !== o || r.slot !== a || r.count !== t)
|
|
18
|
+
throw new Error("同一文档不能切换协同身份分配命名空间");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
e.allocation = {
|
|
22
|
+
replicaId: o,
|
|
23
|
+
slot: a,
|
|
24
|
+
count: t,
|
|
25
|
+
prefix: `${e.prefix}c${G(o)}_`,
|
|
26
|
+
clock: 0,
|
|
27
|
+
sequence: 0,
|
|
28
|
+
ranges: {}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function oe(e, o, a, t = S) {
|
|
32
|
+
const r = e.allocation;
|
|
33
|
+
if (!r) return null;
|
|
34
|
+
const n = r.ranges[o];
|
|
35
|
+
if (n) {
|
|
36
|
+
if (F(o)) {
|
|
37
|
+
if (n.base !== r.slot + 1 || n.maximum !== S || n.step !== r.count || n.end !== S + 1 || (n.next - n.base) % r.count !== 0)
|
|
38
|
+
throw new Error(`身份范围 ${o} 与当前副本分区不匹配`);
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
41
|
+
const u = Math.floor((t - n.base + 1) / r.count), g = n.base + r.slot * u, p = r.slot === r.count - 1 ? t + 1 : g + u;
|
|
42
|
+
if (n.maximum !== t || n.step !== 1 || n.end !== p || n.next < g || n.next > p)
|
|
43
|
+
throw new Error(`身份范围 ${o} 与当前副本分区不匹配`);
|
|
44
|
+
return n;
|
|
45
|
+
}
|
|
46
|
+
if (!Number.isSafeInteger(a) || a <= 0 || a > t)
|
|
47
|
+
throw new Error(`身份范围 ${o} 已耗尽`);
|
|
48
|
+
const s = Math.floor((t - a + 1) / r.count);
|
|
49
|
+
if (s < 1) throw new Error(`身份范围 ${o} 无法容纳协同副本`);
|
|
50
|
+
const d = a + r.slot * s, m = r.slot === r.count - 1 ? t + 1 : d + s;
|
|
51
|
+
return r.ranges[o] = { base: a, maximum: t, next: d, end: m, step: 1 };
|
|
52
|
+
}
|
|
53
|
+
function de(e, o, a, t = S) {
|
|
54
|
+
const r = oe(e, o, a, t);
|
|
55
|
+
if (!r) return null;
|
|
56
|
+
if (r.next >= r.end) throw new Error(`身份范围 ${o} 已耗尽`);
|
|
57
|
+
const n = r.next;
|
|
58
|
+
return r.next += r.step, n;
|
|
59
|
+
}
|
|
60
|
+
const X = (e) => {
|
|
61
|
+
var o;
|
|
62
|
+
return ((o = e.allocation) == null ? void 0 : o.prefix) ?? e.prefix;
|
|
63
|
+
};
|
|
64
|
+
function se(e) {
|
|
65
|
+
const o = e.allocation;
|
|
66
|
+
if (o && (o.clock >= x || o.sequence >= x))
|
|
67
|
+
throw new Error("协同逻辑时钟或消息序号已耗尽");
|
|
68
|
+
}
|
|
69
|
+
function ue(e) {
|
|
70
|
+
const o = e.allocation;
|
|
71
|
+
o && (se(e), o.clock++, o.sequence++);
|
|
72
|
+
}
|
|
73
|
+
let V = 0;
|
|
74
|
+
const y = /* @__PURE__ */ new WeakMap(), B = /* @__PURE__ */ new WeakSet();
|
|
75
|
+
function z(e) {
|
|
76
|
+
var t, r;
|
|
77
|
+
if (e !== void 0) return e;
|
|
78
|
+
V++;
|
|
79
|
+
const o = new Uint32Array(2);
|
|
80
|
+
return (r = (t = globalThis.crypto) == null ? void 0 : t.getRandomValues) == null || r.call(t, o), `d${o[0] || o[1] ? `${o[0].toString(36)}${o[1].toString(36)}` : `${Date.now().toString(36)}${V.toString(36)}`}-`;
|
|
81
|
+
}
|
|
82
|
+
function re(e) {
|
|
83
|
+
var o;
|
|
84
|
+
return (o = e.editInfo) != null && o.editable ? e.editInfo.editable : e.kind === "unsupported" || e.kind === "group" && (e.name === "图表" || e.name === "SmartArt" || e.name === "墨迹") ? "frame" : "full";
|
|
85
|
+
}
|
|
86
|
+
function ie(e, o, a, t) {
|
|
87
|
+
var u;
|
|
88
|
+
const r = re(e), n = e.editInfo, s = a === "pptx" && !(n != null && n.origin), d = a === "pptx" && ((u = n == null ? void 0 : n.origin) == null ? void 0 : u.part) !== t, m = o === "full" && !s && !d ? r : "none";
|
|
89
|
+
return {
|
|
90
|
+
...n != null && n.geom ? { geom: n.geom } : {},
|
|
91
|
+
...n != null && n.customGeometry ? { customGeometry: n.customGeometry } : {},
|
|
92
|
+
...n != null && n.placeholder ? { ph: n.placeholder } : {},
|
|
93
|
+
...n != null && n.placeholderDirect ? { placeholderDirect: n.placeholderDirect } : {},
|
|
94
|
+
...n != null && n.placeholderInheritedEffects ? { placeholderInheritedEffects: n.placeholderInheritedEffects } : {},
|
|
95
|
+
...n != null && n.origin ? { origin: n.origin } : {},
|
|
96
|
+
...n != null && n.moveLocked ? { moveLocked: !0 } : {},
|
|
97
|
+
...n != null && n.textTemplate ? { textTemplate: n.textTemplate } : {},
|
|
98
|
+
...n != null && n.readonlyLink ? { sourceLinkReadonly: !0 } : {},
|
|
99
|
+
editable: m,
|
|
100
|
+
...d ? { inherited: !0 } : {}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function ae(e) {
|
|
104
|
+
const { elements: o, editInfo: a, ...t } = e;
|
|
105
|
+
return t;
|
|
106
|
+
}
|
|
107
|
+
function fe(e, o = {}) {
|
|
108
|
+
var E, $, P, v, k, A, O, N, j, D, M, R, T, C, L;
|
|
109
|
+
const a = z(o.idPrefix), t = {}, r = {}, n = [];
|
|
110
|
+
let s = 0, d = 0;
|
|
111
|
+
const m = (i, c, l, f, h, q) => i.map((I, H) => {
|
|
112
|
+
const b = `${a}e${(++d).toString(36)}`, _ = ie(I, l, e.source, f), W = {
|
|
113
|
+
id: b,
|
|
114
|
+
parent: c,
|
|
115
|
+
z: Q(H),
|
|
116
|
+
src: I,
|
|
117
|
+
ovr: {},
|
|
118
|
+
meta: _
|
|
119
|
+
};
|
|
120
|
+
return r[b] = W, Y(I) && h.push(b), Z(I) && q.push(b), I.kind === "group" && (W.children = m(
|
|
121
|
+
I.children,
|
|
122
|
+
b,
|
|
123
|
+
_.editable,
|
|
124
|
+
f,
|
|
125
|
+
h,
|
|
126
|
+
q
|
|
127
|
+
)), b;
|
|
128
|
+
});
|
|
129
|
+
for (const i of e.slides) {
|
|
130
|
+
const c = `${a}s${(++s).toString(36)}`, l = [], f = [], h = {
|
|
131
|
+
id: c,
|
|
132
|
+
src: ae(i),
|
|
133
|
+
ovr: {},
|
|
134
|
+
children: [],
|
|
135
|
+
dynamicSlideNumbers: l,
|
|
136
|
+
dynamicSlideLinks: f,
|
|
137
|
+
origin: ((E = i.editInfo) == null ? void 0 : E.origin) ?? null,
|
|
138
|
+
...($ = i.editInfo) != null && $.notes ? {
|
|
139
|
+
notes: {
|
|
140
|
+
sourcePart: i.editInfo.notes.part,
|
|
141
|
+
targetPart: i.editInfo.notes.part,
|
|
142
|
+
relationshipId: i.editInfo.notes.relationshipId
|
|
143
|
+
}
|
|
144
|
+
} : {},
|
|
145
|
+
...(P = i.editInfo) != null && P.layoutId ? { layoutId: i.editInfo.layoutId } : {},
|
|
146
|
+
...(v = i.editInfo) != null && v.layoutId ? { sourceLayoutId: i.editInfo.layoutId } : {},
|
|
147
|
+
...(k = i.editInfo) != null && k.directBackground ? { sourceDirectBackground: !0 } : {},
|
|
148
|
+
...(A = i.editInfo) != null && A.directTransition ? { sourceDirectTransition: !0 } : {},
|
|
149
|
+
...(O = i.editInfo) != null && O.hideMasterShapes ? { sourceHideMasterShapes: !0 } : {},
|
|
150
|
+
...(N = i.editInfo) != null && N.defaultShape ? { defaultShape: structuredClone(i.editInfo.defaultShape) } : {},
|
|
151
|
+
...(j = i.editInfo) != null && j.defaultTable ? { defaultTable: structuredClone(i.editInfo.defaultTable) } : {},
|
|
152
|
+
...(D = i.editInfo) != null && D.tableStyles ? { tableStyles: structuredClone(i.editInfo.tableStyles) } : {}
|
|
153
|
+
};
|
|
154
|
+
t[c] = h, n.push(c), h.children = m(
|
|
155
|
+
i.elements,
|
|
156
|
+
c,
|
|
157
|
+
"full",
|
|
158
|
+
((M = h.origin) == null ? void 0 : M.part) ?? null,
|
|
159
|
+
l,
|
|
160
|
+
f
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (e.source === "pptx") {
|
|
164
|
+
const i = /* @__PURE__ */ new Map();
|
|
165
|
+
for (const c of Object.values(r)) {
|
|
166
|
+
if (!c.meta.origin) continue;
|
|
167
|
+
const l = `${c.meta.origin.part}\0${c.meta.origin.spid}`, f = i.get(l) ?? [];
|
|
168
|
+
f.push(c), i.set(l, f);
|
|
169
|
+
}
|
|
170
|
+
for (const c of i.values())
|
|
171
|
+
if (c.length > 1) for (const l of c) l.meta.editable = "none";
|
|
172
|
+
}
|
|
173
|
+
const u = e.package ?? null, g = e.source === "pptx" ? !!u && !u.disposed && n.every((i) => t[i].origin !== null) : !0, p = {
|
|
174
|
+
meta: {
|
|
175
|
+
width: e.width,
|
|
176
|
+
height: e.height,
|
|
177
|
+
source: e.source,
|
|
178
|
+
readonly: !g,
|
|
179
|
+
...(R = e.editInfo) != null && R.tableStylesPart ? { tableStylesPart: e.editInfo.tableStylesPart } : {}
|
|
180
|
+
},
|
|
181
|
+
identity: { prefix: a, nextSlide: s + 1, nextElement: d + 1, nextSpid: {} },
|
|
182
|
+
slides: t,
|
|
183
|
+
slideOrder: n,
|
|
184
|
+
layouts: Object.fromEntries((((T = e.editInfo) == null ? void 0 : T.layouts) ?? []).map((i) => [
|
|
185
|
+
i.id,
|
|
186
|
+
structuredClone(i)
|
|
187
|
+
])),
|
|
188
|
+
layoutOrder: ((C = e.editInfo) == null ? void 0 : C.layouts.map((i) => i.id)) ?? [],
|
|
189
|
+
elements: r,
|
|
190
|
+
removedElements: {},
|
|
191
|
+
imageResources: {},
|
|
192
|
+
package: u,
|
|
193
|
+
saveState: {
|
|
194
|
+
baselines: /* @__PURE__ */ Object.create(null),
|
|
195
|
+
createdParts: [],
|
|
196
|
+
sourceSlideParts: n.flatMap((i) => {
|
|
197
|
+
var c;
|
|
198
|
+
return ((c = t[i].origin) == null ? void 0 : c.part) ?? [];
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
return e.slides.forEach((i, c) => {
|
|
203
|
+
var h;
|
|
204
|
+
const l = n[c], f = U(p, l, i.animations);
|
|
205
|
+
f.steps.length && (p.slides[l].sourceAnimations = f.steps), (f.readonly || (h = i.editInfo) != null && h.animationSourceReadonly) && (p.slides[l].sourceAnimationsReadonly = !0);
|
|
206
|
+
}), e.dispose && y.set(p, e.dispose), J(p, (L = e.editInfo) == null ? void 0 : L.assets), p;
|
|
207
|
+
}
|
|
208
|
+
function me(e) {
|
|
209
|
+
if (!Number.isFinite(e.width) || e.width <= 0 || !Number.isFinite(e.height) || e.height <= 0)
|
|
210
|
+
throw new Error("页面宽高必须是有限正数");
|
|
211
|
+
const o = z(e.idPrefix);
|
|
212
|
+
return {
|
|
213
|
+
meta: { width: e.width, height: e.height, source: "pptx", readonly: !1 },
|
|
214
|
+
identity: { prefix: o, nextSlide: 1, nextElement: 1, nextSpid: {} },
|
|
215
|
+
slides: {},
|
|
216
|
+
slideOrder: [],
|
|
217
|
+
layouts: {},
|
|
218
|
+
layoutOrder: [],
|
|
219
|
+
elements: {},
|
|
220
|
+
removedElements: {},
|
|
221
|
+
imageResources: {},
|
|
222
|
+
package: null,
|
|
223
|
+
saveState: { baselines: /* @__PURE__ */ Object.create(null), createdParts: [], sourceSlideParts: [] }
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function pe(e) {
|
|
227
|
+
for (; ; ) {
|
|
228
|
+
const o = `${X(e.identity)}s${(e.identity.nextSlide++).toString(36)}`;
|
|
229
|
+
if (!e.slides[o] && !e.elements[o]) return o;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function he(e) {
|
|
233
|
+
for (; ; ) {
|
|
234
|
+
const o = `${X(e.identity)}e${(e.identity.nextElement++).toString(36)}`;
|
|
235
|
+
if (!e.elements[o] && !e.slides[o]) return o;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function w(e, o) {
|
|
239
|
+
var t;
|
|
240
|
+
const a = e.package;
|
|
241
|
+
a !== o && (ee(e), te(e)), e.package = o, a !== o && ((t = a == null ? void 0 : a.dispose) == null || t.call(a));
|
|
242
|
+
}
|
|
243
|
+
function Se(e, o) {
|
|
244
|
+
if (o.disposed) throw new Error("不能采用已经释放的 OPC 包");
|
|
245
|
+
w(e, o), e.saveState.baselines = /* @__PURE__ */ Object.create(null), e.saveState.createdParts = [], e.saveState.sourceSlideParts = e.slideOrder.flatMap((a) => {
|
|
246
|
+
var t;
|
|
247
|
+
return ((t = e.slides[a].origin) == null ? void 0 : t.part) ?? [];
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function Ie(e, o, a, t) {
|
|
251
|
+
w(e, o), e.saveState.baselines = a, e.saveState.createdParts = t;
|
|
252
|
+
}
|
|
253
|
+
function be(e) {
|
|
254
|
+
var o;
|
|
255
|
+
B.has(e) || (B.add(e), (o = y.get(e)) == null || o(), y.delete(e), K(e), e.saveState.baselines = /* @__PURE__ */ Object.create(null), e.saveState.createdParts = [], e.saveState.sourceSlideParts = [], e.imageResources = {}, w(e, null));
|
|
256
|
+
}
|
|
257
|
+
export {
|
|
258
|
+
x as M,
|
|
259
|
+
de as a,
|
|
260
|
+
he as b,
|
|
261
|
+
Ie as c,
|
|
262
|
+
ie as d,
|
|
263
|
+
oe as e,
|
|
264
|
+
pe as f,
|
|
265
|
+
ne as g,
|
|
266
|
+
se as h,
|
|
267
|
+
ue as i,
|
|
268
|
+
le as j,
|
|
269
|
+
fe as k,
|
|
270
|
+
X as l,
|
|
271
|
+
me as m,
|
|
272
|
+
be as n,
|
|
273
|
+
Se as r
|
|
274
|
+
};
|