@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,31 @@
|
|
|
1
|
+
import type { CanvasContext } from './context';
|
|
2
|
+
import type { ControlsOverlay } from './overlay';
|
|
3
|
+
/**
|
|
4
|
+
* Corner grips on the selected image: the width follows the pointer and keeps the proportion.
|
|
5
|
+
* The keyboard does the same with the arrows, on the focused grip or, from the image itself,
|
|
6
|
+
* with Shift + Alt + left or right.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ImageTools {
|
|
9
|
+
#private;
|
|
10
|
+
private readonly ctx;
|
|
11
|
+
constructor(ctx: CanvasContext, overlay: ControlsOverlay);
|
|
12
|
+
/** Moves the keyboard from the selected image to its resize grip. */
|
|
13
|
+
focusGrip(id: string): boolean;
|
|
14
|
+
/** Drops the size the keys left without sending it; false when there was none. */
|
|
15
|
+
dropKeys(): boolean;
|
|
16
|
+
get active(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Changes the width of the selected image by `delta` pixels, keeping its proportion. The
|
|
19
|
+
* piece shows each step at once; the host receives one size when the keys rest.
|
|
20
|
+
*/
|
|
21
|
+
nudge(id: string, delta: number): boolean;
|
|
22
|
+
/** Sends the size the keys left, before anything else is asked of the piece. */
|
|
23
|
+
flushKeys(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Runs `then` once the size just sent is answered (a revision, or no answer in time); at once
|
|
26
|
+
* when none is on its way. Saving waits for it, so the size of the last key is what is saved.
|
|
27
|
+
*/
|
|
28
|
+
afterAnswer(then: () => void): void;
|
|
29
|
+
/** A revision arrived: its markup already carries the accepted size. */
|
|
30
|
+
documentChanged(): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BlockDrag } from './block-drag';
|
|
2
|
+
import type { CanvasContext } from './context';
|
|
3
|
+
import type { ImageTools } from './image-tools';
|
|
4
|
+
import type { TextSession } from './text-session';
|
|
5
|
+
import type { ViewportRestorer } from './viewport';
|
|
6
|
+
/**
|
|
7
|
+
* Keys pressed while the frame holds the keyboard. The shortcuts are the ones of the shell: the
|
|
8
|
+
* frame only forwards what it cannot do itself, as a typed intent.
|
|
9
|
+
*/
|
|
10
|
+
export declare class KeyboardIntents {
|
|
11
|
+
#private;
|
|
12
|
+
private readonly ctx;
|
|
13
|
+
private readonly text;
|
|
14
|
+
private readonly drag;
|
|
15
|
+
private readonly viewport;
|
|
16
|
+
private readonly images;
|
|
17
|
+
constructor(ctx: CanvasContext, text: TextSession, drag: BlockDrag, viewport: ViewportRestorer, images: ImageTools);
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type Payload = Readonly<Record<string, unknown>>;
|
|
2
|
+
/**
|
|
3
|
+
* The only way out of the frame: every message carries the window nonce, the revision the frame
|
|
4
|
+
* currently shows and a growing sequence. Measurements are throttled here and keep their last
|
|
5
|
+
* value; what the person asked for is never dropped by this side.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BridgeChannel {
|
|
8
|
+
#private;
|
|
9
|
+
private readonly nonce;
|
|
10
|
+
revision: number;
|
|
11
|
+
constructor(nonce: string, revision: number);
|
|
12
|
+
send(type: string, payload?: Payload): void;
|
|
13
|
+
/** Selection is the one unsequenced intent of the original contract. */
|
|
14
|
+
selection(nodeId: string): void;
|
|
15
|
+
/** At most thirty per second for each kind; the latest value is always delivered. */
|
|
16
|
+
telemetry(type: string, payload: Payload): void;
|
|
17
|
+
/** Coalesces drafts; the producer runs when the message leaves, so it carries the last text. */
|
|
18
|
+
draft(produce: () => Payload | undefined): void;
|
|
19
|
+
flushDraft(): void;
|
|
20
|
+
cancelDraft(): void;
|
|
21
|
+
/** One intent made while a commit awaits its revision; a newer one replaces it. */
|
|
22
|
+
defer(intent: (() => void) | undefined): void;
|
|
23
|
+
takeDeferred(): (() => void) | undefined;
|
|
24
|
+
dispose(): void;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface MorphOptions {
|
|
2
|
+
/** Nodes owned by the runtime: never matched, moved or removed. */
|
|
3
|
+
readonly keep: (node: Node) => boolean;
|
|
4
|
+
/** The element under edition is left exactly as it is, attributes and content. */
|
|
5
|
+
readonly frozen?: (element: Element) => boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Reconciles the live preview with the next validated revision without reloading the window.
|
|
9
|
+
* The incoming markup is parsed into an inert document and is subject to the same CSP. It throws
|
|
10
|
+
* when the revision needs a new window; the caller then asks the host for one.
|
|
11
|
+
*/
|
|
12
|
+
export declare class DocumentMorph {
|
|
13
|
+
private readonly options;
|
|
14
|
+
constructor(options: MorphOptions);
|
|
15
|
+
apply(html: string): void;
|
|
16
|
+
private head;
|
|
17
|
+
private attributes;
|
|
18
|
+
private matches;
|
|
19
|
+
private children;
|
|
20
|
+
private node;
|
|
21
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CanvasContext } from './context';
|
|
2
|
+
export type NavigationCommand = 'selectPrevious' | 'selectNext' | 'selectParent' | 'selectChild';
|
|
3
|
+
/**
|
|
4
|
+
* Moves the selection with the arrows: up and down to the sibling before or after (or to the
|
|
5
|
+
* block next to it in the document when there is none), left to the block which contains it,
|
|
6
|
+
* right into its first block. Only blocks of the revision on screen are visited, in the order
|
|
7
|
+
* the piece shows them; the page scrolls only as far as needed to show the block reached.
|
|
8
|
+
*/
|
|
9
|
+
export declare class BlockNavigation {
|
|
10
|
+
#private;
|
|
11
|
+
private readonly ctx;
|
|
12
|
+
constructor(ctx: CanvasContext);
|
|
13
|
+
/**
|
|
14
|
+
* Where the next arrow starts: the block the previous arrow reached while it still holds the
|
|
15
|
+
* keyboard, otherwise the selected block, otherwise the focused one.
|
|
16
|
+
*/
|
|
17
|
+
origin(focused: string | undefined): string | undefined;
|
|
18
|
+
/** A block the person can see: one with a box, not hidden, not inside a closed `details`. */
|
|
19
|
+
visible(id: string): boolean;
|
|
20
|
+
/** The visible block an arrow leads to from `id`, or nothing at the edges of the piece. */
|
|
21
|
+
target(id: string, command: NavigationCommand): string | undefined;
|
|
22
|
+
/** Selects the block an arrow leads to, gives it the keyboard and brings it into view. */
|
|
23
|
+
go(id: string, command: NavigationCommand): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Scrolls the piece the least needed for the block to be seen; never the host page. A block
|
|
26
|
+
* without a box, or fixed to the window, is not brought anywhere by scrolling.
|
|
27
|
+
*/
|
|
28
|
+
reveal(element: Element): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CanvasBridgeConfiguration } from '../renderers/canvas-bridge';
|
|
2
|
+
/** The trusted layer above the piece: a shadow tree which document styles cannot reach. */
|
|
3
|
+
export declare class ControlsOverlay {
|
|
4
|
+
#private;
|
|
5
|
+
private readonly cfg;
|
|
6
|
+
readonly element: HTMLElement;
|
|
7
|
+
readonly shadow: ShadowRoot;
|
|
8
|
+
constructor(cfg: CanvasBridgeConfiguration);
|
|
9
|
+
/** Colors of the host shell; anything which is not a plain color value is ignored. */
|
|
10
|
+
theme(value: unknown): void;
|
|
11
|
+
node<K extends keyof HTMLElementTagNameMap>(tag: K, className: string): HTMLElementTagNameMap[K];
|
|
12
|
+
/** Icon bodies come exclusively from the installed Lucide subset generated at build time. */
|
|
13
|
+
icon(name: string, size?: number): string | undefined;
|
|
14
|
+
button(label: string, icon: string, signal: AbortSignal, action: () => void): HTMLButtonElement;
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BlockDrag } from './block-drag';
|
|
2
|
+
import type { CanvasContext } from './context';
|
|
3
|
+
import type { TextSession } from './text-session';
|
|
4
|
+
/**
|
|
5
|
+
* Turns clicks on the piece into intents: one click selects a block and opens its text, a double
|
|
6
|
+
* click on an image asks for another one, the secondary button asks the host for its menu.
|
|
7
|
+
*/
|
|
8
|
+
export declare class PointerIntents {
|
|
9
|
+
#private;
|
|
10
|
+
private readonly ctx;
|
|
11
|
+
private readonly text;
|
|
12
|
+
private readonly drag;
|
|
13
|
+
constructor(ctx: CanvasContext, text: TextSession, drag: BlockDrag);
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CanvasContext } from './context';
|
|
2
|
+
import type { ControlsOverlay } from './overlay';
|
|
3
|
+
/**
|
|
4
|
+
* Shows which block is under the pointer and which one is selected: a thin box, the friendly
|
|
5
|
+
* name of the block and, on the hovered one, the button which asks the host for a new block.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SelectionLayer {
|
|
8
|
+
#private;
|
|
9
|
+
private readonly ctx;
|
|
10
|
+
private readonly overlay;
|
|
11
|
+
private readonly editingId;
|
|
12
|
+
constructor(ctx: CanvasContext, overlay: ControlsOverlay, editingId: () => string | undefined);
|
|
13
|
+
get hoverId(): string | undefined;
|
|
14
|
+
hover(id: string | undefined): void;
|
|
15
|
+
highlight(id: string | undefined): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keyboard contract of the editor, shared by the shell and by the frame runtime: one table,
|
|
3
|
+
* one matcher. It owns no DOM and no state, so both sides bundle it as it is.
|
|
4
|
+
*/
|
|
5
|
+
export declare const EDITOR_SHORTCUT_COMMANDS: readonly ["undo", "redo", "remove", "duplicate", "moveUp", "moveDown", "parent", "save", "insert", "menu", "selectPrevious", "selectNext", "selectParent", "selectChild", "shrinkImage", "growImage"];
|
|
6
|
+
/**
|
|
7
|
+
* Commands which only mean something with the keyboard in the piece: bare arrows move the focus
|
|
8
|
+
* in every panel of the shell, and the menu key there belongs to the element which has it.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CANVAS_ONLY_SHORTCUTS: ReadonlySet<string>;
|
|
11
|
+
export type EditorShortcutCommand = (typeof EDITOR_SHORTCUT_COMMANDS)[number];
|
|
12
|
+
export interface ShortcutKeyEvent {
|
|
13
|
+
readonly key: string;
|
|
14
|
+
readonly ctrlKey: boolean;
|
|
15
|
+
readonly metaKey: boolean;
|
|
16
|
+
readonly altKey: boolean;
|
|
17
|
+
readonly shiftKey: boolean;
|
|
18
|
+
readonly isComposing?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface EditorShortcut {
|
|
21
|
+
readonly command: EditorShortcutCommand;
|
|
22
|
+
/** Keys as shown to the person; `Mod` stands for Ctrl or Cmd. */
|
|
23
|
+
readonly keys: readonly (readonly string[])[];
|
|
24
|
+
}
|
|
25
|
+
export declare const EDITOR_SHORTCUTS: readonly EditorShortcut[];
|
|
26
|
+
/** Resolves a key press to the command it asks for; text keys never match. */
|
|
27
|
+
export declare function matchEditorShortcut(event: ShortcutKeyEvent): EditorShortcutCommand | undefined;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { RichTextCommandName, RichTextCommandState } from '../rich-text/commands';
|
|
2
|
+
export interface TextEditorOptions {
|
|
3
|
+
readonly blocks: boolean;
|
|
4
|
+
readonly links: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface TextEditorEvents {
|
|
7
|
+
/** The text or the selection changed. */
|
|
8
|
+
changed(documentChanged: boolean): void;
|
|
9
|
+
finish(): void;
|
|
10
|
+
history(direction: 'undo' | 'redo'): void;
|
|
11
|
+
/** The person asked to reach the formatting controls outside the frame. */
|
|
12
|
+
toolbar(): void;
|
|
13
|
+
}
|
|
14
|
+
export interface TextSelectionRect {
|
|
15
|
+
readonly x: number;
|
|
16
|
+
readonly y: number;
|
|
17
|
+
readonly width: number;
|
|
18
|
+
readonly height: number;
|
|
19
|
+
}
|
|
20
|
+
/** The rich-text editor mounted over the real element of the piece, with its real CSS. */
|
|
21
|
+
export declare class InlineTextEditor {
|
|
22
|
+
#private;
|
|
23
|
+
private readonly element;
|
|
24
|
+
private constructor();
|
|
25
|
+
/**
|
|
26
|
+
* Returns the editor, or how many parts of the element would look different when it cannot be
|
|
27
|
+
* edited in place faithfully (zero when its markup is simply outside what the editor
|
|
28
|
+
* represents). On a refusal the element is left exactly as it was.
|
|
29
|
+
*/
|
|
30
|
+
static mount(element: HTMLElement, options: TextEditorOptions, events: TextEditorEvents): InlineTextEditor | {
|
|
31
|
+
readonly refused: number;
|
|
32
|
+
};
|
|
33
|
+
/** Every run of text and every decorated box of the element, with what makes it look so. */
|
|
34
|
+
private static appearance;
|
|
35
|
+
private static difference;
|
|
36
|
+
get dirty(): boolean;
|
|
37
|
+
exportHtml(): string;
|
|
38
|
+
contains(node: unknown): boolean;
|
|
39
|
+
setEditable(value: boolean): void;
|
|
40
|
+
/** Puts the caret where the person clicked; `end` is the keyboard entry. */
|
|
41
|
+
focus(point: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
} | 'end' | 'keep'): void;
|
|
45
|
+
run(command: RichTextCommandName, value: string | null): boolean;
|
|
46
|
+
history(direction: 'undo' | 'redo'): boolean;
|
|
47
|
+
state(): RichTextCommandState;
|
|
48
|
+
/** The selection rectangle in viewport coordinates, for the controls outside the frame. */
|
|
49
|
+
selectionRect(): TextSelectionRect;
|
|
50
|
+
/**
|
|
51
|
+
* `restore` returns the element to the markup it had before the edition; `keep` leaves the
|
|
52
|
+
* edited rendering in place until the next revision is reconciled over it.
|
|
53
|
+
*/
|
|
54
|
+
destroy(mode: 'restore' | 'keep'): void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CanvasContext, FramePoint } from './context';
|
|
2
|
+
import { InlineTextEditor } from './text-editor';
|
|
3
|
+
export type EditPoint = FramePoint | 'end' | 'keep';
|
|
4
|
+
/** The one text being edited in its own element, from the first caret to the host's answer. */
|
|
5
|
+
export declare class TextSession {
|
|
6
|
+
#private;
|
|
7
|
+
private readonly ctx;
|
|
8
|
+
private readonly highlight;
|
|
9
|
+
constructor(ctx: CanvasContext, highlight: (id: string) => void);
|
|
10
|
+
get id(): string | undefined;
|
|
11
|
+
get active(): boolean;
|
|
12
|
+
get awaiting(): boolean;
|
|
13
|
+
get dirty(): boolean;
|
|
14
|
+
contains(target: unknown): boolean;
|
|
15
|
+
element(): HTMLElement | undefined;
|
|
16
|
+
editable(id: string | undefined): id is string;
|
|
17
|
+
focus(point: EditPoint): void;
|
|
18
|
+
/** The keyboard belongs to the open text whenever the frame holds it. */
|
|
19
|
+
reclaim(): void;
|
|
20
|
+
setEditable(): void;
|
|
21
|
+
report(): void;
|
|
22
|
+
/** The host refused the commit or never answered: the text stays editable and nothing is lost. */
|
|
23
|
+
resume(id: string): void;
|
|
24
|
+
/** The host refused to open the transaction: the element returns to what it was. */
|
|
25
|
+
reject(id: string): void;
|
|
26
|
+
end(mode: 'finish' | 'cancel', then?: () => void): void;
|
|
27
|
+
/** No local step is left: the history of the document takes the request. */
|
|
28
|
+
documentHistory(direction: 'undo' | 'redo'): void;
|
|
29
|
+
/** With a text open, its own history comes first wherever the key was pressed. */
|
|
30
|
+
history(direction: 'undo' | 'redo'): void;
|
|
31
|
+
run(command: Parameters<InlineTextEditor['run']>[0], value: string | null): void;
|
|
32
|
+
begin(id: string | undefined, point: EditPoint): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Another revision arrived. A changed text was confirmed by the host and ends here; a clean one
|
|
35
|
+
* is reported so it can open again over the new markup.
|
|
36
|
+
*/
|
|
37
|
+
supersede(): string | undefined;
|
|
38
|
+
forgetRefusals(): void;
|
|
39
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CanvasContext } from './context';
|
|
2
|
+
import type { ControlsOverlay } from './overlay';
|
|
3
|
+
/**
|
|
4
|
+
* Shows the variables of the piece as tags without touching its text: a highlight of the CSS
|
|
5
|
+
* Highlight API over each `{{key}}` (the DOM, the text being edited and the saved piece stay
|
|
6
|
+
* exactly as they are), and, under the pointer, a label with the friendly name the host gave
|
|
7
|
+
* the variable. A browser without the API keeps the plain text.
|
|
8
|
+
*/
|
|
9
|
+
export declare class VariableMarks {
|
|
10
|
+
#private;
|
|
11
|
+
private readonly ctx;
|
|
12
|
+
constructor(ctx: CanvasContext, overlay: ControlsOverlay);
|
|
13
|
+
private registry;
|
|
14
|
+
private constructorOf;
|
|
15
|
+
private schedule;
|
|
16
|
+
private scan;
|
|
17
|
+
/** The label of the variable under the pointer, just above it. */
|
|
18
|
+
private hover;
|
|
19
|
+
private hide;
|
|
20
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CanvasContext } from './context';
|
|
2
|
+
/** Restores the scroll position the host remembers, also after media which arrives late. */
|
|
3
|
+
export declare class ViewportRestorer {
|
|
4
|
+
#private;
|
|
5
|
+
private readonly ctx;
|
|
6
|
+
constructor(ctx: CanvasContext);
|
|
7
|
+
/** The person acted: a late restoration would now move the piece under their hands. */
|
|
8
|
+
cancelDeferred(): void;
|
|
9
|
+
request(x: unknown, y: unknown): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { RichTextDecorationLine } from '../core/rich-text-format';
|
|
2
|
+
import type { Diagnostic } from '../core/document';
|
|
3
|
+
import { UrlPolicy } from '../security/url-policy';
|
|
4
|
+
export interface CssInspection {
|
|
5
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
6
|
+
readonly declarations: Readonly<Record<string, string>>;
|
|
7
|
+
readonly urls: readonly string[];
|
|
8
|
+
readonly urlCandidates: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
/** What an author's CSS holds. Nothing here refuses a document; the host decides. */
|
|
11
|
+
export interface CssSurvey {
|
|
12
|
+
/** Targets of `@import`, as written. */
|
|
13
|
+
readonly imports: readonly string[];
|
|
14
|
+
readonly fontFaces: number;
|
|
15
|
+
/** Every `url()` and string source the stylesheet refers to. */
|
|
16
|
+
readonly urls: readonly string[];
|
|
17
|
+
/** `expression()`, `behavior`, `-moz-binding` and URLs which would run code. */
|
|
18
|
+
readonly active: number;
|
|
19
|
+
}
|
|
20
|
+
/** Parse CSS rather than matching dangerous strings in the original stylesheet. */
|
|
21
|
+
export declare class CssDocumentCodec {
|
|
22
|
+
#private;
|
|
23
|
+
constructor(urls?: UrlPolicy);
|
|
24
|
+
validate(css: string, context?: 'stylesheet' | 'declarationList'): readonly Diagnostic[];
|
|
25
|
+
inspect(css: string, context?: 'stylesheet' | 'declarationList'): CssInspection;
|
|
26
|
+
/** The only refusals left for the CSS of a document: its size and the element it lives in. */
|
|
27
|
+
documentDiagnostics(css: string): readonly Diagnostic[];
|
|
28
|
+
/**
|
|
29
|
+
* Tolerant inventory of imported CSS: hacks, vendor filters and parse errors are kept as
|
|
30
|
+
* written. It never validates; `inspect` stays the strict gate of what the editor writes.
|
|
31
|
+
*/
|
|
32
|
+
survey(css: string, context?: 'stylesheet' | 'declarationList'): CssSurvey;
|
|
33
|
+
/**
|
|
34
|
+
* Removes from imported CSS what `survey` counts as active: a declaration which holds
|
|
35
|
+
* `expression()`, a binding, a behavior file or a code URL, and an `@import` of a code URL.
|
|
36
|
+
* Everything else keeps its bytes: the cut is made by the positions of the parser. The built-in
|
|
37
|
+
* behaviors of Outlook (`behavior:url(#default#VML)`) load nothing and stay: without them the
|
|
38
|
+
* VML of an e-mail does not draw.
|
|
39
|
+
*/
|
|
40
|
+
stripActive(css: string, context?: 'stylesheet' | 'declarationList'): {
|
|
41
|
+
readonly css: string;
|
|
42
|
+
readonly removed: number;
|
|
43
|
+
};
|
|
44
|
+
/** Source spans of the declarations and imports to remove; undefined when unreadable. */
|
|
45
|
+
private activeSpans;
|
|
46
|
+
/**
|
|
47
|
+
* A value the grammar could not read is kept as text. Whether it means code is judged over
|
|
48
|
+
* that text with its escapes resolved and its white space removed, as an engine would join it.
|
|
49
|
+
*/
|
|
50
|
+
private activeRaw;
|
|
51
|
+
/** `behavior:url(#default#VML)`: a behavior of the program itself, not a file it would load. */
|
|
52
|
+
private builtInBehavior;
|
|
53
|
+
readDeclarations(css: string): Readonly<Record<string, string>>;
|
|
54
|
+
/** Only semantic text declarations may enter the authenticated editing DOM. */
|
|
55
|
+
richTextStyles(css: string): Readonly<Record<string, string>> | undefined;
|
|
56
|
+
/** Conservative stylesheet check; cascade applicability is deliberately not inferred. */
|
|
57
|
+
hasDecorationRules(css: string): boolean;
|
|
58
|
+
/** Removes one line while keeping an independent strike/underline and its color/style. */
|
|
59
|
+
removeDecoration(css: string, line: RichTextDecorationLine): string;
|
|
60
|
+
/**
|
|
61
|
+
* Catalog defaults go before the author's rules, which keep precedence, yet after any
|
|
62
|
+
* leading `@charset` / `@import`, which only count at the top. The existing CSS is the
|
|
63
|
+
* author's and is kept as written, hacks included; only the incoming CSS is validated.
|
|
64
|
+
*/
|
|
65
|
+
prependDefaults(existing: string, incoming: readonly string[]): string;
|
|
66
|
+
removeDeclarations(css: string, properties: readonly string[]): string;
|
|
67
|
+
/** Replaces every declaration of the property and keeps the priority the author gave it. */
|
|
68
|
+
setDeclaration(css: string, property: string, value: string): string;
|
|
69
|
+
/** Untouched declarations and comments keep their source text; empty separators are dropped. */
|
|
70
|
+
private remaining;
|
|
71
|
+
private join;
|
|
72
|
+
private error;
|
|
73
|
+
private unique;
|
|
74
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BlockCatalog } from '../core/catalog';
|
|
2
|
+
import { EditorDocument } from '../core/document';
|
|
3
|
+
import type { DocumentKind, EditorDocumentData, ImportResult, SourceInput } from '../core/document';
|
|
4
|
+
import { ContentPolicy } from '../security/policy';
|
|
5
|
+
/** HTML5 parser, structural recognition and a bounded, private source-preservation cache. */
|
|
6
|
+
export declare class HtmlDocumentCodec {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(policy?: ContentPolicy, catalog?: BlockCatalog, cacheSize?: number);
|
|
9
|
+
/**
|
|
10
|
+
* Never refuses a document for what it contains. A source is only turned down when it is
|
|
11
|
+
* over the limits or when its tree cannot be written back as the same tree; a tree which
|
|
12
|
+
* needed one pass of the serializer to settle is accepted in that settled form.
|
|
13
|
+
*/
|
|
14
|
+
import(source: SourceInput, kind: DocumentKind, previous?: EditorDocumentData): ImportResult;
|
|
15
|
+
/**
|
|
16
|
+
* Parses and validates auxiliary source (rich text projections, snippets, verification)
|
|
17
|
+
* without touching the preservation cache of the documents being edited.
|
|
18
|
+
*/
|
|
19
|
+
inspect(source: SourceInput, kind: DocumentKind): ImportResult;
|
|
20
|
+
private read;
|
|
21
|
+
/**
|
|
22
|
+
* The tree the parser builds for this markup, in the shape of the document model, and the
|
|
23
|
+
* source slice of every node which stands alone in it. Throws over the node limits.
|
|
24
|
+
*/
|
|
25
|
+
private tree;
|
|
26
|
+
export(input: EditorDocumentData | EditorDocument): SourceInput;
|
|
27
|
+
clearCache(): void;
|
|
28
|
+
private plain;
|
|
29
|
+
private roundTrips;
|
|
30
|
+
private forget;
|
|
31
|
+
/**
|
|
32
|
+
* `template`, `svg` and `math` are kept as one block of source. Their inner markup follows
|
|
33
|
+
* other parsing rules (inert content, foreign elements, CDATA) which a tree of HTML nodes
|
|
34
|
+
* would not write back as it was read.
|
|
35
|
+
*/
|
|
36
|
+
private island;
|
|
37
|
+
private opener;
|
|
38
|
+
/** How a comment is written: as recorded, or by the grammar of old documents without it. */
|
|
39
|
+
private commentOpener;
|
|
40
|
+
private namespace;
|
|
41
|
+
/**
|
|
42
|
+
* Reparse output before returning it; serializer edge cases are a security boundary too.
|
|
43
|
+
* The tree read back has to be the tree which was written: the same nodes, attributes,
|
|
44
|
+
* text, comment forms and namespaces. Anything a parser would read differently, such as
|
|
45
|
+
* text which closes its own script or comment, fails here whatever the kind allows.
|
|
46
|
+
*/
|
|
47
|
+
private verification;
|
|
48
|
+
/**
|
|
49
|
+
* A source slice may stand for a node only when it holds that node and nothing else.
|
|
50
|
+
* Foster parenting, formatting reconstruction and ignored tokens leave foreign source
|
|
51
|
+
* between the located children; implied elements carry no location and are transparent.
|
|
52
|
+
*/
|
|
53
|
+
private selfContainedElement;
|
|
54
|
+
private tile;
|
|
55
|
+
private serialize;
|
|
56
|
+
/**
|
|
57
|
+
* Markup without `html`, `head` or `body` is read as a fragment. The fragment parser moves
|
|
58
|
+
* its result node by node, which is quadratic over tens of thousands of top-level nodes:
|
|
59
|
+
* such a wide source uses the flow content of the document parse, which is the same tree
|
|
60
|
+
* for everything a browser would place in a body.
|
|
61
|
+
*/
|
|
62
|
+
private fragment;
|
|
63
|
+
private isDocument;
|
|
64
|
+
private findTitle;
|
|
65
|
+
private newId;
|
|
66
|
+
private reconcileIds;
|
|
67
|
+
/**
|
|
68
|
+
* Digest of a subtree, remembered per node object so that matching preserved slices and
|
|
69
|
+
* older identities costs one pass over the tree. It only chooses candidates: whatever is
|
|
70
|
+
* written is still verified against the exact document fingerprint by reparse.
|
|
71
|
+
*/
|
|
72
|
+
private nodeFingerprint;
|
|
73
|
+
/** Two independent 32-bit mixes and the length: enough to pick a candidate, never a proof. */
|
|
74
|
+
private digest;
|
|
75
|
+
private ownStructure;
|
|
76
|
+
private nodeStructure;
|
|
77
|
+
private documentFingerprint;
|
|
78
|
+
private remember;
|
|
79
|
+
private error;
|
|
80
|
+
private notice;
|
|
81
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MjmlCompilerPort } from '../renderers/email-renderer';
|
|
2
|
+
import { GeneratedMjml } from './generated-mjml';
|
|
3
|
+
import type { GeneratedMjmlCompilerPort } from './generated-mjml';
|
|
4
|
+
export declare class BrowserMjmlCompiler implements MjmlCompilerPort, GeneratedMjmlCompilerPort {
|
|
5
|
+
private readonly guard;
|
|
6
|
+
private readonly jobs;
|
|
7
|
+
private disposed;
|
|
8
|
+
/** MJML from outside: no raw region is accepted. */
|
|
9
|
+
compile(source: string): Promise<string>;
|
|
10
|
+
/** MJML of the block codec, with the raw regions it generated. */
|
|
11
|
+
compileGenerated(mjml: GeneratedMjml): Promise<string>;
|
|
12
|
+
private run;
|
|
13
|
+
dispose(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GeneratedMjmlCompilerPort } from './generated-mjml';
|
|
2
|
+
/** A preview compilation replaced by a newer one before it started. */
|
|
3
|
+
export declare const COMPILE_SUPERSEDED = "COMPILE_SUPERSEDED";
|
|
4
|
+
/**
|
|
5
|
+
* Two lanes over one compiler, which runs at most two jobs at a time and refuses a third with
|
|
6
|
+
* `COMPILER_BUSY`. The preview lane has at most one compilation in flight and keeps only the
|
|
7
|
+
* newest one waiting: an older waiting preview is rejected with `COMPILE_SUPERSEDED`, because
|
|
8
|
+
* the frame only shows the newest revision. The final lane (save, conversion) runs one at a time
|
|
9
|
+
* in order, so the preview never takes its place; if a compiler shared with the host is busy with
|
|
10
|
+
* other work, the final job waits and tries again instead of failing.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CompileLanes {
|
|
13
|
+
#private;
|
|
14
|
+
private readonly compiler;
|
|
15
|
+
readonly preview: GeneratedMjmlCompilerPort;
|
|
16
|
+
readonly final: GeneratedMjmlCompilerPort;
|
|
17
|
+
constructor(compiler: GeneratedMjmlCompilerPort);
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MJML written by the block codec, with the exact raw regions (`mj-raw`) it emitted. A raw
|
|
3
|
+
* region is accepted by the compilation only through this type, only inside `mj-column`, and
|
|
4
|
+
* only when it is one of `fragments` and passes `CompilationGuard.rawFragment`: one table row
|
|
5
|
+
* whose single cell holds markup the e-mail rules keep as it is. MJML that arrives as a string
|
|
6
|
+
* (`compile`) never has a raw region.
|
|
7
|
+
*/
|
|
8
|
+
export declare class GeneratedMjml {
|
|
9
|
+
readonly source: string;
|
|
10
|
+
readonly fragments: readonly string[];
|
|
11
|
+
constructor(source: string, fragments?: readonly string[]);
|
|
12
|
+
}
|
|
13
|
+
/** Compilers which accept generated MJML. Both bundled compilers implement it. */
|
|
14
|
+
export interface GeneratedMjmlCompilerPort {
|
|
15
|
+
compileGenerated(mjml: GeneratedMjml): Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
/** What a compilation worker receives: external MJML, or generated MJML with its regions. */
|
|
18
|
+
export type CompileRequest = string | {
|
|
19
|
+
readonly source: string;
|
|
20
|
+
readonly fragments: string[];
|
|
21
|
+
};
|
|
22
|
+
export declare function readCompileRequest(request: unknown): {
|
|
23
|
+
source: string;
|
|
24
|
+
fragments?: readonly string[];
|
|
25
|
+
} | undefined;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const COMPILE_LIMITS: Readonly<{
|
|
2
|
+
sourceBytes: 200000;
|
|
3
|
+
outputBytes: 2000000;
|
|
4
|
+
timeoutMs: 15000;
|
|
5
|
+
parallelJobs: 2;
|
|
6
|
+
}>;
|
|
7
|
+
/** Compilation accepts content, never filesystem paths, configuration or plugins. */
|
|
8
|
+
export declare class CompilationGuard {
|
|
9
|
+
private readonly codec;
|
|
10
|
+
/**
|
|
11
|
+
* Without `fragments` (MJML from outside) `mj-raw` is refused like an include. With them
|
|
12
|
+
* (MJML of the block codec) an `mj-raw` is accepted only as a child of `mj-column`, only
|
|
13
|
+
* when its content is exactly one of the fragments, and each fragment must pass
|
|
14
|
+
* `rawFragment`.
|
|
15
|
+
*/
|
|
16
|
+
source(source: string, fragments?: readonly string[]): void;
|
|
17
|
+
/**
|
|
18
|
+
* A raw region of generated MJML. MJML writes it, as it is, inside the `tbody` of the column,
|
|
19
|
+
* so it is read here the way a browser reads it there: one row, one cell with only a class
|
|
20
|
+
* and a padding, and a content the e-mail rules keep without removing or rewriting anything.
|
|
21
|
+
*/
|
|
22
|
+
rawFragment(fragment: string): void;
|
|
23
|
+
output(source: unknown): string;
|
|
24
|
+
private rawRegion;
|
|
25
|
+
}
|
|
26
|
+
export declare const MJML_OPTIONS: Readonly<{
|
|
27
|
+
fonts: {};
|
|
28
|
+
validationLevel: "strict";
|
|
29
|
+
ignoreIncludes: true;
|
|
30
|
+
useMjmlConfigOptions: false;
|
|
31
|
+
keepComments: true;
|
|
32
|
+
minify: false;
|
|
33
|
+
juiceOptions: {
|
|
34
|
+
webResources: {
|
|
35
|
+
images: boolean;
|
|
36
|
+
scripts: boolean;
|
|
37
|
+
links: boolean;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MjmlCompilerPort } from '../renderers/email-renderer';
|
|
2
|
+
import { GeneratedMjml } from './generated-mjml';
|
|
3
|
+
import type { GeneratedMjmlCompilerPort } from './generated-mjml';
|
|
4
|
+
export declare class NodeMjmlCompiler implements MjmlCompilerPort, GeneratedMjmlCompilerPort {
|
|
5
|
+
private readonly workerUrl;
|
|
6
|
+
private readonly timeoutMs;
|
|
7
|
+
private readonly guard;
|
|
8
|
+
private readonly jobs;
|
|
9
|
+
private disposed;
|
|
10
|
+
constructor(workerUrl: URL, timeoutMs?: number);
|
|
11
|
+
/** MJML from outside: no raw region is accepted. */
|
|
12
|
+
compile(source: string): Promise<string>;
|
|
13
|
+
/** MJML of the block codec, with the raw regions it generated. */
|
|
14
|
+
compileGenerated(mjml: GeneratedMjml): Promise<string>;
|
|
15
|
+
private run;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|