@lit-pigeon/renderer-mjml 0.2.3 → 0.2.5

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.
Files changed (3) hide show
  1. package/dist/index.cjs +28 -24
  2. package/dist/index.js +158 -150
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -1,43 +1,47 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("mjml"),R=require("@lit-pigeon/core");function u(e){return`${e.top}px ${e.right}px ${e.bottom}px ${e.left}px`}function j(e){const{content:t,padding:r,textAlign:a,lineHeight:n}=e.values;return`<mj-text ${[`padding="${u(r)}"`,`align="${a}"`,`line-height="${n}"`].join(" ")}>${t}</mj-text>`}function b(e){const{src:t,alt:r,width:a,href:n,padding:o,alignment:c,borderRadius:i}=e.values,s=[`src="${g(t)}"`,`alt="${g(r)}"`,`padding="${u(o)}"`,`align="${c}"`];return a!=="auto"&&s.push(`width="${a}px"`),n&&s.push(`href="${g(n)}"`),i!==void 0&&i>0&&s.push(`border-radius="${i}px"`),`<mj-image ${s.join(" ")} />`}function g(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function k(e){const{content:t,href:r,backgroundColor:a,textColor:n,borderRadius:o,padding:c,innerPadding:i,fontSize:s,fontWeight:l,alignment:p,fullWidth:m}=e.values,f=[`href="${H(r)}"`,`background-color="${a}"`,`color="${n}"`,`border-radius="${o}px"`,`padding="${u(c)}"`,`inner-padding="${u(i)}"`,`font-size="${s}px"`,`font-weight="${l}"`,`align="${p}"`];m&&f.push('width="100%"');const C=t.replace(/^\s*<p>([\s\S]*?)<\/p>\s*$/i,"$1");return`<mj-button ${f.join(" ")}>${C}</mj-button>`}function H(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function x(e){const{borderColor:t,borderWidth:r,borderStyle:a,padding:n,width:o}=e.values;return`<mj-divider ${[`border-color="${t}"`,`border-width="${r}px"`,`border-style="${a}"`,`padding="${u(n)}"`,`width="${o}"`].join(" ")} />`}function v(e){const{height:t}=e.values;return`<mj-spacer height="${t}px" />`}function W(e){switch(e.type){case"facebook":return"facebook";case"twitter":return"twitter";case"instagram":return"instagram";case"linkedin":return"linkedin";case"youtube":return"youtube";case"tiktok":return"web";case"custom":return"web";default:return"web"}}function N(e,t){const a=[`name="${W(e)}"`,`href="${$(e.href)}"`,`icon-size="${t}px"`];e.iconUrl&&a.push(`src="${$(e.iconUrl)}"`);const n=e.label??"";return`<mj-social-element ${a.join(" ")}>${q(n)}</mj-social-element>`}function w(e){const{icons:t,iconSize:r,spacing:a,alignment:n,padding:o}=e.values,c=[`icon-size="${r}px"`,`icon-padding="${a}px"`,`align="${n}"`,`padding="${u(o)}"`,'mode="horizontal"'],i=t.map(s=>N(s,r)).join(`
2
- `);return`<mj-social ${c.join(" ")}>
3
- ${i}
4
- </mj-social>`}function $(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function q(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}const _=/<(\s*\/?\s*mj-raw\b[^>]*)>/gi;function z(e){return e.replace(_,"&lt;$1&gt;")}function y(e){const{content:t,padding:r}=e.values,a=u(r),n=z(t);return`<mj-raw><div style="padding: ${a};">${n}</div></mj-raw>`}function B(e){const{content:t,innerPadding:r}=e.values;return`<mj-text ${[`padding="${u(r)}"`].join(" ")}>${t}</mj-text>`}function M(e){const t=e.values,r=[`mode="${t.mode}"`,`height="${t.height}px"`,`vertical-align="${t.verticalAlign}"`,`padding="${u(t.padding)}"`];return t.backgroundUrl&&r.push(`background-width="${t.width}px"`),t.backgroundUrl&&(r.push(`background-url="${D(t.backgroundUrl)}"`),r.push(`background-position="${t.backgroundPosition}"`)),t.backgroundColor&&r.push(`background-color="${t.backgroundColor}"`),` <mj-hero ${r.join(" ")}>
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("mjml"),W=require("@lit-pigeon/core");function u(e){return`${e.top}px ${e.right}px ${e.bottom}px ${e.left}px`}function k(e){const{content:t,padding:r,textAlign:a,lineHeight:o,cssClass:n}=e.values,s=[`padding="${u(r)}"`,`align="${a}"`,`line-height="${o}"`];return n&&s.push(`css-class="${q(n)}"`),`<mj-text ${s.join(" ")}>${t}</mj-text>`}function q(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function y(e){const{src:t,alt:r,width:a,href:o,padding:n,alignment:s,borderRadius:c,cssClass:l}=e.values,i=[`src="${g(t)}"`,`alt="${g(r)}"`,`padding="${u(n)}"`,`align="${s}"`];return a!=="auto"&&i.push(`width="${a}px"`),o&&i.push(`href="${g(o)}"`),c!==void 0&&c>0&&i.push(`border-radius="${c}px"`),l&&i.push(`css-class="${g(l)}"`),`<mj-image ${i.join(" ")} />`}function g(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function x(e){const{content:t,href:r,backgroundColor:a,textColor:o,borderRadius:n,padding:s,innerPadding:c,fontSize:l,fontWeight:i,alignment:d,fullWidth:$,cssClass:p}=e.values,f=[`href="${h(r)}"`,`background-color="${a}"`,`color="${o}"`,`border-radius="${n}px"`,`padding="${u(s)}"`,`inner-padding="${u(c)}"`,`font-size="${l}px"`,`font-weight="${i}"`,`align="${d}"`];$&&f.push('width="100%"'),p&&f.push(`css-class="${h(p)}"`);const H=t.replace(/^\s*<p>([\s\S]*?)<\/p>\s*$/i,"$1");return`<mj-button ${f.join(" ")}>${H}</mj-button>`}function h(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function v(e){const{borderColor:t,borderWidth:r,borderStyle:a,padding:o,width:n}=e.values;return`<mj-divider ${[`border-color="${t}"`,`border-width="${r}px"`,`border-style="${a}"`,`padding="${u(o)}"`,`width="${n}"`].join(" ")} />`}function w(e){const{height:t}=e.values;return`<mj-spacer height="${t}px" />`}function N(e){switch(e.type){case"facebook":return"facebook";case"twitter":return"twitter";case"instagram":return"instagram";case"linkedin":return"linkedin";case"youtube":return"youtube";case"tiktok":return"web";case"custom":return"web";default:return"web"}}function z(e,t){const a=[`name="${N(e)}"`,`href="${j(e.href)}"`,`icon-size="${t}px"`];e.iconUrl&&a.push(`src="${j(e.iconUrl)}"`);const o=e.label??"";return`<mj-social-element ${a.join(" ")}>${_(o)}</mj-social-element>`}function B(e){const{icons:t,iconSize:r,spacing:a,alignment:o,padding:n}=e.values,s=[`icon-size="${r}px"`,`icon-padding="${a}px"`,`align="${o}"`,`padding="${u(n)}"`,'mode="horizontal"'],c=t.map(l=>z(l,r)).join(`
2
+ `);return`<mj-social ${s.join(" ")}>
3
+ ${c}
4
+ </mj-social>`}function j(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function _(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}const D=/<(\s*\/?\s*mj-raw\b[^>]*)>/gi;function O(e){return e.replace(D,"&lt;$1&gt;")}function C(e){const{content:t,padding:r}=e.values,a=u(r),o=O(t);return`<mj-raw><div class="lp-html" style="padding: ${a};">${o}</div></mj-raw>`}function A(e){const{content:t,innerPadding:r}=e.values;return`<mj-text ${[`padding="${u(r)}"`].join(" ")}>${t}</mj-text>`}function M(e){const t=e.values,r=[`mode="${t.mode}"`,`height="${t.height}px"`,`vertical-align="${t.verticalAlign}"`,`padding="${u(t.padding)}"`];return t.backgroundUrl&&r.push(`background-width="${t.width}px"`),t.backgroundUrl&&(r.push(`background-url="${I(t.backgroundUrl)}"`),r.push(`background-position="${t.backgroundPosition}"`)),t.backgroundColor&&r.push(`background-color="${t.backgroundColor}"`),` <mj-hero ${r.join(" ")}>
5
5
  <mj-text padding="${u(t.innerPadding)}">${t.content}</mj-text>
6
- </mj-hero>`}function D(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function O(e){const t=[`href="${I(e.href)}"`];return e.color&&t.push(`color="${e.color}"`),e.fontWeight&&t.push(`font-weight="${e.fontWeight}"`),e.textDecoration&&t.push(`text-decoration="${e.textDecoration}"`),e.padding&&t.push(`padding="${e.padding}"`),`<mj-navbar-link ${t.join(" ")}>${E(e.text)}</mj-navbar-link>`}function A(e){const{links:t,hamburger:r,padding:a}=e.values,n=[`hamburger="${r}"`,`padding="${u(a)}"`],o=t.map(c=>O(c)).join(`
7
- `);return`<mj-navbar ${n.join(" ")}>
8
- ${o}
9
- </mj-navbar>`}function I(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function E(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function U(e){switch(e.type){case"text":return j(e);case"image":return b(e);case"button":return k(e);case"divider":return x(e);case"spacer":return v(e);case"social":return w(e);case"html":return y(e);case"hero":return B(e);case"navbar":return A(e);default:return L(e)}}function L(e){const t=e.type,r=R.getBlockDefinition(t);return r!=null&&r.renderMjml?r.renderMjml(e):`<!-- Unknown block type: ${t} -->`}function P(e,t){const{backgroundColor:r,padding:a,borderRadius:n,verticalAlign:o}=e.attributes,c=[`width="${t}"`,`padding="${u(a)}"`,`vertical-align="${o}"`];r&&c.push(`background-color="${r}"`),n!==void 0&&n>0&&c.push(`border-radius="${n}px"`);const i=e.blocks.map(s=>` ${U(s)}`).join(`
6
+ </mj-hero>`}function I(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function E(e){const t=[`href="${U(e.href)}"`];return e.color&&t.push(`color="${e.color}"`),e.fontWeight&&t.push(`font-weight="${e.fontWeight}"`),e.textDecoration&&t.push(`text-decoration="${e.textDecoration}"`),e.padding&&t.push(`padding="${e.padding}"`),`<mj-navbar-link ${t.join(" ")}>${L(e.text)}</mj-navbar-link>`}function S(e){const{links:t,hamburger:r,padding:a}=e.values,o=[`hamburger="${r}"`,`padding="${u(a)}"`],n=t.map(s=>E(s)).join(`
7
+ `);return`<mj-navbar ${o.join(" ")}>
8
+ ${n}
9
+ </mj-navbar>`}function U(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function L(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function P(e){switch(e.type){case"text":return k(e);case"image":return y(e);case"button":return x(e);case"divider":return v(e);case"spacer":return w(e);case"social":return B(e);case"html":return C(e);case"hero":return A(e);case"navbar":return S(e);default:return K(e)}}function K(e){const t=e.type,r=W.getBlockDefinition(t);return r!=null&&r.renderMjml?r.renderMjml(e):`<!-- Unknown block type: ${t} -->`}function F(e,t){const{backgroundColor:r,padding:a,borderRadius:o,verticalAlign:n,cssClass:s}=e.attributes,c=[`width="${t}"`,`padding="${u(a)}"`,`vertical-align="${n}"`];r&&c.push(`background-color="${r}"`),o!==void 0&&o>0&&c.push(`border-radius="${o}px"`),s&&c.push(`css-class="${m(s)}"`);const l=e.blocks.map(i=>` ${P(i)}`).join(`
10
10
  `);return` <mj-column ${c.join(" ")}>
11
- ${i}
12
- </mj-column>`}function K(e){if(e.columns.length===1&&e.columns[0].blocks.length===1&&e.columns[0].blocks[0].type==="hero")return h(M(e.columns[0].blocks[0]),e.attributes.condition);const{backgroundColor:t,backgroundImage:r,padding:a,fullWidth:n}=e.attributes,o=[`padding="${u(a)}"`];n&&o.push('full-width="full-width"'),t&&o.push(`background-color="${t}"`),r&&(o.push(`background-url="${d(r)}"`),o.push('background-size="cover"'),o.push('background-repeat="no-repeat"'));const c=e.columnRatios.reduce((s,l)=>s+l,0),i=e.columns.map((s,l)=>{const m=((e.columnRatios[l]??1)/c*100).toFixed(2).replace(/\.?0+$/,"");return P(s,`${m}%`)}).join(`
13
- `);return h(` <mj-section ${o.join(" ")}>
14
- ${i}
15
- </mj-section>`,e.attributes.condition)}function h(e,t){const r=t==null?void 0:t.trim();return r?` <mj-raw>{{#if ${r}}}</mj-raw>
11
+ ${l}
12
+ </mj-column>`}function G(e){if(e.columns.length===1&&e.columns[0].blocks.length===1&&e.columns[0].blocks[0].type==="hero")return b(M(e.columns[0].blocks[0]),e.attributes.condition);const{backgroundColor:t,backgroundImage:r,padding:a,fullWidth:o,cssClass:n}=e.attributes,s=[`padding="${u(a)}"`];o&&s.push('full-width="full-width"'),t&&s.push(`background-color="${t}"`),r&&(s.push(`background-url="${m(r)}"`),s.push('background-size="cover"'),s.push('background-repeat="no-repeat"')),n&&s.push(`css-class="${m(n)}"`);const c=e.columnRatios.reduce((i,d)=>i+d,0),l=e.columns.map((i,d)=>{const p=((e.columnRatios[d]??1)/c*100).toFixed(2).replace(/\.?0+$/,"");return F(i,`${p}%`)}).join(`
13
+ `);return b(` <mj-section ${s.join(" ")}>
14
+ ${l}
15
+ </mj-section>`,e.attributes.condition)}function b(e,t){const r=t==null?void 0:t.trim();return r?` <mj-raw>{{#if ${r}}}</mj-raw>
16
16
  ${e}
17
- <mj-raw>{{/if}}</mj-raw>`:e}const F=` <mj-raw>
17
+ <mj-raw>{{/if}}</mj-raw>`:e}const J=` <mj-raw>
18
18
  <!--[if mso]>
19
19
  <style>
20
20
  body, table, td { font-family: Arial, Helvetica, sans-serif !important; }
21
21
  blockquote { margin: 0 0 16px !important; }
22
22
  </style>
23
23
  <![endif]-->
24
- </mj-raw>`,G=` <mj-raw>
24
+ </mj-raw>`,Q=` <mj-raw>
25
25
  <meta name="color-scheme" content="light dark">
26
26
  <meta name="supported-color-schemes" content="light dark">
27
- </mj-raw>`,J=` <mj-style inline="inline">
27
+ </mj-raw>`,V=` <mj-style inline="inline">
28
28
  h1, h2, h3, blockquote { margin: 0 0 0.5em; }
29
- </mj-style>`;function Q(e){const t=new Set,r=[];for(const a of e){if(!a.url||t.has(a.url))continue;t.add(a.url);const n=a.family.split(",")[0].trim().replace(/^['"]|['"]$/g,""),o=d(a.url),c=d(n);r.push(` <mj-font name="${c}" href="${o}" />`),r.push(` <mj-raw><link rel="stylesheet" href="${o}"></mj-raw>`)}return r.join(`
30
- `)}function V(e,t){const{fontFamily:r}=e.body.attributes,a=e.metadata.previewText,n=[];t.outlookWorkarounds&&(n.push(F),n.push(G),n.push(J));const o=Q(t.fonts);return o&&n.push(o),n.push(` <mj-attributes>
31
- <mj-all font-family="${d(r)}" />
29
+ </mj-style>`;function X(e){const t=new Set,r=[];for(const a of e){if(!a.url||t.has(a.url))continue;t.add(a.url);const o=a.family.split(",")[0].trim().replace(/^['"]|['"]$/g,""),n=m(a.url),s=m(o);r.push(` <mj-font name="${s}" href="${n}" />`),r.push(` <mj-raw><link rel="stylesheet" href="${n}"></mj-raw>`)}return r.join(`
30
+ `)}function Y(e,t){const{fontFamily:r,css:a}=e.body.attributes,o=e.metadata.previewText,n=[];t.outlookWorkarounds&&(n.push(J),n.push(Q),n.push(V));const s=X(t.fonts);return s&&n.push(s),n.push(` <mj-attributes>
31
+ <mj-all font-family="${m(r)}" />
32
32
  <mj-text font-size="14px" line-height="1.5" />
33
33
  <mj-button font-size="14px" />
34
- </mj-attributes>`),a&&n.push(` <mj-preview>${X(a)}</mj-preview>`),` <mj-head>
34
+ </mj-attributes>`),e.body.rows.some(l=>l.columns.some(i=>i.blocks.some(d=>d.type==="html")))&&n.push(` <mj-style inline="inline">
35
+ .lp-html { font-size: 14px; line-height: 1.5; font-family: ${r.replace(/[<>{};]/g,"")}; }
36
+ </mj-style>`),a&&n.push(` <mj-style>
37
+ ${a.replace(/<\/mj-style/gi,"<\\/mj-style")}
38
+ </mj-style>`),o&&n.push(` <mj-preview>${Z(o)}</mj-preview>`),` <mj-head>
35
39
  ${n.join(`
36
40
  `)}
37
- </mj-head>`}function S(e,t){const r={outlookWorkarounds:(t==null?void 0:t.outlookWorkarounds)??!0,fonts:(t==null?void 0:t.fonts)??[]},{width:a,backgroundColor:n}=e.body.attributes,o=[`width="${a}px"`];n&&o.push(`background-color="${n}"`);const c=V(e,r),i=e.body.rows.map(s=>K(s)).join(`
41
+ </mj-head>`}function T(e,t){const r={outlookWorkarounds:(t==null?void 0:t.outlookWorkarounds)??!0,fonts:(t==null?void 0:t.fonts)??[]},{width:a,backgroundColor:o}=e.body.attributes,n=[`width="${a}px"`];o&&n.push(`background-color="${o}"`);const s=Y(e,r),c=e.body.rows.map(l=>G(l)).join(`
38
42
  `);return`<mjml>
43
+ ${s}
44
+ <mj-body ${n.join(" ")}>
39
45
  ${c}
40
- <mj-body ${o.join(" ")}>
41
- ${i}
42
46
  </mj-body>
43
- </mjml>`}function d(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function X(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}class Y{async render(t,r){const a=S(t,{outlookWorkarounds:r==null?void 0:r.outlookWorkarounds,fonts:r==null?void 0:r.fonts}),n={keepComments:!1};r!=null&&r.minify&&(n.minify=!0),r!=null&&r.beautify&&(n.beautify=!0);try{const o=T(a,n),c=(o.errors||[]).map(i=>({message:i.message,line:i.line,tagName:i.tagName}));return{html:o.html,errors:c}}catch(o){return{html:"",errors:[{message:`MJML compilation failed: ${o instanceof Error?o.message:String(o)}`}]}}}}exports.MjmlRenderer=Y;exports.documentToMjml=S;exports.renderButtonBlock=k;exports.renderDividerBlock=x;exports.renderHeroBlock=B;exports.renderHeroSection=M;exports.renderHtmlBlock=y;exports.renderImageBlock=b;exports.renderNavBarBlock=A;exports.renderSocialBlock=w;exports.renderSpacerBlock=v;exports.renderTextBlock=j;exports.spacingToMjml=u;
47
+ </mjml>`}function m(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Z(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}class ee{async render(t,r){const a=T(t,{outlookWorkarounds:r==null?void 0:r.outlookWorkarounds,fonts:r==null?void 0:r.fonts}),o={keepComments:!1};r!=null&&r.minify&&(o.minify=!0),r!=null&&r.beautify&&(o.beautify=!0);try{const n=R(a,o),s=(n.errors||[]).map(c=>({message:c.message,line:c.line,tagName:c.tagName}));return{html:n.html,errors:s}}catch(n){return{html:"",errors:[{message:`MJML compilation failed: ${n instanceof Error?n.message:String(n)}`}]}}}}exports.MjmlRenderer=ee;exports.documentToMjml=T;exports.renderButtonBlock=x;exports.renderDividerBlock=v;exports.renderHeroBlock=A;exports.renderHeroSection=M;exports.renderHtmlBlock=C;exports.renderImageBlock=y;exports.renderNavBarBlock=S;exports.renderSocialBlock=B;exports.renderSpacerBlock=w;exports.renderTextBlock=k;exports.spacingToMjml=u;
package/dist/index.js CHANGED
@@ -1,74 +1,78 @@
1
- import b from "mjml";
2
- import { getBlockDefinition as k } from "@lit-pigeon/core";
1
+ import y from "mjml";
2
+ import { getBlockDefinition as x } from "@lit-pigeon/core";
3
3
  function u(e) {
4
4
  return `${e.top}px ${e.right}px ${e.bottom}px ${e.left}px`;
5
5
  }
6
- function x(e) {
7
- const { content: t, padding: r, textAlign: a, lineHeight: n } = e.values;
8
- return `<mj-text ${[
6
+ function w(e) {
7
+ const { content: t, padding: r, textAlign: a, lineHeight: o, cssClass: n } = e.values, s = [
9
8
  `padding="${u(r)}"`,
10
9
  `align="${a}"`,
11
- `line-height="${n}"`
12
- ].join(" ")}>${t}</mj-text>`;
10
+ `line-height="${o}"`
11
+ ];
12
+ return n && s.push(`css-class="${v(n)}"`), `<mj-text ${s.join(" ")}>${t}</mj-text>`;
13
13
  }
14
- function w(e) {
15
- const { src: t, alt: r, width: a, href: n, padding: o, alignment: c, borderRadius: i } = e.values, s = [
14
+ function v(e) {
15
+ return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
16
+ }
17
+ function C(e) {
18
+ const { src: t, alt: r, width: a, href: o, padding: n, alignment: s, borderRadius: c, cssClass: l } = e.values, i = [
16
19
  `src="${g(t)}"`,
17
20
  `alt="${g(r)}"`,
18
- `padding="${u(o)}"`,
19
- `align="${c}"`
21
+ `padding="${u(n)}"`,
22
+ `align="${s}"`
20
23
  ];
21
- return a !== "auto" && s.push(`width="${a}px"`), n && s.push(`href="${g(n)}"`), i !== void 0 && i > 0 && s.push(`border-radius="${i}px"`), `<mj-image ${s.join(" ")} />`;
24
+ return a !== "auto" && i.push(`width="${a}px"`), o && i.push(`href="${g(o)}"`), c !== void 0 && c > 0 && i.push(`border-radius="${c}px"`), l && i.push(`css-class="${g(l)}"`), `<mj-image ${i.join(" ")} />`;
22
25
  }
23
26
  function g(e) {
24
27
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
25
28
  }
26
- function v(e) {
29
+ function A(e) {
27
30
  const {
28
31
  content: t,
29
32
  href: r,
30
33
  backgroundColor: a,
31
- textColor: n,
32
- borderRadius: o,
33
- padding: c,
34
- innerPadding: i,
35
- fontSize: s,
36
- fontWeight: l,
37
- alignment: p,
38
- fullWidth: m
34
+ textColor: o,
35
+ borderRadius: n,
36
+ padding: s,
37
+ innerPadding: c,
38
+ fontSize: l,
39
+ fontWeight: i,
40
+ alignment: d,
41
+ fullWidth: $,
42
+ cssClass: p
39
43
  } = e.values, f = [
40
- `href="${y(r)}"`,
44
+ `href="${h(r)}"`,
41
45
  `background-color="${a}"`,
42
- `color="${n}"`,
43
- `border-radius="${o}px"`,
44
- `padding="${u(c)}"`,
45
- `inner-padding="${u(i)}"`,
46
- `font-size="${s}px"`,
47
- `font-weight="${l}"`,
48
- `align="${p}"`
46
+ `color="${o}"`,
47
+ `border-radius="${n}px"`,
48
+ `padding="${u(s)}"`,
49
+ `inner-padding="${u(c)}"`,
50
+ `font-size="${l}px"`,
51
+ `font-weight="${i}"`,
52
+ `align="${d}"`
49
53
  ];
50
- m && f.push('width="100%"');
51
- const j = t.replace(/^\s*<p>([\s\S]*?)<\/p>\s*$/i, "$1");
52
- return `<mj-button ${f.join(" ")}>${j}</mj-button>`;
54
+ $ && f.push('width="100%"'), p && f.push(`css-class="${h(p)}"`);
55
+ const k = t.replace(/^\s*<p>([\s\S]*?)<\/p>\s*$/i, "$1");
56
+ return `<mj-button ${f.join(" ")}>${k}</mj-button>`;
53
57
  }
54
- function y(e) {
58
+ function h(e) {
55
59
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
56
60
  }
57
- function A(e) {
58
- const { borderColor: t, borderWidth: r, borderStyle: a, padding: n, width: o } = e.values;
61
+ function B(e) {
62
+ const { borderColor: t, borderWidth: r, borderStyle: a, padding: o, width: n } = e.values;
59
63
  return `<mj-divider ${[
60
64
  `border-color="${t}"`,
61
65
  `border-width="${r}px"`,
62
66
  `border-style="${a}"`,
63
- `padding="${u(n)}"`,
64
- `width="${o}"`
67
+ `padding="${u(o)}"`,
68
+ `width="${n}"`
65
69
  ].join(" ")} />`;
66
70
  }
67
- function B(e) {
71
+ function M(e) {
68
72
  const { height: t } = e.values;
69
73
  return `<mj-spacer height="${t}px" />`;
70
74
  }
71
- function C(e) {
75
+ function R(e) {
72
76
  switch (e.type) {
73
77
  case "facebook":
74
78
  return "facebook";
@@ -88,215 +92,219 @@ function C(e) {
88
92
  return "web";
89
93
  }
90
94
  }
91
- function M(e, t) {
95
+ function S(e, t) {
92
96
  const a = [
93
- `name="${C(e)}"`,
94
- `href="${$(e.href)}"`,
97
+ `name="${R(e)}"`,
98
+ `href="${j(e.href)}"`,
95
99
  `icon-size="${t}px"`
96
100
  ];
97
- e.iconUrl && a.push(`src="${$(e.iconUrl)}"`);
98
- const n = e.label ?? "";
99
- return `<mj-social-element ${a.join(" ")}>${S(n)}</mj-social-element>`;
101
+ e.iconUrl && a.push(`src="${j(e.iconUrl)}"`);
102
+ const o = e.label ?? "";
103
+ return `<mj-social-element ${a.join(" ")}>${T(o)}</mj-social-element>`;
100
104
  }
101
- function R(e) {
102
- const { icons: t, iconSize: r, spacing: a, alignment: n, padding: o } = e.values, c = [
105
+ function H(e) {
106
+ const { icons: t, iconSize: r, spacing: a, alignment: o, padding: n } = e.values, s = [
103
107
  `icon-size="${r}px"`,
104
108
  `icon-padding="${a}px"`,
105
- `align="${n}"`,
106
- `padding="${u(o)}"`,
109
+ `align="${o}"`,
110
+ `padding="${u(n)}"`,
107
111
  'mode="horizontal"'
108
- ], i = t.map((s) => M(s, r)).join(`
112
+ ], c = t.map((l) => S(l, r)).join(`
109
113
  `);
110
- return `<mj-social ${c.join(" ")}>
111
- ${i}
114
+ return `<mj-social ${s.join(" ")}>
115
+ ${c}
112
116
  </mj-social>`;
113
117
  }
114
- function $(e) {
118
+ function j(e) {
115
119
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
116
120
  }
117
- function S(e) {
121
+ function T(e) {
118
122
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
119
123
  }
120
- const T = /<(\s*\/?\s*mj-raw\b[^>]*)>/gi;
121
- function W(e) {
122
- return e.replace(T, "&lt;$1&gt;");
123
- }
124
- function H(e) {
125
- const { content: t, padding: r } = e.values, a = u(r), n = W(t);
126
- return `<mj-raw><div style="padding: ${a};">${n}</div></mj-raw>`;
124
+ const W = /<(\s*\/?\s*mj-raw\b[^>]*)>/gi;
125
+ function z(e) {
126
+ return e.replace(W, "&lt;$1&gt;");
127
127
  }
128
128
  function N(e) {
129
+ const { content: t, padding: r } = e.values, a = u(r), o = z(t);
130
+ return `<mj-raw><div class="lp-html" style="padding: ${a};">${o}</div></mj-raw>`;
131
+ }
132
+ function _(e) {
129
133
  const { content: t, innerPadding: r } = e.values;
130
134
  return `<mj-text ${[
131
135
  `padding="${u(r)}"`
132
136
  ].join(" ")}>${t}</mj-text>`;
133
137
  }
134
- function _(e) {
138
+ function q(e) {
135
139
  const t = e.values, r = [
136
140
  `mode="${t.mode}"`,
137
141
  `height="${t.height}px"`,
138
142
  `vertical-align="${t.verticalAlign}"`,
139
143
  `padding="${u(t.padding)}"`
140
144
  ];
141
- return t.backgroundUrl && r.push(`background-width="${t.width}px"`), t.backgroundUrl && (r.push(`background-url="${z(t.backgroundUrl)}"`), r.push(`background-position="${t.backgroundPosition}"`)), t.backgroundColor && r.push(`background-color="${t.backgroundColor}"`), ` <mj-hero ${r.join(" ")}>
145
+ return t.backgroundUrl && r.push(`background-width="${t.width}px"`), t.backgroundUrl && (r.push(`background-url="${D(t.backgroundUrl)}"`), r.push(`background-position="${t.backgroundPosition}"`)), t.backgroundColor && r.push(`background-color="${t.backgroundColor}"`), ` <mj-hero ${r.join(" ")}>
142
146
  <mj-text padding="${u(t.innerPadding)}">${t.content}</mj-text>
143
147
  </mj-hero>`;
144
148
  }
145
- function z(e) {
149
+ function D(e) {
146
150
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
147
151
  }
148
- function q(e) {
152
+ function O(e) {
149
153
  const t = [
150
- `href="${O(e.href)}"`
154
+ `href="${I(e.href)}"`
151
155
  ];
152
- return e.color && t.push(`color="${e.color}"`), e.fontWeight && t.push(`font-weight="${e.fontWeight}"`), e.textDecoration && t.push(`text-decoration="${e.textDecoration}"`), e.padding && t.push(`padding="${e.padding}"`), `<mj-navbar-link ${t.join(" ")}>${E(e.text)}</mj-navbar-link>`;
156
+ return e.color && t.push(`color="${e.color}"`), e.fontWeight && t.push(`font-weight="${e.fontWeight}"`), e.textDecoration && t.push(`text-decoration="${e.textDecoration}"`), e.padding && t.push(`padding="${e.padding}"`), `<mj-navbar-link ${t.join(" ")}>${U(e.text)}</mj-navbar-link>`;
153
157
  }
154
- function D(e) {
155
- const { links: t, hamburger: r, padding: a } = e.values, n = [
158
+ function E(e) {
159
+ const { links: t, hamburger: r, padding: a } = e.values, o = [
156
160
  `hamburger="${r}"`,
157
161
  `padding="${u(a)}"`
158
- ], o = t.map((c) => q(c)).join(`
162
+ ], n = t.map((s) => O(s)).join(`
159
163
  `);
160
- return `<mj-navbar ${n.join(" ")}>
161
- ${o}
164
+ return `<mj-navbar ${o.join(" ")}>
165
+ ${n}
162
166
  </mj-navbar>`;
163
167
  }
164
- function O(e) {
168
+ function I(e) {
165
169
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
166
170
  }
167
- function E(e) {
171
+ function U(e) {
168
172
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
169
173
  }
170
- function I(e) {
174
+ function L(e) {
171
175
  switch (e.type) {
172
176
  case "text":
173
- return x(e);
174
- case "image":
175
177
  return w(e);
178
+ case "image":
179
+ return C(e);
176
180
  case "button":
177
- return v(e);
178
- case "divider":
179
181
  return A(e);
180
- case "spacer":
182
+ case "divider":
181
183
  return B(e);
184
+ case "spacer":
185
+ return M(e);
182
186
  case "social":
183
- return R(e);
184
- case "html":
185
187
  return H(e);
186
- case "hero":
188
+ case "html":
187
189
  return N(e);
190
+ case "hero":
191
+ return _(e);
188
192
  case "navbar":
189
- return D(e);
193
+ return E(e);
190
194
  default:
191
- return U(e);
195
+ return P(e);
192
196
  }
193
197
  }
194
- function U(e) {
195
- const t = e.type, r = k(t);
198
+ function P(e) {
199
+ const t = e.type, r = x(t);
196
200
  return r != null && r.renderMjml ? r.renderMjml(e) : `<!-- Unknown block type: ${t} -->`;
197
201
  }
198
- function L(e, t) {
199
- const { backgroundColor: r, padding: a, borderRadius: n, verticalAlign: o } = e.attributes, c = [
202
+ function K(e, t) {
203
+ const { backgroundColor: r, padding: a, borderRadius: o, verticalAlign: n, cssClass: s } = e.attributes, c = [
200
204
  `width="${t}"`,
201
205
  `padding="${u(a)}"`,
202
- `vertical-align="${o}"`
206
+ `vertical-align="${n}"`
203
207
  ];
204
- r && c.push(`background-color="${r}"`), n !== void 0 && n > 0 && c.push(`border-radius="${n}px"`);
205
- const i = e.blocks.map((s) => ` ${I(s)}`).join(`
208
+ r && c.push(`background-color="${r}"`), o !== void 0 && o > 0 && c.push(`border-radius="${o}px"`), s && c.push(`css-class="${m(s)}"`);
209
+ const l = e.blocks.map((i) => ` ${L(i)}`).join(`
206
210
  `);
207
211
  return ` <mj-column ${c.join(" ")}>
208
- ${i}
212
+ ${l}
209
213
  </mj-column>`;
210
214
  }
211
- function P(e) {
215
+ function F(e) {
212
216
  if (e.columns.length === 1 && e.columns[0].blocks.length === 1 && e.columns[0].blocks[0].type === "hero")
213
- return h(
214
- _(e.columns[0].blocks[0]),
217
+ return b(
218
+ q(e.columns[0].blocks[0]),
215
219
  e.attributes.condition
216
220
  );
217
- const { backgroundColor: t, backgroundImage: r, padding: a, fullWidth: n } = e.attributes, o = [
221
+ const { backgroundColor: t, backgroundImage: r, padding: a, fullWidth: o, cssClass: n } = e.attributes, s = [
218
222
  `padding="${u(a)}"`
219
223
  ];
220
- n && o.push('full-width="full-width"'), t && o.push(`background-color="${t}"`), r && (o.push(`background-url="${d(r)}"`), o.push('background-size="cover"'), o.push('background-repeat="no-repeat"'));
221
- const c = e.columnRatios.reduce((s, l) => s + l, 0), i = e.columns.map((s, l) => {
222
- const m = ((e.columnRatios[l] ?? 1) / c * 100).toFixed(2).replace(/\.?0+$/, "");
223
- return L(s, `${m}%`);
224
+ o && s.push('full-width="full-width"'), t && s.push(`background-color="${t}"`), r && (s.push(`background-url="${m(r)}"`), s.push('background-size="cover"'), s.push('background-repeat="no-repeat"')), n && s.push(`css-class="${m(n)}"`);
225
+ const c = e.columnRatios.reduce((i, d) => i + d, 0), l = e.columns.map((i, d) => {
226
+ const p = ((e.columnRatios[d] ?? 1) / c * 100).toFixed(2).replace(/\.?0+$/, "");
227
+ return K(i, `${p}%`);
224
228
  }).join(`
225
229
  `);
226
- return h(
227
- ` <mj-section ${o.join(" ")}>
228
- ${i}
230
+ return b(
231
+ ` <mj-section ${s.join(" ")}>
232
+ ${l}
229
233
  </mj-section>`,
230
234
  e.attributes.condition
231
235
  );
232
236
  }
233
- function h(e, t) {
237
+ function b(e, t) {
234
238
  const r = t == null ? void 0 : t.trim();
235
239
  return r ? ` <mj-raw>{{#if ${r}}}</mj-raw>
236
240
  ${e}
237
241
  <mj-raw>{{/if}}</mj-raw>` : e;
238
242
  }
239
- const K = ` <mj-raw>
243
+ const G = ` <mj-raw>
240
244
  <!--[if mso]>
241
245
  <style>
242
246
  body, table, td { font-family: Arial, Helvetica, sans-serif !important; }
243
247
  blockquote { margin: 0 0 16px !important; }
244
248
  </style>
245
249
  <![endif]-->
246
- </mj-raw>`, F = ` <mj-raw>
250
+ </mj-raw>`, J = ` <mj-raw>
247
251
  <meta name="color-scheme" content="light dark">
248
252
  <meta name="supported-color-schemes" content="light dark">
249
- </mj-raw>`, G = ` <mj-style inline="inline">
253
+ </mj-raw>`, Q = ` <mj-style inline="inline">
250
254
  h1, h2, h3, blockquote { margin: 0 0 0.5em; }
251
255
  </mj-style>`;
252
- function J(e) {
256
+ function V(e) {
253
257
  const t = /* @__PURE__ */ new Set(), r = [];
254
258
  for (const a of e) {
255
259
  if (!a.url || t.has(a.url)) continue;
256
260
  t.add(a.url);
257
- const n = a.family.split(",")[0].trim().replace(/^['"]|['"]$/g, ""), o = d(a.url), c = d(n);
258
- r.push(` <mj-font name="${c}" href="${o}" />`), r.push(` <mj-raw><link rel="stylesheet" href="${o}"></mj-raw>`);
261
+ const o = a.family.split(",")[0].trim().replace(/^['"]|['"]$/g, ""), n = m(a.url), s = m(o);
262
+ r.push(` <mj-font name="${s}" href="${n}" />`), r.push(` <mj-raw><link rel="stylesheet" href="${n}"></mj-raw>`);
259
263
  }
260
264
  return r.join(`
261
265
  `);
262
266
  }
263
- function Q(e, t) {
264
- const { fontFamily: r } = e.body.attributes, a = e.metadata.previewText, n = [];
265
- t.outlookWorkarounds && (n.push(K), n.push(F), n.push(G));
266
- const o = J(t.fonts);
267
- return o && n.push(o), n.push(` <mj-attributes>
268
- <mj-all font-family="${d(r)}" />
267
+ function X(e, t) {
268
+ const { fontFamily: r, css: a } = e.body.attributes, o = e.metadata.previewText, n = [];
269
+ t.outlookWorkarounds && (n.push(G), n.push(J), n.push(Q));
270
+ const s = V(t.fonts);
271
+ return s && n.push(s), n.push(` <mj-attributes>
272
+ <mj-all font-family="${m(r)}" />
269
273
  <mj-text font-size="14px" line-height="1.5" />
270
274
  <mj-button font-size="14px" />
271
- </mj-attributes>`), a && n.push(` <mj-preview>${X(a)}</mj-preview>`), ` <mj-head>
275
+ </mj-attributes>`), e.body.rows.some((l) => l.columns.some((i) => i.blocks.some((d) => d.type === "html"))) && n.push(` <mj-style inline="inline">
276
+ .lp-html { font-size: 14px; line-height: 1.5; font-family: ${r.replace(/[<>{};]/g, "")}; }
277
+ </mj-style>`), a && n.push(` <mj-style>
278
+ ${a.replace(/<\/mj-style/gi, "<\\/mj-style")}
279
+ </mj-style>`), o && n.push(` <mj-preview>${Z(o)}</mj-preview>`), ` <mj-head>
272
280
  ${n.join(`
273
281
  `)}
274
282
  </mj-head>`;
275
283
  }
276
- function V(e, t) {
284
+ function Y(e, t) {
277
285
  const r = {
278
286
  outlookWorkarounds: (t == null ? void 0 : t.outlookWorkarounds) ?? !0,
279
287
  fonts: (t == null ? void 0 : t.fonts) ?? []
280
- }, { width: a, backgroundColor: n } = e.body.attributes, o = [
288
+ }, { width: a, backgroundColor: o } = e.body.attributes, n = [
281
289
  `width="${a}px"`
282
290
  ];
283
- n && o.push(`background-color="${n}"`);
284
- const c = Q(e, r), i = e.body.rows.map((s) => P(s)).join(`
291
+ o && n.push(`background-color="${o}"`);
292
+ const s = X(e, r), c = e.body.rows.map((l) => F(l)).join(`
285
293
  `);
286
294
  return `<mjml>
295
+ ${s}
296
+ <mj-body ${n.join(" ")}>
287
297
  ${c}
288
- <mj-body ${o.join(" ")}>
289
- ${i}
290
298
  </mj-body>
291
299
  </mjml>`;
292
300
  }
293
- function d(e) {
301
+ function m(e) {
294
302
  return e.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
295
303
  }
296
- function X(e) {
304
+ function Z(e) {
297
305
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
298
306
  }
299
- class ee {
307
+ class re {
300
308
  /**
301
309
  * Renders a PigeonDocument to HTML using MJML as the compilation backend.
302
310
  *
@@ -305,44 +313,44 @@ class ee {
305
313
  * @returns A promise resolving to the rendered HTML and any errors
306
314
  */
307
315
  async render(t, r) {
308
- const a = V(t, {
316
+ const a = Y(t, {
309
317
  outlookWorkarounds: r == null ? void 0 : r.outlookWorkarounds,
310
318
  fonts: r == null ? void 0 : r.fonts
311
- }), n = {
319
+ }), o = {
312
320
  // By default MJML inlines CSS; respect the option if provided
313
321
  keepComments: !1
314
322
  };
315
- r != null && r.minify && (n.minify = !0), r != null && r.beautify && (n.beautify = !0);
323
+ r != null && r.minify && (o.minify = !0), r != null && r.beautify && (o.beautify = !0);
316
324
  try {
317
- const o = b(a, n), c = (o.errors || []).map((i) => ({
318
- message: i.message,
319
- line: i.line,
320
- tagName: i.tagName
325
+ const n = y(a, o), s = (n.errors || []).map((c) => ({
326
+ message: c.message,
327
+ line: c.line,
328
+ tagName: c.tagName
321
329
  }));
322
330
  return {
323
- html: o.html,
324
- errors: c
331
+ html: n.html,
332
+ errors: s
325
333
  };
326
- } catch (o) {
334
+ } catch (n) {
327
335
  return {
328
336
  html: "",
329
- errors: [{ message: `MJML compilation failed: ${o instanceof Error ? o.message : String(o)}` }]
337
+ errors: [{ message: `MJML compilation failed: ${n instanceof Error ? n.message : String(n)}` }]
330
338
  };
331
339
  }
332
340
  }
333
341
  }
334
342
  export {
335
- ee as MjmlRenderer,
336
- V as documentToMjml,
337
- v as renderButtonBlock,
338
- A as renderDividerBlock,
339
- N as renderHeroBlock,
340
- _ as renderHeroSection,
341
- H as renderHtmlBlock,
342
- w as renderImageBlock,
343
- D as renderNavBarBlock,
344
- R as renderSocialBlock,
345
- B as renderSpacerBlock,
346
- x as renderTextBlock,
343
+ re as MjmlRenderer,
344
+ Y as documentToMjml,
345
+ A as renderButtonBlock,
346
+ B as renderDividerBlock,
347
+ _ as renderHeroBlock,
348
+ q as renderHeroSection,
349
+ N as renderHtmlBlock,
350
+ C as renderImageBlock,
351
+ E as renderNavBarBlock,
352
+ H as renderSocialBlock,
353
+ M as renderSpacerBlock,
354
+ w as renderTextBlock,
347
355
  u as spacingToMjml
348
356
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lit-pigeon/renderer-mjml",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "MJML-based HTML renderer for Pigeon email editor",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "mjml": "^4.15.0",
23
- "@lit-pigeon/core": "^0.3.2"
23
+ "@lit-pigeon/core": "^0.3.3"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/mjml": "^4.7.0",