@lyads/visual-editor 0.0.0-stage → 1.0.1
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 +15 -0
- package/LICENSE +201 -0
- package/NOTICE +8 -0
- package/README.md +135 -2
- package/THIRD_PARTY_NOTICES.md +21259 -0
- package/dist/application/block-placement.d.ts +30 -0
- package/dist/application/block-session.d.ts +135 -0
- package/dist/application/content-service.d.ts +73 -0
- package/dist/application/document-commands.d.ts +51 -0
- package/dist/application/document-metadata.d.ts +30 -0
- package/dist/application/document-presentation.d.ts +35 -0
- package/dist/application/email-insertion.d.ts +76 -0
- package/dist/application/host.d.ts +36 -0
- package/dist/application/image-link.d.ts +36 -0
- package/dist/application/section-layout.d.ts +25 -0
- package/dist/application/session.d.ts +128 -0
- package/dist/assets/browser-worker-D56tNvnb.js +1014 -0
- package/dist/assets/browser-worker-D56tNvnb.js.map +1 -0
- package/dist/block-controller-RjYGvOcn.js +2468 -0
- package/dist/block-controller-RjYGvOcn.js.map +1 -0
- package/dist/block-factory-C5oHi4Fm.js +5397 -0
- package/dist/block-factory-C5oHi4Fm.js.map +1 -0
- package/dist/blocks/block-checks.d.ts +34 -0
- package/dist/blocks/block-inspector.d.ts +55 -0
- package/dist/blocks/block-output.d.ts +28 -0
- package/dist/blocks/block-type.d.ts +124 -0
- package/dist/blocks/content-guard.d.ts +52 -0
- package/dist/blocks/conversion.d.ts +22 -0
- package/dist/blocks/definitions.d.ts +43 -0
- package/dist/blocks/device-styles.d.ts +31 -0
- package/dist/blocks/email-generator.d.ts +22 -0
- package/dist/blocks/email-preview.d.ts +23 -0
- package/dist/blocks/email-renderer.d.ts +20 -0
- package/dist/blocks/fields.d.ts +34 -0
- package/dist/blocks/page-generator.d.ts +16 -0
- package/dist/blocks/render-context.d.ts +58 -0
- package/dist/blocks/styles.d.ts +54 -0
- package/dist/blocks/types/embed.d.ts +40 -0
- package/dist/blocks/types/layout.d.ts +41 -0
- package/dist/blocks/types/media.d.ts +53 -0
- package/dist/blocks/types/structure.d.ts +44 -0
- package/dist/blocks/types/text.d.ts +88 -0
- package/dist/blocks/values.d.ts +64 -0
- package/dist/browser.js +69 -0
- package/dist/browser.js.map +1 -0
- package/dist/canvas-runtime/action-bar.d.ts +19 -0
- package/dist/canvas-runtime/auto-scroll.d.ts +10 -0
- package/dist/canvas-runtime/block-drag.d.ts +29 -0
- package/dist/canvas-runtime/bridge.d.ts +6 -0
- package/dist/canvas-runtime/context.d.ts +53 -0
- package/dist/canvas-runtime/document-sync.d.ts +21 -0
- package/dist/canvas-runtime/drop-targets.d.ts +34 -0
- package/dist/canvas-runtime/embed-markers.d.ts +15 -0
- package/dist/canvas-runtime/file-guard.d.ts +12 -0
- package/dist/canvas-runtime/image-tools.d.ts +31 -0
- package/dist/canvas-runtime/keyboard.d.ts +18 -0
- package/dist/canvas-runtime/main.d.ts +1 -0
- package/dist/canvas-runtime/messages.d.ts +26 -0
- package/dist/canvas-runtime/morph.d.ts +21 -0
- package/dist/canvas-runtime/navigation.d.ts +29 -0
- package/dist/canvas-runtime/overlay.d.ts +15 -0
- package/dist/canvas-runtime/pointer-intents.d.ts +14 -0
- package/dist/canvas-runtime/selection-layer.d.ts +16 -0
- package/dist/canvas-runtime/shared/shortcuts.d.ts +27 -0
- package/dist/canvas-runtime/text-editor.d.ts +55 -0
- package/dist/canvas-runtime/text-session.d.ts +39 -0
- package/dist/canvas-runtime/variable-marks.d.ts +20 -0
- package/dist/canvas-runtime/viewport.d.ts +10 -0
- package/dist/codecs/css.d.ts +74 -0
- package/dist/codecs/html.d.ts +81 -0
- package/dist/compilation/browser-compiler.d.ts +14 -0
- package/dist/compilation/browser-worker.d.ts +1 -0
- package/dist/compilation/compile-lanes.d.ts +18 -0
- package/dist/compilation/generated-mjml.d.ts +25 -0
- package/dist/compilation/guard.d.ts +40 -0
- package/dist/compilation/node-compiler.d.ts +17 -0
- package/dist/compilation/node-worker.d.ts +1 -0
- package/dist/composition/block-factory.d.ts +84 -0
- package/dist/composition/browser.d.ts +48 -0
- package/dist/composition/factory.d.ts +48 -0
- package/dist/composition/server.d.ts +43 -0
- package/dist/core/any-document.d.ts +16 -0
- package/dist/core/block-document.d.ts +215 -0
- package/dist/core/budget.d.ts +32 -0
- package/dist/core/canvas-contract.d.ts +29 -0
- package/dist/core/canvas-layout.d.ts +66 -0
- package/dist/core/catalog.d.ts +35 -0
- package/dist/core/document-presentation.d.ts +21 -0
- package/dist/core/document.d.ts +99 -0
- package/dist/core/history.d.ts +26 -0
- package/dist/core/html-content-model.d.ts +32 -0
- package/dist/core/html-escape.d.ts +2 -0
- package/dist/core/rich-text-format.d.ts +14 -0
- package/dist/core/rich-text-markup.d.ts +28 -0
- package/dist/core/section-layout.d.ts +83 -0
- package/dist/generated-mjml-CtzE-f3v.js +1235 -0
- package/dist/generated-mjml-CtzE-f3v.js.map +1 -0
- package/dist/identity-CJHb6l9N.js +13759 -0
- package/dist/identity-CJHb6l9N.js.map +1 -0
- package/dist/renderers/canvas-bridge.d.ts +75 -0
- package/dist/renderers/canvas-icons.d.ts +1 -0
- package/dist/renderers/canvas-runtime.generated.d.ts +3 -0
- package/dist/renderers/element-source.d.ts +13 -0
- package/dist/renderers/email-renderer.d.ts +14 -0
- package/dist/renderers/marked-preview.d.ts +34 -0
- package/dist/renderers/markup-tree.d.ts +36 -0
- package/dist/renderers/page-renderer.d.ts +15 -0
- package/dist/renderers/preview-document.d.ts +39 -0
- package/dist/renderers/preview-frame.d.ts +102 -0
- package/dist/renderers/section-scaffold.d.ts +16 -0
- package/dist/renderers/selection-preview.d.ts +47 -0
- package/dist/rich-text/command-executor.d.ts +26 -0
- package/dist/rich-text/commands.d.ts +36 -0
- package/dist/rich-text/document-builder.d.ts +52 -0
- package/dist/rich-text/formatting.d.ts +17 -0
- package/dist/rich-text/projection-export.d.ts +17 -0
- package/dist/rich-text/projection-rules.d.ts +13 -0
- package/dist/rich-text/schema.d.ts +50 -0
- package/dist/rich-text/whitespace.d.ts +7 -0
- package/dist/security/bounded-parser.d.ts +18 -0
- package/dist/security/conditional-comment.d.ts +30 -0
- package/dist/security/content-inventory.d.ts +78 -0
- package/dist/security/email-sanitizer.d.ts +36 -0
- package/dist/security/identity.d.ts +6 -0
- package/dist/security/markup-rules.d.ts +31 -0
- package/dist/security/policy.d.ts +61 -0
- package/dist/security/preview-message.d.ts +317 -0
- package/dist/security/rich-text-projection.d.ts +19 -0
- package/dist/security/sha256.d.ts +6 -0
- package/dist/security/source-markup.d.ts +53 -0
- package/dist/security/text-presentation.d.ts +19 -0
- package/dist/security/url-policy.d.ts +23 -0
- package/dist/server-worker.js +17 -0
- package/dist/server-worker.js.map +1 -0
- package/dist/server.js +79 -0
- package/dist/server.js.map +1 -0
- package/dist/templates/blank-email.d.ts +6 -0
- package/dist/templates/blocks/catalog.d.ts +31 -0
- package/dist/templates/catalog.d.ts +31 -0
- package/dist/visual-editor.css +2 -0
- package/dist/vue/block-controller.d.ts +106 -0
- package/dist/vue/block-workbench.d.ts +70 -0
- package/dist/vue/canvas/canvas-theme.d.ts +8 -0
- package/dist/vue/canvas/file-drop.d.ts +38 -0
- package/dist/vue/canvas/frame-window.d.ts +26 -0
- package/dist/vue/canvas/inline-text.d.ts +98 -0
- package/dist/vue/canvas/palette-drag.d.ts +55 -0
- package/dist/vue/canvas/piece-requests.d.ts +48 -0
- package/dist/vue/canvas/strip-reserve.d.ts +14 -0
- package/dist/vue/canvas-content-label.d.ts +5 -0
- package/dist/vue/components/BlockVisualEditor.vue.d.ts +44 -0
- package/dist/vue/components/CanvasSurface.vue.d.ts +11 -0
- package/dist/vue/components/CodeEditor.vue.d.ts +22 -0
- package/dist/vue/components/EditorBlockMenus.vue.d.ts +3 -0
- package/dist/vue/components/EditorBlockPalette.vue.d.ts +3 -0
- package/dist/vue/components/EditorDiagnostics.vue.d.ts +3 -0
- package/dist/vue/components/EditorDialogs.vue.d.ts +16 -0
- package/dist/vue/components/EditorDocumentMetadata.vue.d.ts +3 -0
- package/dist/vue/components/EditorDocumentStyles.vue.d.ts +15 -0
- package/dist/vue/components/EditorImageSizeControls.vue.d.ts +23 -0
- package/dist/vue/components/EditorLayoutControls.vue.d.ts +16 -0
- package/dist/vue/components/EditorLeftPanel.vue.d.ts +3 -0
- package/dist/vue/components/EditorNoticeIndicator.vue.d.ts +3 -0
- package/dist/vue/components/EditorPreview.vue.d.ts +8 -0
- package/dist/vue/components/EditorProperties.vue.d.ts +14 -0
- package/dist/vue/components/EditorRichTextControls.vue.d.ts +25 -0
- package/dist/vue/components/EditorSelectionPath.vue.d.ts +11 -0
- package/dist/vue/components/EditorShortcutHelp.vue.d.ts +3 -0
- package/dist/vue/components/EditorSourcePane.vue.d.ts +3 -0
- package/dist/vue/components/EditorStructureTree.vue.d.ts +3 -0
- package/dist/vue/components/EditorTemplateGallery.vue.d.ts +15 -0
- package/dist/vue/components/EditorTopBar.vue.d.ts +33 -0
- package/dist/vue/components/RichTextEditor.vue.d.ts +47 -0
- package/dist/vue/components/SelectionPreviewFrame.vue.d.ts +212 -0
- package/dist/vue/components/VisualEditor.vue.d.ts +53 -0
- package/dist/vue/components/blocks/BlockCanvas.vue.d.ts +15 -0
- package/dist/vue/components/blocks/BlockFieldControl.vue.d.ts +39 -0
- package/dist/vue/components/blocks/BlockGlobalStyles.vue.d.ts +3 -0
- package/dist/vue/components/blocks/BlockPalette.vue.d.ts +6 -0
- package/dist/vue/components/blocks/BlockProperties.vue.d.ts +5 -0
- package/dist/vue/components/blocks/BlockReview.vue.d.ts +5 -0
- package/dist/vue/components/properties/EditorPropertyAdvanced.vue.d.ts +8 -0
- package/dist/vue/components/properties/EditorPropertyContent.vue.d.ts +13 -0
- package/dist/vue/components/properties/EditorPropertyStyle.vue.d.ts +8 -0
- package/dist/vue/components/ui/EditorAnchoredMenu.vue.d.ts +36 -0
- package/dist/vue/components/ui/EditorBadge.vue.d.ts +18 -0
- package/dist/vue/components/ui/EditorButton.vue.d.ts +28 -0
- package/dist/vue/components/ui/EditorCheckbox.vue.d.ts +13 -0
- package/dist/vue/components/ui/EditorColorInput.vue.d.ts +27 -0
- package/dist/vue/components/ui/EditorConfirmDialog.vue.d.ts +35 -0
- package/dist/vue/components/ui/EditorContextMenu.vue.d.ts +27 -0
- package/dist/vue/components/ui/EditorContextPopover.vue.d.ts +33 -0
- package/dist/vue/components/ui/EditorEmpty.vue.d.ts +8 -0
- package/dist/vue/components/ui/EditorField.vue.d.ts +24 -0
- package/dist/vue/components/ui/EditorGroup.vue.d.ts +16 -0
- package/dist/vue/components/ui/EditorIcon.vue.d.ts +6 -0
- package/dist/vue/components/ui/EditorIconButton.vue.d.ts +19 -0
- package/dist/vue/components/ui/EditorInput.vue.d.ts +41 -0
- package/dist/vue/components/ui/EditorKeys.vue.d.ts +6 -0
- package/dist/vue/components/ui/EditorMeasurement.vue.d.ts +34 -0
- package/dist/vue/components/ui/EditorMenu.vue.d.ts +56 -0
- package/dist/vue/components/ui/EditorNotice.vue.d.ts +30 -0
- package/dist/vue/components/ui/EditorPropertyGroup.vue.d.ts +22 -0
- package/dist/vue/components/ui/EditorRecoveryDialog.vue.d.ts +23 -0
- package/dist/vue/components/ui/EditorScrollArea.vue.d.ts +13 -0
- package/dist/vue/components/ui/EditorSelect.vue.d.ts +25 -0
- package/dist/vue/components/ui/EditorSeparator.vue.d.ts +8 -0
- package/dist/vue/components/ui/EditorSidePanel.vue.d.ts +26 -0
- package/dist/vue/components/ui/EditorSwitch.vue.d.ts +12 -0
- package/dist/vue/components/ui/EditorTabs.vue.d.ts +28 -0
- package/dist/vue/components/ui/EditorTemplatePreview.vue.d.ts +9 -0
- package/dist/vue/components/ui/EditorTextToolbar.vue.d.ts +16 -0
- package/dist/vue/components/ui/EditorTree.vue.d.ts +37 -0
- package/dist/vue/components/ui/EditorUiProvider.vue.d.ts +13 -0
- package/dist/vue/components/ui/EditorVariablePicker.vue.d.ts +20 -0
- package/dist/vue/components/ui/color-style-value.d.ts +9 -0
- package/dist/vue/components/ui/composition-dismissal.d.ts +1 -0
- package/dist/vue/components/ui/editor-dialog-focus.d.ts +6 -0
- package/dist/vue/components/ui/numeric-style-value.d.ts +15 -0
- package/dist/vue/controller.d.ts +115 -0
- package/dist/vue/font-options.d.ts +6 -0
- package/dist/vue/icon-data.d.ts +233 -0
- package/dist/vue/icons.d.ts +5 -0
- package/dist/vue/locale.d.ts +7 -0
- package/dist/vue/outline.d.ts +26 -0
- package/dist/vue/projection-key.d.ts +7 -0
- package/dist/vue/properties/selection-properties.d.ts +40 -0
- package/dist/vue/properties/style-fields.d.ts +30 -0
- package/dist/vue/public.d.ts +14 -0
- package/dist/vue/recovery.d.ts +30 -0
- package/dist/vue/responsive-panel.d.ts +1 -0
- package/dist/vue/rich-text-commands.d.ts +29 -0
- package/dist/vue/services/block-command-definitions.d.ts +14 -0
- package/dist/vue/services/block-commands.d.ts +114 -0
- package/dist/vue/services/block-menu.d.ts +12 -0
- package/dist/vue/services/block-palette.d.ts +21 -0
- package/dist/vue/services/block-presentation.d.ts +16 -0
- package/dist/vue/services/diagnostic-groups.d.ts +25 -0
- package/dist/vue/services/image-requests.d.ts +80 -0
- package/dist/vue/services/live-change.d.ts +26 -0
- package/dist/vue/services/property-commands.d.ts +28 -0
- package/dist/vue/services/saved-blocks.d.ts +32 -0
- package/dist/vue/services/selection-path.d.ts +20 -0
- package/dist/vue/services/shortcuts.d.ts +39 -0
- package/dist/vue/services/structure-tree.d.ts +38 -0
- package/dist/vue/services/template-application.d.ts +33 -0
- package/dist/vue/services/tree-drag.d.ts +28 -0
- package/dist/vue/session/blocks.d.ts +44 -0
- package/dist/vue/session/guard.d.ts +13 -0
- package/dist/vue/session/structure.d.ts +36 -0
- package/dist/vue/session/text.d.ts +23 -0
- package/dist/vue/session/transfer.d.ts +23 -0
- package/dist/vue/theme.d.ts +20 -0
- package/dist/vue/variables.d.ts +21 -0
- package/dist/vue/workbench.d.ts +100 -0
- package/dist/vue.js +71418 -0
- package/dist/vue.js.map +1 -0
- package/package.json +125 -4
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BlockDocument, BlockNodeType, BlockRules, BlockTarget } from '../core/block-document';
|
|
2
|
+
export type BlockPlacement = 'before' | 'after' | 'inside';
|
|
3
|
+
/** Where a block may land next to or inside one other block. */
|
|
4
|
+
export interface BlockPlacementTarget {
|
|
5
|
+
readonly targetId: string;
|
|
6
|
+
readonly placements: readonly BlockPlacement[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Where a block may go, by the rules of the block types: the drop targets of a drag, of a block
|
|
10
|
+
* from the palette and the single step of "move up/down". Nothing here changes the piece; the
|
|
11
|
+
* aggregate checks every command again.
|
|
12
|
+
*/
|
|
13
|
+
export declare class BlockPlacementService {
|
|
14
|
+
private readonly rules;
|
|
15
|
+
constructor(rules: BlockRules);
|
|
16
|
+
/** Targets for an existing block: never inside itself, never leaving a parent too empty. */
|
|
17
|
+
movementTargets(document: BlockDocument, id: string): readonly BlockPlacementTarget[];
|
|
18
|
+
/** Targets for a new block of a type. */
|
|
19
|
+
insertionTargets(document: BlockDocument, type: BlockNodeType): readonly BlockPlacementTarget[];
|
|
20
|
+
/** The command target of a placement next to or inside a block. */
|
|
21
|
+
target(targetId: string, placement: BlockPlacement): BlockTarget;
|
|
22
|
+
/**
|
|
23
|
+
* One step up or down: past the sibling on that side, or, at the edge of its parent, into the
|
|
24
|
+
* neighbouring container of the same type (the next column or section).
|
|
25
|
+
*/
|
|
26
|
+
step(document: BlockDocument, id: string, direction: 'up' | 'down'): BlockTarget | undefined;
|
|
27
|
+
private targets;
|
|
28
|
+
private accepts;
|
|
29
|
+
private locate;
|
|
30
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { BlockDocument } from '../core/block-document';
|
|
2
|
+
import type { Block, BlockDevice, BlockDocumentData, BlockNodeType, BlockProps, BlockTarget, StylePatch } from '../core/block-document';
|
|
3
|
+
import type { Diagnostic, SourceInput } from '../core/document';
|
|
4
|
+
import { DocumentHistory } from '../core/history';
|
|
5
|
+
/** The final output of a piece: the compiled e-mail, or the HTML and CSS of the page. */
|
|
6
|
+
export interface BlockOutputPort {
|
|
7
|
+
render(document: BlockDocument): Promise<SourceInput>;
|
|
8
|
+
}
|
|
9
|
+
/** Where the host keeps a block piece, with the output generated from it. */
|
|
10
|
+
export interface BlockStorePort {
|
|
11
|
+
save(document: BlockDocumentData, output: SourceInput, expectedRevision: number, signal?: AbortSignal): Promise<{
|
|
12
|
+
revision: number;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
/** Creates the blocks of each type and says which keys hold a text edited in place. */
|
|
16
|
+
export interface BlockFactoryPort {
|
|
17
|
+
create(type: BlockNodeType, nextId: () => string, props?: BlockProps): Block;
|
|
18
|
+
textKeys(type: BlockNodeType): readonly string[];
|
|
19
|
+
}
|
|
20
|
+
export interface IdentifierPort {
|
|
21
|
+
next(): string;
|
|
22
|
+
}
|
|
23
|
+
/** An image chosen for a block: the asset of the host, when there is one. */
|
|
24
|
+
export interface BlockImageChoice {
|
|
25
|
+
readonly url: string;
|
|
26
|
+
readonly alt?: string;
|
|
27
|
+
readonly assetId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface BlockEditorState {
|
|
30
|
+
readonly document: BlockDocumentData;
|
|
31
|
+
readonly selectedBlockId: string | undefined;
|
|
32
|
+
/** The text being edited in place, until it is confirmed or cancelled. */
|
|
33
|
+
readonly pendingText: {
|
|
34
|
+
readonly id: string;
|
|
35
|
+
readonly key: string;
|
|
36
|
+
} | undefined;
|
|
37
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
38
|
+
readonly canUndo: boolean;
|
|
39
|
+
readonly canRedo: boolean;
|
|
40
|
+
readonly readOnly: boolean;
|
|
41
|
+
readonly dirty: boolean;
|
|
42
|
+
readonly saving: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface BlockSessionServices {
|
|
45
|
+
readonly factory: BlockFactoryPort;
|
|
46
|
+
readonly output: BlockOutputPort;
|
|
47
|
+
readonly identifiers: IdentifierPort;
|
|
48
|
+
readonly store?: BlockStorePort;
|
|
49
|
+
readonly history?: DocumentHistory<BlockDocument>;
|
|
50
|
+
}
|
|
51
|
+
export interface BlockSessionOptions {
|
|
52
|
+
readonly document: BlockDocument;
|
|
53
|
+
readonly readOnly?: boolean;
|
|
54
|
+
readonly persistedRevision?: number;
|
|
55
|
+
readonly onObserverError?: (error: unknown) => void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The editing session of a block piece (schema 2), beside the session of the HTML document
|
|
59
|
+
* (schema 1). Every command is one step of history; the document is the immutable aggregate,
|
|
60
|
+
* so a refused command changes nothing. Undoing moves forward in revision, as in schema 1, so a
|
|
61
|
+
* host saving by compare-and-swap never goes back.
|
|
62
|
+
*/
|
|
63
|
+
export declare class BlockEditorSession {
|
|
64
|
+
#private;
|
|
65
|
+
private readonly services;
|
|
66
|
+
private readonly options;
|
|
67
|
+
constructor(services: BlockSessionServices, options: BlockSessionOptions);
|
|
68
|
+
/** The current piece; immutable, so it can be handed to generators as it is. */
|
|
69
|
+
document(): BlockDocument;
|
|
70
|
+
snapshot(): BlockDocumentData;
|
|
71
|
+
getState(): BlockEditorState;
|
|
72
|
+
subscribe(listener: (state: BlockEditorState) => void): () => void;
|
|
73
|
+
setReadOnly(value: boolean): void;
|
|
74
|
+
select(id: string | undefined): boolean;
|
|
75
|
+
/** A new block of a type; it becomes the selection. Returns its id, or undefined. */
|
|
76
|
+
insert(type: BlockNodeType, target: BlockTarget, props?: BlockProps): string | undefined;
|
|
77
|
+
/** A block with its children, made with ids of `newId()`; it becomes the selection. */
|
|
78
|
+
insertBlock(block: Block, target: BlockTarget): string | undefined;
|
|
79
|
+
/** A new block id, unique in practice: 80 random bits. */
|
|
80
|
+
newId(): string;
|
|
81
|
+
move(id: string, target: BlockTarget): boolean;
|
|
82
|
+
duplicate(id: string): boolean;
|
|
83
|
+
remove(id: string): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Properties of a block in one step. A new address typed by hand (`url` without `assetId`)
|
|
86
|
+
* no longer points at the asset of the host library chosen before: that asset goes in the
|
|
87
|
+
* same step, so the host never keeps a stale reference.
|
|
88
|
+
*/
|
|
89
|
+
updateProps(id: string, patch: BlockProps, device?: BlockDevice): boolean;
|
|
90
|
+
restoreDefault(id: string, keys: readonly string[], device?: BlockDevice): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Address, description and asset of an image in one step of history. What the choice does
|
|
93
|
+
* not bring goes: the description and the asset of the previous image never describe the new
|
|
94
|
+
* one.
|
|
95
|
+
*/
|
|
96
|
+
replaceImage(id: string, choice: BlockImageChoice): boolean;
|
|
97
|
+
updateStyles(patch: StylePatch): boolean;
|
|
98
|
+
restoreStyleDefault(group?: string, keys?: readonly string[]): boolean;
|
|
99
|
+
setLanguage(lang: string): boolean;
|
|
100
|
+
setTitle(title: string): boolean;
|
|
101
|
+
/** A whole piece of the same kind and id, e.g. made from a template: one step of history. */
|
|
102
|
+
replace(document: BlockDocument): boolean;
|
|
103
|
+
/** Opens the text of a block for editing in place. */
|
|
104
|
+
beginText(id: string): boolean;
|
|
105
|
+
updateTextDraft(html: string): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Confirms the text being edited: the block takes it in the projection of its type. A refused
|
|
108
|
+
* text stays open as it was typed, with the diagnostic, as in the HTML document: nothing the
|
|
109
|
+
* person wrote is lost because the piece did not accept it.
|
|
110
|
+
*/
|
|
111
|
+
commitText(): boolean;
|
|
112
|
+
cancelText(): void;
|
|
113
|
+
undo(): boolean;
|
|
114
|
+
redo(): boolean;
|
|
115
|
+
/** Generates the final output and hands both to the host store. */
|
|
116
|
+
save(): Promise<boolean>;
|
|
117
|
+
/**
|
|
118
|
+
* As `save`, returning the exact piece the store received (changes made while it was being
|
|
119
|
+
* saved are not in it), or undefined when nothing was saved.
|
|
120
|
+
*/
|
|
121
|
+
saveDocument(): Promise<BlockDocumentData | undefined>;
|
|
122
|
+
dispose(): void;
|
|
123
|
+
private change;
|
|
124
|
+
/** The piece a command makes, or undefined (with the diagnostic) when it is refused. */
|
|
125
|
+
private attempt;
|
|
126
|
+
private apply;
|
|
127
|
+
private restore;
|
|
128
|
+
private commit;
|
|
129
|
+
private textChanged;
|
|
130
|
+
private fail;
|
|
131
|
+
private canWrite;
|
|
132
|
+
private assertActive;
|
|
133
|
+
private emit;
|
|
134
|
+
private deliver;
|
|
135
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { EditorDocument } from '../core/document';
|
|
2
|
+
import type { RichTextDecorationLine } from '../core/rich-text-format';
|
|
3
|
+
import type { Diagnostic, DocumentKind, DocumentNode, EditorDocumentData, ImportResult, SourceInput } from '../core/document';
|
|
4
|
+
export interface CodecPort {
|
|
5
|
+
import(source: SourceInput, kind: DocumentKind, previous?: EditorDocumentData): ImportResult;
|
|
6
|
+
export(document: EditorDocumentData | EditorDocument): SourceInput;
|
|
7
|
+
/** Auxiliary parse which must not replace the preserved source of an edited document. */
|
|
8
|
+
inspect?(source: SourceInput, kind: DocumentKind): ImportResult;
|
|
9
|
+
}
|
|
10
|
+
export interface PolicyPort {
|
|
11
|
+
validate(document: EditorDocumentData | EditorDocument): readonly Diagnostic[];
|
|
12
|
+
assertSafe(document: EditorDocumentData | EditorDocument): void;
|
|
13
|
+
/** Whether editor commands may write these nodes; stricter than what an import keeps. */
|
|
14
|
+
writable?(nodes: readonly DocumentNode[]): boolean;
|
|
15
|
+
/** Applies the removals of the document kind and says, grouped, what was removed. */
|
|
16
|
+
sanitize?(document: EditorDocumentData | EditorDocument): AdmittedDocumentData;
|
|
17
|
+
}
|
|
18
|
+
export interface AdmittedDocumentData {
|
|
19
|
+
readonly document: EditorDocumentData;
|
|
20
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
21
|
+
}
|
|
22
|
+
export interface AdmittedDocument {
|
|
23
|
+
readonly document: EditorDocument;
|
|
24
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
25
|
+
}
|
|
26
|
+
export interface InlineStylePort {
|
|
27
|
+
setDeclaration(css: string, property: string, value: string): string;
|
|
28
|
+
readDeclarations?(css: string): Readonly<Record<string, string>>;
|
|
29
|
+
removeDeclarations?(css: string, properties: readonly string[]): string;
|
|
30
|
+
prependDefaults(existing: string, incoming: readonly string[]): string;
|
|
31
|
+
richTextStyles?(css: string): Readonly<Record<string, string>> | undefined;
|
|
32
|
+
removeDecoration?(css: string, line: RichTextDecorationLine): string;
|
|
33
|
+
hasDecorationRules?(css: string): boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare class ContentService {
|
|
36
|
+
private readonly codec;
|
|
37
|
+
private readonly policy;
|
|
38
|
+
private readonly styles;
|
|
39
|
+
constructor(codec: CodecPort, policy: PolicyPort, styles: InlineStylePort);
|
|
40
|
+
import(source: SourceInput, kind: DocumentKind, previous?: EditorDocumentData): ImportResult;
|
|
41
|
+
/** Imports a snippet or projection which never becomes the session document by itself. */
|
|
42
|
+
inspect(source: SourceInput, kind: DocumentKind): ImportResult;
|
|
43
|
+
validate(document: EditorDocumentData | EditorDocument): readonly Diagnostic[];
|
|
44
|
+
setStyle(css: string, property: string, value: string): string;
|
|
45
|
+
withoutStyles(css: string, properties: readonly string[]): string;
|
|
46
|
+
inlineDeclarations(css: string): Readonly<Record<string, string>>;
|
|
47
|
+
richTextStyles(css: string): Readonly<Record<string, string>> | undefined;
|
|
48
|
+
removeDecoration(css: string, line: RichTextDecorationLine): string;
|
|
49
|
+
hasDecorationRules(css: string): boolean;
|
|
50
|
+
mergeRichTextStyle(existing: string, incoming: string): string;
|
|
51
|
+
addDefaultStyles(css: string, incoming: readonly string[]): string;
|
|
52
|
+
/**
|
|
53
|
+
* Entry of a document which did not come from this session: host JSON, a file, a backup.
|
|
54
|
+
* It follows the same rules as imported source. An e-mail which still carries scripts,
|
|
55
|
+
* embeds, handlers or code URLs has them removed and reported, never silently accepted.
|
|
56
|
+
*/
|
|
57
|
+
admit(input: unknown): AdmittedDocument;
|
|
58
|
+
/**
|
|
59
|
+
* Markup produced by a command or returned by the editing frame is held to the strict
|
|
60
|
+
* rule, whatever the document kind keeps from an import.
|
|
61
|
+
*/
|
|
62
|
+
assertWritable(nodes: readonly DocumentNode[]): void;
|
|
63
|
+
document(input: unknown): EditorDocument;
|
|
64
|
+
export(document: EditorDocumentData | EditorDocument): SourceInput;
|
|
65
|
+
/**
|
|
66
|
+
* Source and notices of a document about to become the current one, validated once here
|
|
67
|
+
* (the codec asserts the policy again and verifies its output by reparse).
|
|
68
|
+
*/
|
|
69
|
+
render(document: EditorDocument): {
|
|
70
|
+
readonly source: SourceInput;
|
|
71
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { EditorDocumentData, SourceInput } from '../core/document';
|
|
2
|
+
import { EditorDocument } from '../core/document';
|
|
3
|
+
import { BlockCatalog } from '../core/catalog';
|
|
4
|
+
import type { BlockType } from '../core/catalog';
|
|
5
|
+
import { ContentService } from './content-service';
|
|
6
|
+
import type { EmailInsertionUnit } from './email-insertion';
|
|
7
|
+
import type { AssetReference } from './host';
|
|
8
|
+
/** Source of a block to insert. Generated e-mail blocks may state the unit they stand for. */
|
|
9
|
+
export interface InsertionSource extends SourceInput {
|
|
10
|
+
readonly insertion?: EmailInsertionUnit;
|
|
11
|
+
}
|
|
12
|
+
export declare class DocumentMutationService {
|
|
13
|
+
private readonly content;
|
|
14
|
+
private readonly catalog;
|
|
15
|
+
private sequence;
|
|
16
|
+
private readonly formats;
|
|
17
|
+
private readonly markup;
|
|
18
|
+
private readonly emails;
|
|
19
|
+
constructor(content: ContentService, catalog: BlockCatalog);
|
|
20
|
+
text(document: EditorDocumentData, id: string, value: string): EditorDocument;
|
|
21
|
+
canEditRichText(document: EditorDocumentData, id: string): boolean;
|
|
22
|
+
validateRichTextProjection(document: EditorDocumentData, id: string, html: string): void;
|
|
23
|
+
richText(document: EditorDocumentData, id: string, html: string): EditorDocument;
|
|
24
|
+
attribute(document: EditorDocumentData, id: string, name: string, value: string): EditorDocument;
|
|
25
|
+
style(document: EditorDocumentData, id: string, property: string, value: string): EditorDocument;
|
|
26
|
+
connectFormReference(document: EditorDocumentData, reference: string, id?: string, parentId?: string, index?: number): EditorDocument;
|
|
27
|
+
attachAsset(document: EditorDocumentData, asset: AssetReference, id?: string, parentId?: string, index?: number): EditorDocument;
|
|
28
|
+
insert(document: EditorDocumentData, source: InsertionSource, parentId?: string, index?: number): EditorDocument;
|
|
29
|
+
add(document: EditorDocumentData, type: BlockType, parentId?: string, index?: number): EditorDocument;
|
|
30
|
+
remove(document: EditorDocumentData, id: string): EditorDocument;
|
|
31
|
+
duplicate(document: EditorDocumentData, id: string): EditorDocument;
|
|
32
|
+
move(document: EditorDocumentData, id: string, parentId: string | undefined, index: number): EditorDocument;
|
|
33
|
+
private richTextChildren;
|
|
34
|
+
private insertionNodes;
|
|
35
|
+
private restoreRichAttributes;
|
|
36
|
+
private mutate;
|
|
37
|
+
private next;
|
|
38
|
+
private id;
|
|
39
|
+
private hidden;
|
|
40
|
+
private position;
|
|
41
|
+
private find;
|
|
42
|
+
private findTag;
|
|
43
|
+
private parent;
|
|
44
|
+
private body;
|
|
45
|
+
private assertText;
|
|
46
|
+
private assertStructuralEdit;
|
|
47
|
+
private assertParent;
|
|
48
|
+
private unique;
|
|
49
|
+
private mutable;
|
|
50
|
+
private copyNode;
|
|
51
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EditorDocumentData } from '../core/document';
|
|
2
|
+
import { EditorDocument } from '../core/document';
|
|
3
|
+
import { ContentService } from './content-service';
|
|
4
|
+
export interface DocumentMetadata {
|
|
5
|
+
readonly title: string;
|
|
6
|
+
/** Hidden preview text of an e-mail; undefined for a page, empty when there is none. */
|
|
7
|
+
readonly preheader: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface MetadataIdentityPort {
|
|
10
|
+
next(): string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Title and preheader are part of what a recipient receives, so they are document content
|
|
14
|
+
* edited by commands like any other, never sample text left behind by a template.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DocumentMetadataService {
|
|
17
|
+
private readonly content;
|
|
18
|
+
private readonly identifiers;
|
|
19
|
+
constructor(content: ContentService, identifiers: MetadataIdentityPort);
|
|
20
|
+
read(document: EditorDocumentData): DocumentMetadata;
|
|
21
|
+
title(document: EditorDocumentData, value: string): EditorDocument;
|
|
22
|
+
preheader(document: EditorDocumentData, value: string): EditorDocument;
|
|
23
|
+
/** The first content of the body when it is a hidden block which only holds text. */
|
|
24
|
+
private preheaderNode;
|
|
25
|
+
private next;
|
|
26
|
+
private text;
|
|
27
|
+
private control;
|
|
28
|
+
private findTag;
|
|
29
|
+
private copy;
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DOCUMENT_STYLE_PROPERTIES } from '../core/document-presentation';
|
|
2
|
+
import type { DocumentStyleProperty, ImageSizeSettings } from '../core/document-presentation';
|
|
3
|
+
import { EditorDocument } from '../core/document';
|
|
4
|
+
import type { EditorDocumentData } from '../core/document';
|
|
5
|
+
import { ContentService } from './content-service';
|
|
6
|
+
export { IMAGE_SIZE_LIMITS, DOCUMENT_STYLE_PROPERTIES } from '../core/document-presentation';
|
|
7
|
+
export type { DocumentStyleProperty, ImageSizeSettings } from '../core/document-presentation';
|
|
8
|
+
export interface ImageSizeContext {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly width?: number;
|
|
11
|
+
readonly height?: number;
|
|
12
|
+
readonly ratio?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface DocumentStyleContext {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly properties: typeof DOCUMENT_STYLE_PROPERTIES;
|
|
17
|
+
readonly originalProperties: readonly DocumentStyleProperty[];
|
|
18
|
+
readonly values: Readonly<Partial<Record<DocumentStyleProperty, string>>>;
|
|
19
|
+
}
|
|
20
|
+
/** Presentation changes are one validated document transaction, never DOM mutations. */
|
|
21
|
+
export declare class DocumentPresentationService {
|
|
22
|
+
private readonly content;
|
|
23
|
+
private readonly settings;
|
|
24
|
+
constructor(content: ContentService);
|
|
25
|
+
image(document: EditorDocumentData, id: string): ImageSizeContext | undefined;
|
|
26
|
+
resize(document: EditorDocumentData, id: string, input: ImageSizeSettings): EditorDocument;
|
|
27
|
+
styles(document: EditorDocumentData): DocumentStyleContext | undefined;
|
|
28
|
+
style(document: EditorDocumentData, property: DocumentStyleProperty, value: string): EditorDocument;
|
|
29
|
+
private ratio;
|
|
30
|
+
private pixels;
|
|
31
|
+
private number;
|
|
32
|
+
private find;
|
|
33
|
+
private all;
|
|
34
|
+
private change;
|
|
35
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { DocumentNode } from '../core/document';
|
|
2
|
+
export interface MutableNode {
|
|
3
|
+
id: string;
|
|
4
|
+
type: DocumentNode['type'];
|
|
5
|
+
tag?: string;
|
|
6
|
+
value?: string;
|
|
7
|
+
attrs?: Record<string, string>;
|
|
8
|
+
children?: MutableNode[];
|
|
9
|
+
metadata?: NonNullable<DocumentNode['metadata']>;
|
|
10
|
+
}
|
|
11
|
+
/** The unit a generated e-mail block is meant to be inserted as. */
|
|
12
|
+
export type EmailInsertionUnit = 'content' | 'section';
|
|
13
|
+
interface EmailColumn<T> {
|
|
14
|
+
/** Presentation table owned by the column; its body holds one row per content element. */
|
|
15
|
+
readonly table: T;
|
|
16
|
+
readonly body: T;
|
|
17
|
+
readonly rows: readonly T[];
|
|
18
|
+
}
|
|
19
|
+
export interface CompiledEmailBlock {
|
|
20
|
+
/** False for plain snippets, which keep the generic insertion rules. */
|
|
21
|
+
readonly compiled: boolean;
|
|
22
|
+
/** Section-level sequence: sections and their Outlook conditional comments. */
|
|
23
|
+
readonly units: readonly DocumentNode[];
|
|
24
|
+
/** Undefined when a compiled section has a shape this planner does not know. */
|
|
25
|
+
readonly columns: readonly EmailColumn<DocumentNode>[] | undefined;
|
|
26
|
+
}
|
|
27
|
+
export interface EmailInsertionPlan {
|
|
28
|
+
readonly parent: MutableNode | undefined;
|
|
29
|
+
readonly target: MutableNode[];
|
|
30
|
+
readonly index: number;
|
|
31
|
+
readonly nodes: readonly DocumentNode[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Chooses what a generated e-mail block contributes to a destination. Inside a column or
|
|
35
|
+
* cell only content rows travel; at section level the section goes with its balanced pair of
|
|
36
|
+
* Outlook comments. The preheader, the title and the article wrapper of the compiled block
|
|
37
|
+
* never enter the document. Anything that cannot be placed safely is refused.
|
|
38
|
+
*/
|
|
39
|
+
export declare class EmailInsertionPlanner {
|
|
40
|
+
private readonly id;
|
|
41
|
+
private readonly hidden;
|
|
42
|
+
constructor(id: () => string, hidden: (style: string) => boolean);
|
|
43
|
+
block(body: readonly DocumentNode[]): CompiledEmailBlock;
|
|
44
|
+
place(roots: MutableNode[], parent: MutableNode | undefined, index: number | undefined, block: CompiledEmailBlock, requested?: EmailInsertionUnit): EmailInsertionPlan;
|
|
45
|
+
/** A new image is born inside the content unit generated image blocks use. */
|
|
46
|
+
placeImage(roots: MutableNode[], parent: MutableNode | undefined, index: number | undefined, image: MutableNode): EmailInsertionPlan;
|
|
47
|
+
/**
|
|
48
|
+
* Where content rows go when the destination is part of a recognized section: after the
|
|
49
|
+
* selected row of a column, or at the end of the last column when the section shell (its
|
|
50
|
+
* row or the cell which holds the columns) was selected. A cell beside the selected row,
|
|
51
|
+
* or flow content between the Outlook ghost cells, would break the column layout.
|
|
52
|
+
*/
|
|
53
|
+
private rowHost;
|
|
54
|
+
private sectionLevel;
|
|
55
|
+
/**
|
|
56
|
+
* Between two sections one comment closes a ghost table and opens the next. It becomes
|
|
57
|
+
* its two halves, so a new section fits between them with a pair of its own.
|
|
58
|
+
*/
|
|
59
|
+
private splitBridge;
|
|
60
|
+
private assertBalanced;
|
|
61
|
+
/** Flow content next to Outlook ghost cells would land in the wrong table for one client. */
|
|
62
|
+
private assertFlowDestination;
|
|
63
|
+
private columns;
|
|
64
|
+
private descend;
|
|
65
|
+
private conditional;
|
|
66
|
+
private layoutUnit;
|
|
67
|
+
private wrapper;
|
|
68
|
+
private preheader;
|
|
69
|
+
private blank;
|
|
70
|
+
private trim;
|
|
71
|
+
private position;
|
|
72
|
+
private find;
|
|
73
|
+
/** Ancestors of the node, outermost first and ending with the node itself. */
|
|
74
|
+
private chain;
|
|
75
|
+
}
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { EditorDocumentData, SourceInput } from '../core/document';
|
|
2
|
+
export interface AssetReference {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly url: string;
|
|
5
|
+
readonly alt: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AssetPort {
|
|
8
|
+
upload(file: File, signal?: AbortSignal): Promise<AssetReference>;
|
|
9
|
+
resolve(id: string, signal?: AbortSignal): Promise<{
|
|
10
|
+
url: string;
|
|
11
|
+
alt: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export interface StorePort {
|
|
15
|
+
save(document: EditorDocumentData, source: SourceInput, expectedRevision: number, signal?: AbortSignal): Promise<{
|
|
16
|
+
revision: number;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export interface SlotsPort {
|
|
20
|
+
resolve(kind: 'form' | 'footer', id: string, signal?: AbortSignal): Promise<string>;
|
|
21
|
+
}
|
|
22
|
+
export interface HostAdapters {
|
|
23
|
+
assets?: AssetPort;
|
|
24
|
+
store?: StorePort;
|
|
25
|
+
slots?: SlotsPort;
|
|
26
|
+
}
|
|
27
|
+
export declare class HostIntegration {
|
|
28
|
+
private readonly adapters;
|
|
29
|
+
private saveSequence;
|
|
30
|
+
private active;
|
|
31
|
+
constructor(adapters?: HostAdapters);
|
|
32
|
+
save(document: EditorDocumentData, source: SourceInput, expectedRevision: number): Promise<number | undefined>;
|
|
33
|
+
get assets(): AssetPort | undefined;
|
|
34
|
+
get slots(): SlotsPort | undefined;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { EditorDocumentData } from '../core/document';
|
|
2
|
+
import { EditorDocument } from '../core/document';
|
|
3
|
+
import { ContentService } from './content-service';
|
|
4
|
+
export interface ImageLinkOptions {
|
|
5
|
+
readonly target?: '_blank' | '_self';
|
|
6
|
+
}
|
|
7
|
+
export interface ImageLinkContext {
|
|
8
|
+
readonly imageId: string;
|
|
9
|
+
readonly anchorId?: string;
|
|
10
|
+
readonly href: string;
|
|
11
|
+
readonly target: string;
|
|
12
|
+
readonly rel: string;
|
|
13
|
+
readonly shared: boolean;
|
|
14
|
+
readonly editable: boolean;
|
|
15
|
+
readonly reason?: 'shared-structure' | 'shared-identity' | 'nested-link';
|
|
16
|
+
}
|
|
17
|
+
export interface ImageLinkUrlPort {
|
|
18
|
+
isSafe(value: string, purpose: 'link'): boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ImageLinkIdentityPort {
|
|
21
|
+
next(): string;
|
|
22
|
+
}
|
|
23
|
+
/** Changes the link of one image while retaining unrelated content and link destinations. */
|
|
24
|
+
export declare class ImageLinkService {
|
|
25
|
+
private readonly content;
|
|
26
|
+
private readonly urls;
|
|
27
|
+
private readonly identifiers;
|
|
28
|
+
constructor(content: ContentService, urls: ImageLinkUrlPort, identifiers: ImageLinkIdentityPort);
|
|
29
|
+
context(document: EditorDocumentData, imageId: string): ImageLinkContext | undefined;
|
|
30
|
+
update(document: EditorDocumentData, imageId: string, href: string, options?: ImageLinkOptions): EditorDocument;
|
|
31
|
+
private attributes;
|
|
32
|
+
private locate;
|
|
33
|
+
private substantive;
|
|
34
|
+
private path;
|
|
35
|
+
private replace;
|
|
36
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EditorDocument } from '../core/document';
|
|
2
|
+
import type { EditorDocumentData, SourceInput } from '../core/document';
|
|
3
|
+
import type { SectionLayoutContext, SectionLayoutPatch, SectionLayoutProjection, SectionLayoutSettings } from '../core/section-layout';
|
|
4
|
+
import { ContentService } from './content-service';
|
|
5
|
+
export interface SectionScaffoldPort {
|
|
6
|
+
create(settings: SectionLayoutSettings, original: SectionLayoutProjection): Promise<SourceInput>;
|
|
7
|
+
supports(projection: SectionLayoutProjection): boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SectionIdentityPort {
|
|
10
|
+
next(): string;
|
|
11
|
+
}
|
|
12
|
+
/** Changes a supported section, retaining content identities and untouched document regions. */
|
|
13
|
+
export declare class SectionLayoutService {
|
|
14
|
+
private readonly content;
|
|
15
|
+
private readonly identities;
|
|
16
|
+
private readonly scaffold?;
|
|
17
|
+
private readonly policy;
|
|
18
|
+
constructor(content: ContentService, identities: SectionIdentityPort, scaffold?: SectionScaffoldPort | undefined);
|
|
19
|
+
context(document: EditorDocumentData, id: string): SectionLayoutContext | undefined;
|
|
20
|
+
update(document: EditorDocumentData, id: string, patch: SectionLayoutPatch): Promise<EditorDocument>;
|
|
21
|
+
private styles;
|
|
22
|
+
private fresh;
|
|
23
|
+
private all;
|
|
24
|
+
private replace;
|
|
25
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { DocumentPresentationService } from './document-presentation';
|
|
2
|
+
import { DocumentMetadataService } from './document-metadata';
|
|
3
|
+
import type { DocumentMetadata } from './document-metadata';
|
|
4
|
+
import type { DocumentStyleProperty, ImageSizeSettings } from './document-presentation';
|
|
5
|
+
import type { Diagnostic, EditorDocumentData, EditorMode, SourceInput } from '../core/document';
|
|
6
|
+
import { DocumentHistory } from '../core/history';
|
|
7
|
+
import type { BlockType } from '../core/catalog';
|
|
8
|
+
import { ContentService } from './content-service';
|
|
9
|
+
import { DocumentMutationService } from './document-commands';
|
|
10
|
+
import type { InsertionSource } from './document-commands';
|
|
11
|
+
import { SectionLayoutService } from './section-layout';
|
|
12
|
+
import type { SectionLayoutContext, SectionLayoutPatch } from '../core/section-layout';
|
|
13
|
+
import { ImageLinkService } from './image-link';
|
|
14
|
+
import type { ImageLinkContext, ImageLinkOptions } from './image-link';
|
|
15
|
+
import { HostIntegration } from './host';
|
|
16
|
+
import type { AssetReference } from './host';
|
|
17
|
+
export interface PendingRichTextDraft {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly html: string;
|
|
20
|
+
readonly originalHtml: string;
|
|
21
|
+
readonly changed: boolean;
|
|
22
|
+
readonly valid: boolean;
|
|
23
|
+
readonly blocked?: 'oversized';
|
|
24
|
+
readonly documentId: string;
|
|
25
|
+
readonly baseRevision: number;
|
|
26
|
+
readonly editGeneration: number;
|
|
27
|
+
}
|
|
28
|
+
export interface EditorState {
|
|
29
|
+
readonly document: EditorDocumentData;
|
|
30
|
+
readonly mode: EditorMode;
|
|
31
|
+
readonly source: SourceInput;
|
|
32
|
+
readonly draftSource: SourceInput;
|
|
33
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
34
|
+
readonly selectedNodeId: string | undefined;
|
|
35
|
+
readonly pendingRichText?: PendingRichTextDraft;
|
|
36
|
+
readonly canUndo: boolean;
|
|
37
|
+
readonly canRedo: boolean;
|
|
38
|
+
readonly readOnly: boolean;
|
|
39
|
+
readonly readonly: boolean;
|
|
40
|
+
readonly dirty: boolean;
|
|
41
|
+
readonly editGeneration: number;
|
|
42
|
+
}
|
|
43
|
+
export interface SessionOptions {
|
|
44
|
+
readonly document: EditorDocumentData;
|
|
45
|
+
/** Notices of the import which produced the initial document, e.g. what was removed. */
|
|
46
|
+
readonly diagnostics?: readonly Diagnostic[];
|
|
47
|
+
readonly readOnly?: boolean;
|
|
48
|
+
readonly persistedRevision?: number;
|
|
49
|
+
readonly onObserverError?: (error: unknown) => void;
|
|
50
|
+
}
|
|
51
|
+
export interface SessionServices {
|
|
52
|
+
readonly content: ContentService;
|
|
53
|
+
readonly mutations: DocumentMutationService;
|
|
54
|
+
readonly imageLinks: ImageLinkService;
|
|
55
|
+
readonly presentation?: DocumentPresentationService;
|
|
56
|
+
readonly metadata?: DocumentMetadataService;
|
|
57
|
+
readonly sectionLayouts?: SectionLayoutService;
|
|
58
|
+
readonly history: DocumentHistory;
|
|
59
|
+
readonly host: HostIntegration;
|
|
60
|
+
}
|
|
61
|
+
export declare class EditorSession {
|
|
62
|
+
#private;
|
|
63
|
+
private readonly services;
|
|
64
|
+
private readonly options;
|
|
65
|
+
constructor(services: SessionServices, options: SessionOptions);
|
|
66
|
+
getState(): EditorState;
|
|
67
|
+
snapshot(): EditorDocumentData;
|
|
68
|
+
exportSource(): SourceInput;
|
|
69
|
+
setReadOnly(value: boolean): void;
|
|
70
|
+
subscribe(listener: (state: EditorState) => void): () => void;
|
|
71
|
+
select(id: string | undefined): boolean;
|
|
72
|
+
setDraftSource(source: SourceInput): void;
|
|
73
|
+
commitDraft(): boolean;
|
|
74
|
+
importSource(source: SourceInput): boolean;
|
|
75
|
+
importJson(input: unknown): boolean;
|
|
76
|
+
setMode(mode: EditorMode): boolean;
|
|
77
|
+
beginRichText(id: string, initialHtml: string): boolean;
|
|
78
|
+
updateRichTextDraft(html: string): boolean;
|
|
79
|
+
restoreRichTextDraft(draft: Pick<PendingRichTextDraft, 'id' | 'html' | 'blocked'>, initialHtml: string): boolean;
|
|
80
|
+
commitRichText(): boolean;
|
|
81
|
+
cancelRichText(): void;
|
|
82
|
+
inlineStyles(id: string): Readonly<Record<string, string>>;
|
|
83
|
+
/** Title and, in an e-mail, preheader of the document. */
|
|
84
|
+
documentMetadata(): DocumentMetadata | undefined;
|
|
85
|
+
updateTitle(value: string): boolean;
|
|
86
|
+
updatePreheader(value: string): boolean;
|
|
87
|
+
imageSize(id: string): import("./document-presentation").ImageSizeContext | undefined;
|
|
88
|
+
updateImageSize(id: string, settings: ImageSizeSettings): boolean;
|
|
89
|
+
documentStyles(): import("./document-presentation").DocumentStyleContext | undefined;
|
|
90
|
+
updateDocumentStyle(property: DocumentStyleProperty, value: string): boolean;
|
|
91
|
+
updateText(id: string, value: string): boolean;
|
|
92
|
+
updateRichText(id: string, html: string): boolean;
|
|
93
|
+
updateAttribute(id: string, name: string, value: string): boolean;
|
|
94
|
+
updateStyle(id: string, property: string, value: string): boolean;
|
|
95
|
+
connectFormReference(reference: string, id?: string, parentId?: string, index?: number): boolean;
|
|
96
|
+
attachAsset(asset: AssetReference, id?: string, parentId?: string, index?: number): boolean;
|
|
97
|
+
imageLink(imageId: string): ImageLinkContext | undefined;
|
|
98
|
+
updateImageLink(imageId: string, href: string, options?: ImageLinkOptions): boolean;
|
|
99
|
+
layoutSettings(id: string): SectionLayoutContext | undefined;
|
|
100
|
+
updateLayout(id: string, patch: SectionLayoutPatch): Promise<boolean>;
|
|
101
|
+
addBlock(type: BlockType, parentId?: string, index?: number): boolean;
|
|
102
|
+
insertSource(source: InsertionSource, parentId?: string, index?: number): boolean;
|
|
103
|
+
removeBlock(id: string): boolean;
|
|
104
|
+
duplicateBlock(id: string): boolean;
|
|
105
|
+
moveBlock(id: string, parentId: string | undefined, index: number): boolean;
|
|
106
|
+
undo(): boolean;
|
|
107
|
+
redo(): boolean;
|
|
108
|
+
save(): Promise<boolean>;
|
|
109
|
+
dispose(): void;
|
|
110
|
+
private metadata;
|
|
111
|
+
/** What an import removed stays visible next to what the committed document holds. */
|
|
112
|
+
private notices;
|
|
113
|
+
private presentation;
|
|
114
|
+
private change;
|
|
115
|
+
private restore;
|
|
116
|
+
private commit;
|
|
117
|
+
private fail;
|
|
118
|
+
private rejectRichTextSize;
|
|
119
|
+
private boundedRichText;
|
|
120
|
+
private canWrite;
|
|
121
|
+
private assertActive;
|
|
122
|
+
private hasPendingDraft;
|
|
123
|
+
private emit;
|
|
124
|
+
private freezeBroadcast;
|
|
125
|
+
/** False when the listener threw; the failure was already reported. */
|
|
126
|
+
private notify;
|
|
127
|
+
private find;
|
|
128
|
+
}
|