@savvycal/mjml-editor 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -0
- package/dist/components/editor/BlockIcon.d.ts +7 -0
- package/dist/components/editor/BlockIcon.d.ts.map +1 -0
- package/dist/components/editor/BlockInspector.d.ts +6 -0
- package/dist/components/editor/BlockInspector.d.ts.map +1 -0
- package/dist/components/editor/BlockInspector.js +380 -0
- package/dist/components/editor/EditorCanvas.d.ts +11 -0
- package/dist/components/editor/EditorCanvas.d.ts.map +1 -0
- package/dist/components/editor/EditorCanvas.js +116 -0
- package/dist/components/editor/FontEditor.d.ts +2 -0
- package/dist/components/editor/FontEditor.d.ts.map +1 -0
- package/dist/components/editor/FontEditor.js +227 -0
- package/dist/components/editor/GlobalStylesPanel.d.ts +7 -0
- package/dist/components/editor/GlobalStylesPanel.d.ts.map +1 -0
- package/dist/components/editor/GlobalStylesPanel.js +310 -0
- package/dist/components/editor/InteractivePreview.d.ts +8 -0
- package/dist/components/editor/InteractivePreview.d.ts.map +1 -0
- package/dist/components/editor/InteractivePreview.js +130 -0
- package/dist/components/editor/LiquidAutocomplete.d.ts +10 -0
- package/dist/components/editor/LiquidAutocomplete.d.ts.map +1 -0
- package/dist/components/editor/LiquidAutocomplete.js +70 -0
- package/dist/components/editor/LiquidInput.d.ts +12 -0
- package/dist/components/editor/LiquidInput.d.ts.map +1 -0
- package/dist/components/editor/LiquidInput.js +185 -0
- package/dist/components/editor/MjmlEditor.d.ts +22 -0
- package/dist/components/editor/MjmlEditor.d.ts.map +1 -0
- package/dist/components/editor/MjmlEditor.js +137 -0
- package/dist/components/editor/OutlineTree.d.ts +7 -0
- package/dist/components/editor/OutlineTree.d.ts.map +1 -0
- package/dist/components/editor/OutlineTree.js +282 -0
- package/dist/components/editor/SourceEditor.d.ts +2 -0
- package/dist/components/editor/SourceEditor.d.ts.map +1 -0
- package/dist/components/editor/SourceEditor.js +70 -0
- package/dist/components/editor/SourcePreview.d.ts +7 -0
- package/dist/components/editor/SourcePreview.d.ts.map +1 -0
- package/dist/components/editor/SourcePreview.js +69 -0
- package/dist/components/editor/TiptapEditor.d.ts +12 -0
- package/dist/components/editor/TiptapEditor.d.ts.map +1 -0
- package/dist/components/editor/TiptapEditor.js +330 -0
- package/dist/components/editor/VisualEditor.d.ts +7 -0
- package/dist/components/editor/VisualEditor.d.ts.map +1 -0
- package/dist/components/editor/VisualEditor.js +51 -0
- package/dist/components/editor/visual-blocks/VisualBlock.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualBlock.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualBlock.js +34 -0
- package/dist/components/editor/visual-blocks/VisualButton.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualButton.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualButton.js +111 -0
- package/dist/components/editor/visual-blocks/VisualColumn.d.ts +8 -0
- package/dist/components/editor/visual-blocks/VisualColumn.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualColumn.js +44 -0
- package/dist/components/editor/visual-blocks/VisualDivider.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualDivider.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualDivider.js +41 -0
- package/dist/components/editor/visual-blocks/VisualImage.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualImage.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualImage.js +48 -0
- package/dist/components/editor/visual-blocks/VisualRaw.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualRaw.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualRaw.js +32 -0
- package/dist/components/editor/visual-blocks/VisualSection.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualSection.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualSection.js +131 -0
- package/dist/components/editor/visual-blocks/VisualSocial.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualSocial.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualSocial.js +62 -0
- package/dist/components/editor/visual-blocks/VisualSpacer.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualSpacer.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualSpacer.js +30 -0
- package/dist/components/editor/visual-blocks/VisualText.d.ts +7 -0
- package/dist/components/editor/visual-blocks/VisualText.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/VisualText.js +103 -0
- package/dist/components/editor/visual-blocks/helpers.d.ts +13 -0
- package/dist/components/editor/visual-blocks/helpers.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/helpers.js +44 -0
- package/dist/components/editor/visual-blocks/useResolvedAttributes.d.ts +7 -0
- package/dist/components/editor/visual-blocks/useResolvedAttributes.d.ts.map +1 -0
- package/dist/components/editor/visual-blocks/useResolvedAttributes.js +12 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +26 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +54 -0
- package/dist/components/ui/card.d.ts +10 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +7 -0
- package/dist/components/ui/floating-panel.d.ts +12 -0
- package/dist/components/ui/floating-panel.d.ts.map +1 -0
- package/dist/components/ui/floating-panel.js +54 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +26 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +23 -0
- package/dist/components/ui/popover.d.ts +8 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +39 -0
- package/dist/components/ui/resizable-split-pane.d.ts +10 -0
- package/dist/components/ui/resizable-split-pane.d.ts.map +1 -0
- package/dist/components/ui/resizable-split-pane.js +65 -0
- package/dist/components/ui/scroll-area.d.ts +10 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +69 -0
- package/dist/components/ui/select.d.ts +16 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +145 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/tabs.d.ts +8 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +68 -0
- package/dist/components/ui/theme-toggle.d.ts +2 -0
- package/dist/components/ui/theme-toggle.d.ts.map +1 -0
- package/dist/components/ui/theme-toggle.js +58 -0
- package/dist/components.css +365 -0
- package/dist/context/EditorContext.d.ts +40 -0
- package/dist/context/EditorContext.d.ts.map +1 -0
- package/dist/context/EditorContext.js +576 -0
- package/dist/context/LiquidSchemaContext.d.ts +10 -0
- package/dist/context/LiquidSchemaContext.d.ts.map +1 -0
- package/dist/context/LiquidSchemaContext.js +16 -0
- package/dist/context/ThemeContext.d.ts +29 -0
- package/dist/context/ThemeContext.d.ts.map +1 -0
- package/dist/context/ThemeContext.js +55 -0
- package/dist/extensions/LiquidHighlight.d.ts +3 -0
- package/dist/extensions/LiquidHighlight.d.ts.map +1 -0
- package/dist/extensions/LiquidHighlight.js +58 -0
- package/dist/extensions/LiquidSuggestion.d.ts +18 -0
- package/dist/extensions/LiquidSuggestion.d.ts.map +1 -0
- package/dist/extensions/LiquidSuggestion.js +119 -0
- package/dist/hooks/useFontLoader.d.ts +6 -0
- package/dist/hooks/useFontLoader.d.ts.map +1 -0
- package/dist/hooks/useFontLoader.js +21 -0
- package/dist/hooks/useStyleLoader.d.ts +11 -0
- package/dist/hooks/useStyleLoader.d.ts.map +1 -0
- package/dist/hooks/useStyleLoader.js +26 -0
- package/dist/index.d.ts +6 -150
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -57452
- package/dist/lib/html-utils.d.ts +23 -0
- package/dist/lib/html-utils.d.ts.map +1 -0
- package/dist/lib/html-utils.js +25 -0
- package/dist/lib/mjml/attributes.d.ts +100 -0
- package/dist/lib/mjml/attributes.d.ts.map +1 -0
- package/dist/lib/mjml/attributes.js +105 -0
- package/dist/lib/mjml/parser.d.ts +67 -0
- package/dist/lib/mjml/parser.d.ts.map +1 -0
- package/dist/lib/mjml/parser.js +184 -0
- package/dist/lib/mjml/parser.test.d.ts +2 -0
- package/dist/lib/mjml/parser.test.d.ts.map +1 -0
- package/dist/lib/mjml/renderer.d.ts +23 -0
- package/dist/lib/mjml/renderer.d.ts.map +1 -0
- package/dist/lib/mjml/renderer.js +75 -0
- package/dist/lib/mjml/schema.d.ts +21 -0
- package/dist/lib/mjml/schema.d.ts.map +1 -0
- package/dist/lib/mjml/schema.js +1307 -0
- package/dist/lib/mjml/scopeCSS.d.ts +21 -0
- package/dist/lib/mjml/scopeCSS.d.ts.map +1 -0
- package/dist/lib/mjml/scopeCSS.js +67 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +8 -0
- package/dist/preset.css +150 -0
- package/dist/types/liquid.d.ts +28 -0
- package/dist/types/liquid.d.ts.map +1 -0
- package/dist/types/mjml.d.ts +101 -0
- package/dist/types/mjml.d.ts.map +1 -0
- package/package.json +14 -10
- package/dist/styles.css +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitize HTML output from Tiptap for MJML compatibility.
|
|
3
|
+
*
|
|
4
|
+
* Tiptap outputs semantic HTML with <p> tags that may not render well
|
|
5
|
+
* in all email clients. This function normalizes the output to use
|
|
6
|
+
* <br /> for line breaks.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sanitizeHtmlForMjml(html: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Convert MJML content to Tiptap-compatible HTML.
|
|
11
|
+
*
|
|
12
|
+
* MJML content uses <br /> for line breaks. Tiptap expects
|
|
13
|
+
* content wrapped in <p> tags.
|
|
14
|
+
*/
|
|
15
|
+
export declare function mjmlToTiptapHtml(content: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Highlight Liquid template syntax in HTML content.
|
|
18
|
+
*
|
|
19
|
+
* Wraps {{ variable }} and {% tag %} patterns with a span
|
|
20
|
+
* that has the liquid-highlight class for visual styling.
|
|
21
|
+
*/
|
|
22
|
+
export declare function highlightLiquidTags(html: string): string;
|
|
23
|
+
//# sourceMappingURL=html-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-utils.d.ts","sourceRoot":"","sources":["../../src/lib/html-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBxD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAcxD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBxD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function p(i) {
|
|
2
|
+
if (!i || i === "<p></p>")
|
|
3
|
+
return "";
|
|
4
|
+
let r = i.replace(/<p>/g, "");
|
|
5
|
+
return r = r.replace(/<\/p>/g, "<br />"), r = r.replace(/(<br\s*\/?>)+$/, ""), r = r.replace(/<br>/gi, "<br />"), r;
|
|
6
|
+
}
|
|
7
|
+
function l(i) {
|
|
8
|
+
return !i || i.trim() === "" ? "<p></p>" : i.includes("<p>") ? i : i.split(/<br\s*\/?>/gi).map((e) => `<p>${e}</p>`).join("");
|
|
9
|
+
}
|
|
10
|
+
function s(i) {
|
|
11
|
+
if (!i) return i;
|
|
12
|
+
let r = i.replace(
|
|
13
|
+
/(\{\{[^{}]*\}\})/g,
|
|
14
|
+
'<span class="liquid-highlight">$1</span>'
|
|
15
|
+
);
|
|
16
|
+
return r = r.replace(
|
|
17
|
+
/(\{%[^{}]*%\})/g,
|
|
18
|
+
'<span class="liquid-highlight">$1</span>'
|
|
19
|
+
), r;
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
s as highlightLiquidTags,
|
|
23
|
+
l as mjmlToTiptapHtml,
|
|
24
|
+
p as sanitizeHtmlForMjml
|
|
25
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { MjmlNode, ComponentSchema } from '../../types/mjml';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration extracted from mj-attributes in mj-head
|
|
4
|
+
*/
|
|
5
|
+
export interface MjmlAttributesConfig {
|
|
6
|
+
/** Attributes from mj-all that apply to all elements */
|
|
7
|
+
all: Record<string, string>;
|
|
8
|
+
/** Element-specific defaults (tagName -> attributes) */
|
|
9
|
+
elements: Record<string, Record<string, string>>;
|
|
10
|
+
/** Named classes (className -> attributes) */
|
|
11
|
+
classes: Record<string, Record<string, string>>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create an empty mj-attributes configuration
|
|
15
|
+
*/
|
|
16
|
+
export declare function createEmptyConfig(): MjmlAttributesConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Get the mj-head node from a document
|
|
19
|
+
*/
|
|
20
|
+
export declare function getHead(document: MjmlNode): MjmlNode | null;
|
|
21
|
+
/**
|
|
22
|
+
* Get the mj-body node from a document
|
|
23
|
+
*/
|
|
24
|
+
export declare function getBody(document: MjmlNode): MjmlNode | null;
|
|
25
|
+
/**
|
|
26
|
+
* Get the mj-attributes node from mj-head
|
|
27
|
+
*/
|
|
28
|
+
export declare function getMjAttributes(document: MjmlNode): MjmlNode | null;
|
|
29
|
+
/**
|
|
30
|
+
* Extract mj-attributes configuration from a document's mj-head
|
|
31
|
+
*/
|
|
32
|
+
export declare function extractMjmlAttributes(document: MjmlNode): MjmlAttributesConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Parse space-separated class names from mj-class attribute value
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseClassNames(mjClassValue: string | undefined): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Get list of defined class names from the document
|
|
39
|
+
*/
|
|
40
|
+
export declare function getDefinedClasses(document: MjmlNode): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Resolve effective attributes for a node by applying the MJML cascade.
|
|
43
|
+
*
|
|
44
|
+
* Order of precedence (later overrides earlier):
|
|
45
|
+
* 1. mj-all attributes
|
|
46
|
+
* 2. Element-type defaults (mj-text, mj-section, etc.)
|
|
47
|
+
* 3. mj-class attributes (if node has mj-class)
|
|
48
|
+
* 4. Per-element attributes
|
|
49
|
+
*
|
|
50
|
+
* Note: Schema defaults are NOT included here - they are handled
|
|
51
|
+
* at the component level for backward compatibility.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveAttributes(node: MjmlNode, mjmlAttributes: MjmlAttributesConfig): Record<string, string>;
|
|
54
|
+
/**
|
|
55
|
+
* Get the inherited value for a specific attribute (for placeholder display).
|
|
56
|
+
*
|
|
57
|
+
* This returns the value that would be used if the node doesn't override it,
|
|
58
|
+
* computed from the cascade (mj-all -> element-type -> mj-class -> schema default).
|
|
59
|
+
*
|
|
60
|
+
* Returns undefined if there is no inherited value.
|
|
61
|
+
*/
|
|
62
|
+
export declare function getInheritedValue(node: MjmlNode, attributeKey: string, mjmlAttributes: MjmlAttributesConfig, schema: ComponentSchema | null): string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Get the resolved value for a specific attribute.
|
|
65
|
+
* This is a convenience function that resolves a single attribute.
|
|
66
|
+
*/
|
|
67
|
+
export declare function getResolvedValue(node: MjmlNode, attributeKey: string, mjmlAttributes: MjmlAttributesConfig, schema: ComponentSchema | null): string | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Helper function to resolve attributes with schema for a node.
|
|
70
|
+
* This is the main function visual blocks should use.
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveNodeAttributes(node: MjmlNode, mjmlAttributes: MjmlAttributesConfig): Record<string, string>;
|
|
73
|
+
/**
|
|
74
|
+
* Check if a node has any mj-class applied
|
|
75
|
+
*/
|
|
76
|
+
export declare function hasClasses(node: MjmlNode): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Add a class to a node's mj-class attribute
|
|
79
|
+
*/
|
|
80
|
+
export declare function addClassToNode(node: MjmlNode, className: string): Record<string, string>;
|
|
81
|
+
/**
|
|
82
|
+
* Remove a class from a node's mj-class attribute
|
|
83
|
+
*/
|
|
84
|
+
export declare function removeClassFromNode(node: MjmlNode, className: string): Record<string, string>;
|
|
85
|
+
/**
|
|
86
|
+
* Font configuration extracted from mj-font nodes in mj-head
|
|
87
|
+
*/
|
|
88
|
+
export interface MjmlFontConfig {
|
|
89
|
+
name: string;
|
|
90
|
+
href: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Extract all mj-font configurations from mj-head
|
|
94
|
+
*/
|
|
95
|
+
export declare function extractFonts(document: MjmlNode): MjmlFontConfig[];
|
|
96
|
+
/**
|
|
97
|
+
* Extract CSS content from all mj-style nodes in mj-head
|
|
98
|
+
*/
|
|
99
|
+
export declare function extractStyles(document: MjmlNode): string[];
|
|
100
|
+
//# sourceMappingURL=attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/mjml/attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG9D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,oBAAoB,CAMxD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAGnE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,GACjB,oBAAoB,CA4BtB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAM1E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAG9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,cAAc,EAAE,oBAAoB,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBxB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,oBAAoB,EACpC,MAAM,EAAE,eAAe,GAAG,IAAI,GAC7B,MAAM,GAAG,SAAS,CA8BpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,oBAAoB,EACpC,MAAM,EAAE,eAAe,GAAG,IAAI,GAC7B,MAAM,GAAG,SAAS,CAQpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,QAAQ,EACd,cAAc,EAAE,oBAAoB,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcxB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,EAAE,CAWjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAQ1D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { getSchemaForTag as u } from "./schema.js";
|
|
2
|
+
function m() {
|
|
3
|
+
return {
|
|
4
|
+
all: {},
|
|
5
|
+
elements: {},
|
|
6
|
+
classes: {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function i(s) {
|
|
10
|
+
return s.children?.find((t) => t.tagName === "mj-head") || null;
|
|
11
|
+
}
|
|
12
|
+
function d(s) {
|
|
13
|
+
return i(s)?.children?.find((e) => e.tagName === "mj-attributes") || null;
|
|
14
|
+
}
|
|
15
|
+
function g(s) {
|
|
16
|
+
const t = m(), e = d(s);
|
|
17
|
+
if (!e?.children)
|
|
18
|
+
return t;
|
|
19
|
+
for (const n of e.children)
|
|
20
|
+
if (n.tagName === "mj-all")
|
|
21
|
+
Object.assign(t.all, n.attributes);
|
|
22
|
+
else if (n.tagName === "mj-class") {
|
|
23
|
+
const a = n.attributes.name;
|
|
24
|
+
if (a) {
|
|
25
|
+
const r = { ...n.attributes };
|
|
26
|
+
delete r.name, t.classes[a] = r;
|
|
27
|
+
}
|
|
28
|
+
} else n.tagName.startsWith("mj-") && (t.elements[n.tagName] = { ...n.attributes });
|
|
29
|
+
return t;
|
|
30
|
+
}
|
|
31
|
+
function l(s) {
|
|
32
|
+
return s ? s.split(/\s+/).map((t) => t.trim()).filter((t) => t.length > 0) : [];
|
|
33
|
+
}
|
|
34
|
+
function N(s) {
|
|
35
|
+
const t = g(s);
|
|
36
|
+
return Object.keys(t.classes);
|
|
37
|
+
}
|
|
38
|
+
function h(s, t) {
|
|
39
|
+
const e = {};
|
|
40
|
+
Object.assign(e, t.all);
|
|
41
|
+
const n = t.elements[s.tagName];
|
|
42
|
+
n && Object.assign(e, n);
|
|
43
|
+
const a = l(s.attributes["mj-class"]);
|
|
44
|
+
for (const r of a) {
|
|
45
|
+
const c = t.classes[r];
|
|
46
|
+
c && Object.assign(e, c);
|
|
47
|
+
}
|
|
48
|
+
return Object.assign(e, s.attributes), e;
|
|
49
|
+
}
|
|
50
|
+
function b(s, t, e, n) {
|
|
51
|
+
let a;
|
|
52
|
+
e.all[t] && (a = e.all[t]);
|
|
53
|
+
const r = e.elements[s.tagName];
|
|
54
|
+
r?.[t] && (a = r[t]);
|
|
55
|
+
const c = l(s.attributes["mj-class"]);
|
|
56
|
+
for (const f of c) {
|
|
57
|
+
const o = e.classes[f];
|
|
58
|
+
o?.[t] && (a = o[t]);
|
|
59
|
+
}
|
|
60
|
+
return a === void 0 && n && (a = n[t]?.default), a;
|
|
61
|
+
}
|
|
62
|
+
function p(s, t) {
|
|
63
|
+
const e = u(s.tagName), n = h(s, t);
|
|
64
|
+
if (e)
|
|
65
|
+
for (const [a, r] of Object.entries(e))
|
|
66
|
+
n[a] === void 0 && r.default !== void 0 && (n[a] = r.default);
|
|
67
|
+
return n;
|
|
68
|
+
}
|
|
69
|
+
function v(s, t) {
|
|
70
|
+
const e = l(s.attributes["mj-class"]);
|
|
71
|
+
return e.includes(t) || e.push(t), {
|
|
72
|
+
...s.attributes,
|
|
73
|
+
"mj-class": e.join(" ")
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function C(s, t) {
|
|
77
|
+
const n = l(s.attributes["mj-class"]).filter((r) => r !== t), a = { ...s.attributes };
|
|
78
|
+
return n.length === 0 ? delete a["mj-class"] : a["mj-class"] = n.join(" "), a;
|
|
79
|
+
}
|
|
80
|
+
function O(s) {
|
|
81
|
+
const t = i(s);
|
|
82
|
+
return t?.children ? t.children.filter((e) => e.tagName === "mj-font").map((e) => ({
|
|
83
|
+
name: e.attributes.name || "",
|
|
84
|
+
href: e.attributes.href || ""
|
|
85
|
+
})).filter((e) => e.name && e.href) : [];
|
|
86
|
+
}
|
|
87
|
+
function x(s) {
|
|
88
|
+
const t = i(s);
|
|
89
|
+
return t?.children ? t.children.filter((e) => e.tagName === "mj-style").map((e) => e.content || "").filter((e) => e.trim().length > 0) : [];
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
v as addClassToNode,
|
|
93
|
+
m as createEmptyConfig,
|
|
94
|
+
O as extractFonts,
|
|
95
|
+
g as extractMjmlAttributes,
|
|
96
|
+
x as extractStyles,
|
|
97
|
+
N as getDefinedClasses,
|
|
98
|
+
i as getHead,
|
|
99
|
+
b as getInheritedValue,
|
|
100
|
+
d as getMjAttributes,
|
|
101
|
+
l as parseClassNames,
|
|
102
|
+
C as removeClassFromNode,
|
|
103
|
+
h as resolveAttributes,
|
|
104
|
+
p as resolveNodeAttributes
|
|
105
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { MjmlNode } from '../../types/mjml';
|
|
2
|
+
/**
|
|
3
|
+
* Parse MJML markup string into a JSON AST with internal IDs
|
|
4
|
+
* Browser-compatible implementation using DOMParser
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseMjml(mjmlString: string): MjmlNode;
|
|
7
|
+
/**
|
|
8
|
+
* Serialize JSON AST back to MJML markup string
|
|
9
|
+
*/
|
|
10
|
+
export declare function serializeMjml(node: MjmlNode): string;
|
|
11
|
+
/**
|
|
12
|
+
* Add unique IDs to all nodes in the tree (for React keys and selection)
|
|
13
|
+
*/
|
|
14
|
+
export declare function addIds(node: MjmlNode): MjmlNode;
|
|
15
|
+
/**
|
|
16
|
+
* Strip internal IDs from nodes before serialization
|
|
17
|
+
*/
|
|
18
|
+
export declare function stripIds(node: MjmlNode): MjmlNode;
|
|
19
|
+
/**
|
|
20
|
+
* Find a node by ID in the tree
|
|
21
|
+
*/
|
|
22
|
+
export declare function findNodeById(root: MjmlNode, id: string): MjmlNode | null;
|
|
23
|
+
/**
|
|
24
|
+
* Find parent node of a given node ID
|
|
25
|
+
*/
|
|
26
|
+
export declare function findParentNode(root: MjmlNode, id: string): MjmlNode | null;
|
|
27
|
+
/**
|
|
28
|
+
* Get the mj-body node from the document
|
|
29
|
+
*/
|
|
30
|
+
export declare function getBody(root: MjmlNode): MjmlNode | null;
|
|
31
|
+
/**
|
|
32
|
+
* Get all sections from the body
|
|
33
|
+
*/
|
|
34
|
+
export declare function getSections(root: MjmlNode): MjmlNode[];
|
|
35
|
+
/**
|
|
36
|
+
* Create a deep clone of a node
|
|
37
|
+
*/
|
|
38
|
+
export declare function cloneNode(node: MjmlNode): MjmlNode;
|
|
39
|
+
/**
|
|
40
|
+
* Update a node in the tree immutably
|
|
41
|
+
*/
|
|
42
|
+
export declare function updateNode(root: MjmlNode, id: string, updater: (node: MjmlNode) => MjmlNode): MjmlNode;
|
|
43
|
+
/**
|
|
44
|
+
* Delete a node from the tree
|
|
45
|
+
*/
|
|
46
|
+
export declare function deleteNode(root: MjmlNode, id: string): MjmlNode;
|
|
47
|
+
/**
|
|
48
|
+
* Insert a node at a specific position
|
|
49
|
+
*/
|
|
50
|
+
export declare function insertNode(root: MjmlNode, parentId: string, index: number, newNode: MjmlNode): MjmlNode;
|
|
51
|
+
/**
|
|
52
|
+
* Move a node to a new parent at a specific index
|
|
53
|
+
*/
|
|
54
|
+
export declare function moveNode(root: MjmlNode, nodeId: string, newParentId: string, newIndex: number): MjmlNode;
|
|
55
|
+
/**
|
|
56
|
+
* Create a default empty document
|
|
57
|
+
*/
|
|
58
|
+
export declare function createEmptyDocument(): MjmlNode;
|
|
59
|
+
/**
|
|
60
|
+
* Create a new section with a single column
|
|
61
|
+
*/
|
|
62
|
+
export declare function createSection(): MjmlNode;
|
|
63
|
+
/**
|
|
64
|
+
* Create a new column
|
|
65
|
+
*/
|
|
66
|
+
export declare function createColumn(): MjmlNode;
|
|
67
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/lib/mjml/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AA4D7C;;;GAGG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAetD;AA+CD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEpD;AA8CD;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAM/C;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAOjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CASxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAS1E;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAGvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAItD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAElD;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,QAAQ,GACpC,QAAQ,CAWV;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAS/D;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,QAAQ,GAChB,QAAQ,CAeV;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,QAAQ,CAeV;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CA8B9C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,QAAQ,CAYxC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CAMvC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { v4 as $ } from "uuid";
|
|
2
|
+
function j(e) {
|
|
3
|
+
const t = e.match(
|
|
4
|
+
/XML Parsing Error:\s*(.+?)\nLocation:.*?\nLine Number\s*(\d+),\s*Column\s*(\d+)/i
|
|
5
|
+
);
|
|
6
|
+
if (t) {
|
|
7
|
+
const [, r, c, s] = t;
|
|
8
|
+
return `${u(r.trim())} (line ${c}, column ${s})`;
|
|
9
|
+
}
|
|
10
|
+
const n = e.match(
|
|
11
|
+
/error on line (\d+) at column (\d+): (.+?)(?:\n|Below|$)/i
|
|
12
|
+
);
|
|
13
|
+
if (n) {
|
|
14
|
+
const [, r, c, s] = n;
|
|
15
|
+
return `${u(s.trim())} (line ${r}, column ${c})`;
|
|
16
|
+
}
|
|
17
|
+
return e.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
18
|
+
}
|
|
19
|
+
function u(e) {
|
|
20
|
+
return e.charAt(0).toUpperCase() + e.slice(1);
|
|
21
|
+
}
|
|
22
|
+
function N(e) {
|
|
23
|
+
const t = (r) => r.replace(
|
|
24
|
+
/&(?!(amp|lt|gt|quot|apos|#[0-9]+|#x[0-9a-fA-F]+);)/gi,
|
|
25
|
+
"&"
|
|
26
|
+
);
|
|
27
|
+
let n = e.replace(/="([^"]*)"/g, (r, c) => `="${t(c)}"`);
|
|
28
|
+
return n = n.replace(/='([^']*)'/g, (r, c) => `='${t(c)}'`), n;
|
|
29
|
+
}
|
|
30
|
+
function _(e) {
|
|
31
|
+
const t = N(e), r = new DOMParser().parseFromString(t, "text/xml"), c = r.querySelector("parsererror");
|
|
32
|
+
if (c) {
|
|
33
|
+
const a = c.textContent || "Unknown parse error";
|
|
34
|
+
throw new Error(j(a));
|
|
35
|
+
}
|
|
36
|
+
const s = r.documentElement, i = m(s);
|
|
37
|
+
return l(i);
|
|
38
|
+
}
|
|
39
|
+
function m(e) {
|
|
40
|
+
const t = e.tagName.toLowerCase(), n = {};
|
|
41
|
+
for (const i of Array.from(e.attributes))
|
|
42
|
+
n[i.name] = i.value;
|
|
43
|
+
if ([
|
|
44
|
+
"mj-text",
|
|
45
|
+
"mj-button",
|
|
46
|
+
"mj-title",
|
|
47
|
+
"mj-preview",
|
|
48
|
+
"mj-style",
|
|
49
|
+
"mj-raw"
|
|
50
|
+
].includes(t))
|
|
51
|
+
return {
|
|
52
|
+
tagName: t,
|
|
53
|
+
attributes: n,
|
|
54
|
+
content: e.innerHTML.trim()
|
|
55
|
+
};
|
|
56
|
+
const s = [];
|
|
57
|
+
for (const i of Array.from(e.children))
|
|
58
|
+
s.push(m(i));
|
|
59
|
+
return {
|
|
60
|
+
tagName: t,
|
|
61
|
+
attributes: n,
|
|
62
|
+
children: s.length > 0 ? s : void 0
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function A(e) {
|
|
66
|
+
return d(f(e));
|
|
67
|
+
}
|
|
68
|
+
function d(e, t = 0) {
|
|
69
|
+
const n = " ".repeat(t), r = e.tagName, c = Object.entries(e.attributes || {}).filter(([, a]) => a !== "" && a !== void 0).map(([a, o]) => `${a}="${b(o)}"`).join(" "), s = c ? `<${r} ${c}>` : `<${r}>`, i = `</${r}>`;
|
|
70
|
+
if (e.content !== void 0)
|
|
71
|
+
return `${n}${s}${e.content}${i}`;
|
|
72
|
+
if (e.children && e.children.length > 0) {
|
|
73
|
+
const a = e.children.map((o) => d(o, t + 1)).join(`
|
|
74
|
+
`);
|
|
75
|
+
return `${n}${s}
|
|
76
|
+
${a}
|
|
77
|
+
${n}${i}`;
|
|
78
|
+
}
|
|
79
|
+
return `${n}${s}${i}`;
|
|
80
|
+
}
|
|
81
|
+
function b(e) {
|
|
82
|
+
return e.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
83
|
+
}
|
|
84
|
+
function l(e) {
|
|
85
|
+
return {
|
|
86
|
+
...e,
|
|
87
|
+
_id: e._id || $(),
|
|
88
|
+
children: e.children?.map(l)
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function f(e) {
|
|
92
|
+
const { _id: t, ...n } = e;
|
|
93
|
+
return {
|
|
94
|
+
...n,
|
|
95
|
+
children: e.children?.map(f)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function p(e, t) {
|
|
99
|
+
if (e._id === t) return e;
|
|
100
|
+
if (!e.children) return null;
|
|
101
|
+
for (const n of e.children) {
|
|
102
|
+
const r = p(n, t);
|
|
103
|
+
if (r) return r;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function M(e) {
|
|
108
|
+
return JSON.parse(JSON.stringify(e));
|
|
109
|
+
}
|
|
110
|
+
function y(e, t, n) {
|
|
111
|
+
return e._id === t ? n(e) : e.children ? {
|
|
112
|
+
...e,
|
|
113
|
+
children: e.children.map((r) => y(r, t, n))
|
|
114
|
+
} : e;
|
|
115
|
+
}
|
|
116
|
+
function h(e, t) {
|
|
117
|
+
return e.children ? {
|
|
118
|
+
...e,
|
|
119
|
+
children: e.children.filter((n) => n._id !== t).map((n) => h(n, t))
|
|
120
|
+
} : e;
|
|
121
|
+
}
|
|
122
|
+
function g(e, t, n, r) {
|
|
123
|
+
if (e._id === t) {
|
|
124
|
+
const c = [...e.children || []];
|
|
125
|
+
return c.splice(n, 0, l(r)), { ...e, children: c };
|
|
126
|
+
}
|
|
127
|
+
return e.children ? {
|
|
128
|
+
...e,
|
|
129
|
+
children: e.children.map(
|
|
130
|
+
(c) => g(c, t, n, r)
|
|
131
|
+
)
|
|
132
|
+
} : e;
|
|
133
|
+
}
|
|
134
|
+
function E(e, t, n, r) {
|
|
135
|
+
const c = p(e, t);
|
|
136
|
+
if (!c) return e;
|
|
137
|
+
const s = M(c);
|
|
138
|
+
let i = h(e, t);
|
|
139
|
+
return i = g(i, n, r, s), i;
|
|
140
|
+
}
|
|
141
|
+
function v() {
|
|
142
|
+
return l({
|
|
143
|
+
tagName: "mjml",
|
|
144
|
+
attributes: {},
|
|
145
|
+
children: [
|
|
146
|
+
{
|
|
147
|
+
tagName: "mj-body",
|
|
148
|
+
attributes: {},
|
|
149
|
+
children: [
|
|
150
|
+
{
|
|
151
|
+
tagName: "mj-section",
|
|
152
|
+
attributes: {},
|
|
153
|
+
children: [
|
|
154
|
+
{
|
|
155
|
+
tagName: "mj-column",
|
|
156
|
+
attributes: {},
|
|
157
|
+
children: [
|
|
158
|
+
{
|
|
159
|
+
tagName: "mj-text",
|
|
160
|
+
attributes: {},
|
|
161
|
+
content: "Start editing your email here..."
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
export {
|
|
173
|
+
l as addIds,
|
|
174
|
+
M as cloneNode,
|
|
175
|
+
v as createEmptyDocument,
|
|
176
|
+
h as deleteNode,
|
|
177
|
+
p as findNodeById,
|
|
178
|
+
g as insertNode,
|
|
179
|
+
E as moveNode,
|
|
180
|
+
_ as parseMjml,
|
|
181
|
+
A as serializeMjml,
|
|
182
|
+
f as stripIds,
|
|
183
|
+
y as updateNode
|
|
184
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.test.d.ts","sourceRoot":"","sources":["../../../src/lib/mjml/parser.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MjmlNode } from '../../types/mjml';
|
|
2
|
+
export interface RenderResult {
|
|
3
|
+
html: string;
|
|
4
|
+
errors: {
|
|
5
|
+
line: number;
|
|
6
|
+
message: string;
|
|
7
|
+
tagName: string;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render MJML JSON to HTML
|
|
12
|
+
*/
|
|
13
|
+
export declare function renderMjml(document: MjmlNode): Promise<RenderResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Render MJML string to HTML
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderMjmlString(mjmlString: string): Promise<RenderResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Render MJML JSON to HTML with block IDs preserved as CSS classes
|
|
20
|
+
* This allows clicking elements in the preview to identify the source block
|
|
21
|
+
*/
|
|
22
|
+
export declare function renderMjmlInteractive(document: MjmlNode): Promise<RenderResult>;
|
|
23
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/lib/mjml/renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9D;AA6FD;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAmB1E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC,CAkBvB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,CAAC,CAsBvB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import "uuid";
|
|
2
|
+
let o = null;
|
|
3
|
+
async function u() {
|
|
4
|
+
return o || (o = (await import("mjml-browser")).default), o;
|
|
5
|
+
}
|
|
6
|
+
function m(r) {
|
|
7
|
+
if (!r._id || !r.tagName.startsWith("mj-"))
|
|
8
|
+
return {
|
|
9
|
+
...r,
|
|
10
|
+
children: r.children?.map(m)
|
|
11
|
+
};
|
|
12
|
+
const t = r.attributes["mj-class"] || "", e = `block-${r._id}`, s = t ? `${t} ${e}` : e;
|
|
13
|
+
return {
|
|
14
|
+
...r,
|
|
15
|
+
attributes: { ...r.attributes, "mj-class": s },
|
|
16
|
+
children: r.children?.map(m)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function g(r) {
|
|
20
|
+
return p(r);
|
|
21
|
+
}
|
|
22
|
+
function p(r, t = 0) {
|
|
23
|
+
const e = " ".repeat(t), s = r.tagName, n = Object.entries(r.attributes || {}).filter(
|
|
24
|
+
([a, l]) => a !== "_id" && l !== "" && l !== void 0
|
|
25
|
+
).map(([a, l]) => `${a}="${h(l)}"`).join(" "), i = n ? `<${s} ${n}>` : `<${s}>`, c = `</${s}>`;
|
|
26
|
+
if (r.content !== void 0)
|
|
27
|
+
return `${e}${i}${r.content}${c}`;
|
|
28
|
+
if (r.children && r.children.length > 0) {
|
|
29
|
+
const a = r.children.map((l) => p(l, t + 1)).join(`
|
|
30
|
+
`);
|
|
31
|
+
return `${e}${i}
|
|
32
|
+
${a}
|
|
33
|
+
${e}${c}`;
|
|
34
|
+
}
|
|
35
|
+
return `${e}${i}${c}`;
|
|
36
|
+
}
|
|
37
|
+
function h(r) {
|
|
38
|
+
return r.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
39
|
+
}
|
|
40
|
+
async function $(r) {
|
|
41
|
+
try {
|
|
42
|
+
const e = (await u())(r, {
|
|
43
|
+
validationLevel: "soft"
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
html: e.html,
|
|
47
|
+
errors: e.errors || []
|
|
48
|
+
};
|
|
49
|
+
} catch (t) {
|
|
50
|
+
return console.error("MJML render error:", t), {
|
|
51
|
+
html: '<p style="color: red; padding: 20px;">Error rendering email preview</p>',
|
|
52
|
+
errors: [{ line: 0, message: String(t), tagName: "mjml" }]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function d(r) {
|
|
57
|
+
try {
|
|
58
|
+
const t = await u(), e = m(r), s = g(e), n = t(s, {
|
|
59
|
+
validationLevel: "soft"
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
html: n.html,
|
|
63
|
+
errors: n.errors || []
|
|
64
|
+
};
|
|
65
|
+
} catch (t) {
|
|
66
|
+
return console.error("MJML render error:", t), {
|
|
67
|
+
html: '<p style="color: red; padding: 20px;">Error rendering email preview</p>',
|
|
68
|
+
errors: [{ line: 0, message: String(t), tagName: "mjml" }]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
d as renderMjmlInteractive,
|
|
74
|
+
$ as renderMjmlString
|
|
75
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentSchema, ContentBlockType } from '../../types/mjml';
|
|
2
|
+
export declare const sectionSchema: ComponentSchema;
|
|
3
|
+
export declare const wrapperSchema: ComponentSchema;
|
|
4
|
+
export declare const columnSchema: ComponentSchema;
|
|
5
|
+
export declare const textSchema: ComponentSchema;
|
|
6
|
+
export declare const imageSchema: ComponentSchema;
|
|
7
|
+
export declare const buttonSchema: ComponentSchema;
|
|
8
|
+
export declare const dividerSchema: ComponentSchema;
|
|
9
|
+
export declare const spacerSchema: ComponentSchema;
|
|
10
|
+
export declare const bodySchema: ComponentSchema;
|
|
11
|
+
export declare function getSchemaForTag(tagName: string): ComponentSchema | null;
|
|
12
|
+
export declare const contentBlockTypes: {
|
|
13
|
+
type: ContentBlockType;
|
|
14
|
+
label: string;
|
|
15
|
+
icon: string;
|
|
16
|
+
}[];
|
|
17
|
+
export declare function getDefaultBlock(type: ContentBlockType): {
|
|
18
|
+
attributes: Record<string, string>;
|
|
19
|
+
content?: string;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/lib/mjml/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGtE,eAAO,MAAM,aAAa,EAAE,eA4K3B,CAAC;AAIF,eAAO,MAAM,aAAa,EAAE,eAwK3B,CAAC;AAGF,eAAO,MAAM,YAAY,EAAE,eA0J1B,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,eAmJxB,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,eAwMzB,CAAC;AAGF,eAAO,MAAM,YAAY,EAAE,eAsQ1B,CAAC;AAGF,eAAO,MAAM,aAAa,EAAE,eAuF3B,CAAC;AAGF,eAAO,MAAM,YAAY,EAAE,eAgD1B,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,eAsBxB,CAAC;AAGF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAuBvE;AAGD,eAAO,MAAM,iBAAiB,EAAE;IAC9B,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,EAMA,CAAC;AAGF,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG;IACvD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAgCA"}
|