email-builder-utils 1.1.52 → 1.1.53
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/dist/utils/blocks/button.d.ts.map +1 -1
- package/dist/utils/blocks/button.js +28 -30
- package/dist/utils/blocks/dividers.js +30 -30
- package/dist/utils/blocks/grid.d.ts.map +1 -1
- package/dist/utils/blocks/grid.js +65 -63
- package/dist/utils/blocks/shape.js +89 -89
- package/dist/utils/blocks/text.d.ts.map +1 -1
- package/dist/utils/blocks/text.js +29 -26
- package/dist/utils/blocks/video.js +56 -56
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/common.js +4 -1
- package/dist/utils/convertJsonToHtml.js +183 -183
- package/dist/utils/outlookSupport.d.ts.map +1 -1
- package/dist/utils/outlookSupport.js +50 -47
- package/package.json +34 -34
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/button.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/button.ts"],"names":[],"mappings":"AA2IA,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,GAAG,UAuFhD"}
|
|
@@ -55,15 +55,15 @@ function appendOutlookForButton(buttonData) {
|
|
|
55
55
|
const tableMargin = containerAlign === 'center' ? 'margin:0 auto;'
|
|
56
56
|
: containerAlign === 'right' ? 'margin-left:auto;margin-right:0;'
|
|
57
57
|
: '';
|
|
58
|
-
const nonMsoAnchor = `<!--[if !mso]><!-->
|
|
59
|
-
<table border="0" cellpadding="0" cellspacing="0" role="presentation"${tableAlignAttr} style="border-collapse:separate;${tableMargin}">
|
|
60
|
-
<tr>
|
|
61
|
-
<td bgcolor="${bgColor}" align="center" valign="middle"${tdWidthAttr}${tdHeightAttr} style="background-color:${bgColor};border-radius:${br}px;${borderCss}${tdWidthCss}${tdHeightCss}box-sizing:border-box;mso-padding-alt:0;text-align:center;">
|
|
62
|
-
<a href="${safeHref}" target="_blank" rel="noreferrer noopener"
|
|
63
|
-
style="${anchorBoxStyles}color:${safeColor};font-family:${safeFF};font-size:${fs}px;font-weight:${fontWeight};text-decoration:none;text-align:center;white-space:nowrap;-webkit-text-size-adjust:none;box-sizing:border-box;">${text}</a>
|
|
64
|
-
</td>
|
|
65
|
-
</tr>
|
|
66
|
-
</table>
|
|
58
|
+
const nonMsoAnchor = `<!--[if !mso]><!-->
|
|
59
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation"${tableAlignAttr} style="border-collapse:separate;${tableMargin}">
|
|
60
|
+
<tr>
|
|
61
|
+
<td bgcolor="${bgColor}" align="center" valign="middle"${tdWidthAttr}${tdHeightAttr} style="background-color:${bgColor};border-radius:${br}px;${borderCss}${tdWidthCss}${tdHeightCss}box-sizing:border-box;mso-padding-alt:0;text-align:center;">
|
|
62
|
+
<a href="${safeHref}" target="_blank" rel="noreferrer noopener"
|
|
63
|
+
style="${anchorBoxStyles}color:${safeColor};font-family:${safeFF};font-size:${fs}px;font-weight:${fontWeight};text-decoration:none;text-align:center;white-space:nowrap;-webkit-text-size-adjust:none;box-sizing:border-box;">${text}</a>
|
|
64
|
+
</td>
|
|
65
|
+
</tr>
|
|
66
|
+
</table>
|
|
67
67
|
<!--<![endif]-->`;
|
|
68
68
|
// ── MSO: VML bulletproof button (classic Outlook / Word engine) ──
|
|
69
69
|
// VML arcsize is a percentage of half the shorter side. Clamp to 50% (pill).
|
|
@@ -71,18 +71,16 @@ function appendOutlookForButton(buttonData) {
|
|
|
71
71
|
const strokeAttrs = bw > 0
|
|
72
72
|
? `stroke="true" strokecolor="${bdColor}" strokeweight="${bw}px"`
|
|
73
73
|
: `stroke="false"`;
|
|
74
|
-
const msoButton = `<!--[if mso]>
|
|
75
|
-
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
|
|
76
|
-
href="${safeHref}"
|
|
77
|
-
style="height:${finalHeight}px;v-text-anchor:middle;width:${vmlWidth}px;"
|
|
78
|
-
arcsize="${arcSizePct}%"
|
|
79
|
-
${strokeAttrs}
|
|
80
|
-
fillcolor="${bgColor}">
|
|
81
|
-
<w:anchorlock/>
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
</v:textbox>
|
|
85
|
-
</v:roundrect>
|
|
74
|
+
const msoButton = `<!--[if mso]>
|
|
75
|
+
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
|
|
76
|
+
href="${safeHref}"
|
|
77
|
+
style="height:${finalHeight}px;v-text-anchor:middle;width:${vmlWidth}px;"
|
|
78
|
+
arcsize="${arcSizePct}%"
|
|
79
|
+
${strokeAttrs}
|
|
80
|
+
fillcolor="${bgColor}">
|
|
81
|
+
<w:anchorlock/>
|
|
82
|
+
<center style="color:${safeColor};font-family:${safeFF};font-size:${fs}px;font-weight:${fontWeight};mso-line-height-rule:exactly;line-height:${fs}px;text-decoration:none;">${text}</center>
|
|
83
|
+
</v:roundrect>
|
|
86
84
|
<![endif]-->`;
|
|
87
85
|
const innerContent = containerAlign === "center"
|
|
88
86
|
? `<center>${msoButton}${nonMsoAnchor}</center>`
|
|
@@ -167,14 +165,14 @@ function convertButtonBlock(blockData) {
|
|
|
167
165
|
hideOnDesktop: Boolean(props.hideOnDesktop),
|
|
168
166
|
hideOnMobile: Boolean(props.hideOnMobile),
|
|
169
167
|
});
|
|
170
|
-
return `
|
|
171
|
-
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation" class="${visibilityClass}" data-block-type="button" data-block-props="${buttonBlockProps}" style="border-collapse:collapse;table-layout:fixed;">
|
|
172
|
-
<tr>
|
|
173
|
-
<td align="${computed.containerAlign}"${(0, common_1.buildOutlookBgAttr)(containerBg)}
|
|
174
|
-
style="padding:${padding?.top || 0}px ${padding?.right || 0}px ${padding?.bottom || 0}px ${padding?.left || 0}px;background-color:${containerBg || 'transparent'};">
|
|
175
|
-
${innerContent}
|
|
176
|
-
</td>
|
|
177
|
-
</tr>
|
|
178
|
-
</table>
|
|
168
|
+
return `
|
|
169
|
+
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation" class="${visibilityClass}" data-block-type="button" data-block-props="${buttonBlockProps}" style="border-collapse:collapse;table-layout:fixed;">
|
|
170
|
+
<tr>
|
|
171
|
+
<td align="${computed.containerAlign}"${(0, common_1.buildOutlookBgAttr)(containerBg)}
|
|
172
|
+
style="padding:${padding?.top || 0}px ${padding?.right || 0}px ${padding?.bottom || 0}px ${padding?.left || 0}px;background-color:${containerBg || 'transparent'};">
|
|
173
|
+
${innerContent}
|
|
174
|
+
</td>
|
|
175
|
+
</tr>
|
|
176
|
+
</table>
|
|
179
177
|
`;
|
|
180
178
|
}
|
|
@@ -21,23 +21,23 @@ function convertDividerBlockToHtml(blockData) {
|
|
|
21
21
|
hideOnMobile ? "hide-mobile" : "",
|
|
22
22
|
hideOnDesktop ? "hide-desktop" : "",
|
|
23
23
|
].filter(Boolean).join(" ");
|
|
24
|
-
const dividerContent = `
|
|
25
|
-
<table
|
|
26
|
-
align="${alignAttr}"
|
|
27
|
-
width="${dividerWidth}%"
|
|
28
|
-
cellpadding="0"
|
|
29
|
-
cellspacing="0"
|
|
30
|
-
style="margin:${alignMargin};"
|
|
31
|
-
>
|
|
32
|
-
<tr>
|
|
33
|
-
<td
|
|
34
|
-
height="${thickness}"
|
|
35
|
-
style="font-size:1px; line-height:1px; background:${dividerColor}; width:100%;"
|
|
36
|
-
>
|
|
37
|
-
|
|
38
|
-
</td>
|
|
39
|
-
</tr>
|
|
40
|
-
</table>
|
|
24
|
+
const dividerContent = `
|
|
25
|
+
<table
|
|
26
|
+
align="${alignAttr}"
|
|
27
|
+
width="${dividerWidth}%"
|
|
28
|
+
cellpadding="0"
|
|
29
|
+
cellspacing="0"
|
|
30
|
+
style="margin:${alignMargin};"
|
|
31
|
+
>
|
|
32
|
+
<tr>
|
|
33
|
+
<td
|
|
34
|
+
height="${thickness}"
|
|
35
|
+
style="font-size:1px; line-height:1px; background:${dividerColor}; width:100%;"
|
|
36
|
+
>
|
|
37
|
+
|
|
38
|
+
</td>
|
|
39
|
+
</tr>
|
|
40
|
+
</table>
|
|
41
41
|
`;
|
|
42
42
|
return (0, outlookSupport_1.appendOutlookSupport)(dividerContent, contentStyle, visibilityClass);
|
|
43
43
|
}
|
|
@@ -55,18 +55,18 @@ function convertVerticalDividerBlockToHtml(blockData) {
|
|
|
55
55
|
perChanges: [],
|
|
56
56
|
pxChanges: buildStyles_1.allPxAttributes,
|
|
57
57
|
});
|
|
58
|
-
return `
|
|
59
|
-
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
|
|
60
|
-
style="${buildStyles_1.tableCommonStyle}; max-width:600px;" class="${visibilityClass}" data-block-type="vdivider">
|
|
61
|
-
<tr>
|
|
62
|
-
<td style="${outerStyles}; text-align:center; vertical-align:middle;">
|
|
63
|
-
<!--[if mso | IE]>
|
|
64
|
-
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fillcolor="${dividerColor}" style="width:${width}px;height:${height}px;" stroke="f"></v:rect>
|
|
65
|
-
<![endif]-->
|
|
66
|
-
<!--[if !mso]><!-->
|
|
67
|
-
<div style="display:inline-block;width:${width}px;height:${height}px;background:${dividerColor};line-height:0;font-size:0;"> </div>
|
|
68
|
-
<!--<![endif]-->
|
|
69
|
-
</td>
|
|
70
|
-
</tr>
|
|
58
|
+
return `
|
|
59
|
+
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
|
|
60
|
+
style="${buildStyles_1.tableCommonStyle}; max-width:600px;" class="${visibilityClass}" data-block-type="vdivider">
|
|
61
|
+
<tr>
|
|
62
|
+
<td style="${outerStyles}; text-align:center; vertical-align:middle;">
|
|
63
|
+
<!--[if mso | IE]>
|
|
64
|
+
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" fillcolor="${dividerColor}" style="width:${width}px;height:${height}px;" stroke="f"></v:rect>
|
|
65
|
+
<![endif]-->
|
|
66
|
+
<!--[if !mso]><!-->
|
|
67
|
+
<div style="display:inline-block;width:${width}px;height:${height}px;background:${dividerColor};line-height:0;font-size:0;"> </div>
|
|
68
|
+
<!--<![endif]-->
|
|
69
|
+
</td>
|
|
70
|
+
</tr>
|
|
71
71
|
</table>`;
|
|
72
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/grid.ts"],"names":[],"mappings":"AAMA,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,GAAG,EACd,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,MAAM,mBA0TtB;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,GAAG,EACd,QAAQ,EAAE,GAAG,EACb,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,EAAE,MAAM,EACzB,mBAAmB,UAAQ;;;
|
|
1
|
+
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/grid.ts"],"names":[],"mappings":"AAMA,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,GAAG,EACd,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,MAAM,mBA0TtB;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,GAAG,EACd,QAAQ,EAAE,GAAG,EACb,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,EAAE,MAAM,EACzB,mBAAmB,UAAQ;;;GA0G5B"}
|
|
@@ -91,18 +91,18 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
91
91
|
: '';
|
|
92
92
|
const divWrapOpen = divBorderStyle ? `<div style="${divBorderStyle}${divWrapBg}">` : '';
|
|
93
93
|
const divWrapClose = divBorderStyle ? `</div>` : '';
|
|
94
|
-
let html = `
|
|
95
|
-
<!--[if mso]>
|
|
96
|
-
<table border="0" cellpadding="0" cellspacing="0" width="${msoTableWidth}"${msoBgAttr}
|
|
97
|
-
style="border-collapse:collapse;width:${msoTableWidth}px;${msoBgStyle}${innerBgTransparent}"
|
|
98
|
-
class="${gridVisibilityClass}">
|
|
99
|
-
<![endif]-->
|
|
100
|
-
<!--[if !mso]><!-->
|
|
101
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" align="center"
|
|
102
|
-
role="presentation"${nonMsoBgAttr}
|
|
103
|
-
style="border-collapse:collapse; table-layout:fixed; ${innerBgTransparent}${tableStyles}; max-width:600px;"
|
|
104
|
-
class="${gridVisibilityClass}">
|
|
105
|
-
<!--<![endif]-->
|
|
94
|
+
let html = `
|
|
95
|
+
<!--[if mso]>
|
|
96
|
+
<table border="0" cellpadding="0" cellspacing="0" width="${msoTableWidth}"${msoBgAttr}
|
|
97
|
+
style="border-collapse:collapse;width:${msoTableWidth}px;${msoBgStyle}${innerBgTransparent}"
|
|
98
|
+
class="${gridVisibilityClass}">
|
|
99
|
+
<![endif]-->
|
|
100
|
+
<!--[if !mso]><!-->
|
|
101
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" align="center"
|
|
102
|
+
role="presentation"${nonMsoBgAttr}
|
|
103
|
+
style="border-collapse:collapse; table-layout:fixed; ${innerBgTransparent}${tableStyles}; max-width:600px;"
|
|
104
|
+
class="${gridVisibilityClass}">
|
|
105
|
+
<!--<![endif]-->
|
|
106
106
|
`;
|
|
107
107
|
for (let r = 0; r < visualRows; r++) {
|
|
108
108
|
html += "<tr>";
|
|
@@ -167,13 +167,13 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
167
167
|
const canApplyGridBgFallback = !cellHasBorderRadius && !divBorderStyle;
|
|
168
168
|
const effectiveCellBg = cellBgColor || (canApplyGridBgFallback ? msoBgColor : '');
|
|
169
169
|
const cellBgAttr = (0, common_1.buildOutlookBgAttr)(effectiveCellBg);
|
|
170
|
-
html += `
|
|
171
|
-
<td
|
|
172
|
-
width="${Math.max(1, Math.round(widthPercent))}%"${cellBgAttr}
|
|
173
|
-
class="${[responsive ? "stack-column" : "", visibilityClass].filter(Boolean).join(" ")}"
|
|
174
|
-
style="width:${widthPercent}%;vertical-align:${verticalAlign};word-break:break-word;${styles}"
|
|
175
|
-
>
|
|
176
|
-
${childHtml}
|
|
170
|
+
html += `
|
|
171
|
+
<td
|
|
172
|
+
width="${Math.max(1, Math.round(widthPercent))}%"${cellBgAttr}
|
|
173
|
+
class="${[responsive ? "stack-column" : "", visibilityClass].filter(Boolean).join(" ")}"
|
|
174
|
+
style="width:${widthPercent}%;vertical-align:${verticalAlign};word-break:break-word;${styles}"
|
|
175
|
+
>
|
|
176
|
+
${childHtml}
|
|
177
177
|
</td>`;
|
|
178
178
|
// Spacer td between columns — uses width attribute only (no inline style width) so
|
|
179
179
|
// Outlook mobile (which strips <style>) treats it proportionally, not as a fixed blocker.
|
|
@@ -186,11 +186,11 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
186
186
|
}
|
|
187
187
|
else {
|
|
188
188
|
const emptyBgAttr = divBorderStyle ? '' : (0, common_1.buildOutlookBgAttr)(msoBgColor);
|
|
189
|
-
html += `
|
|
190
|
-
<td width="${Math.max(1, Math.round(widthPercent))}%"
|
|
191
|
-
${emptyBgAttr}
|
|
192
|
-
${responsive ? 'class="stack-column"' : ""}
|
|
193
|
-
style="width:${widthPercent}%;vertical-align:top;">
|
|
189
|
+
html += `
|
|
190
|
+
<td width="${Math.max(1, Math.round(widthPercent))}%"
|
|
191
|
+
${emptyBgAttr}
|
|
192
|
+
${responsive ? 'class="stack-column"' : ""}
|
|
193
|
+
style="width:${widthPercent}%;vertical-align:top;">
|
|
194
194
|
</td>`;
|
|
195
195
|
if (columnGap > 0 && c !== lastVisibleCol) {
|
|
196
196
|
const gapBgAttr = divBorderStyle ? '' : (0, common_1.buildOutlookBgAttr)(msoBgColor);
|
|
@@ -201,13 +201,13 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
201
201
|
html += "</tr>";
|
|
202
202
|
}
|
|
203
203
|
// Close both MSO and non-MSO tables
|
|
204
|
-
html += `
|
|
205
|
-
<!--[if mso]>
|
|
206
|
-
</table>
|
|
207
|
-
<![endif]-->
|
|
208
|
-
<!--[if !mso]><!-->
|
|
209
|
-
</table>
|
|
210
|
-
<!--<![endif]-->
|
|
204
|
+
html += `
|
|
205
|
+
<!--[if mso]>
|
|
206
|
+
</table>
|
|
207
|
+
<![endif]-->
|
|
208
|
+
<!--[if !mso]><!-->
|
|
209
|
+
</table>
|
|
210
|
+
<!--<![endif]-->
|
|
211
211
|
`;
|
|
212
212
|
// ── Background image: canonical multi-client approach ────────────────────
|
|
213
213
|
//
|
|
@@ -233,35 +233,35 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
233
233
|
return `<v:fill type="gradient" color="${c1}" color2="${c2}" angle="${vmlAngle}" />`;
|
|
234
234
|
})()
|
|
235
235
|
: `<v:fill type="frame" src="${rawBgImageUrl}" color="${fallbackBgColor}" />`;
|
|
236
|
-
html = `
|
|
237
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation"
|
|
238
|
-
style="border-collapse:collapse;table-layout:fixed;width:100%;max-width:${msoTableWidth}px;">
|
|
239
|
-
<tr>
|
|
240
|
-
<td width="100%"${(0, common_1.buildOutlookBgAttr)(fallbackBgColor)} valign="top"
|
|
241
|
-
${!isGradient && rawBgImageUrl ? `background="${rawBgImageUrl}"` : ""}
|
|
242
|
-
style="
|
|
243
|
-
width:100%;max-width:${msoTableWidth}px;
|
|
244
|
-
background-color:${fallbackBgColor};
|
|
245
|
-
${isGradient ? `background:${effectiveGradient};` : `background-image:url('${rawBgImageUrl}'); background-position:center center; background-size:cover; background-repeat:no-repeat;`}
|
|
246
|
-
">
|
|
247
|
-
|
|
248
|
-
<!--[if gte mso 9]>
|
|
249
|
-
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
|
250
|
-
fill="true" stroke="false"
|
|
251
|
-
style="width:${msoTableWidth}px;">
|
|
252
|
-
${vmlFill}
|
|
253
|
-
<v:textbox inset="0,0,0,0">
|
|
254
|
-
<![endif]-->
|
|
255
|
-
|
|
256
|
-
${html}
|
|
257
|
-
|
|
258
|
-
<!--[if gte mso 9]>
|
|
259
|
-
</v:textbox>
|
|
260
|
-
</v:rect>
|
|
261
|
-
<![endif]-->
|
|
262
|
-
|
|
263
|
-
</td>
|
|
264
|
-
</tr>
|
|
236
|
+
html = `
|
|
237
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation"
|
|
238
|
+
style="border-collapse:collapse;table-layout:fixed;width:100%;max-width:${msoTableWidth}px;">
|
|
239
|
+
<tr>
|
|
240
|
+
<td width="100%"${(0, common_1.buildOutlookBgAttr)(fallbackBgColor)} valign="top"
|
|
241
|
+
${!isGradient && rawBgImageUrl ? `background="${rawBgImageUrl}"` : ""}
|
|
242
|
+
style="
|
|
243
|
+
width:100%;max-width:${msoTableWidth}px;
|
|
244
|
+
background-color:${fallbackBgColor};
|
|
245
|
+
${isGradient ? `background:${effectiveGradient};` : `background-image:url('${rawBgImageUrl}'); background-position:center center; background-size:cover; background-repeat:no-repeat;`}
|
|
246
|
+
">
|
|
247
|
+
|
|
248
|
+
<!--[if gte mso 9]>
|
|
249
|
+
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
|
250
|
+
fill="true" stroke="false"
|
|
251
|
+
style="width:${msoTableWidth}px;">
|
|
252
|
+
${vmlFill}
|
|
253
|
+
<v:textbox inset="0,0,0,0">
|
|
254
|
+
<![endif]-->
|
|
255
|
+
|
|
256
|
+
${html}
|
|
257
|
+
|
|
258
|
+
<!--[if gte mso 9]>
|
|
259
|
+
</v:textbox>
|
|
260
|
+
</v:rect>
|
|
261
|
+
<![endif]-->
|
|
262
|
+
|
|
263
|
+
</td>
|
|
264
|
+
</tr>
|
|
265
265
|
</table>`;
|
|
266
266
|
}
|
|
267
267
|
// Wrap the entire grid (including any bg-image outer table) in a div when the block
|
|
@@ -320,7 +320,7 @@ async function convertGridCellBlock(blockData, rootData, cellWidthPercent, paren
|
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
const borderRadius = cellBorderRadius || 0;
|
|
323
|
-
const bgColor = styleWithoutBorder?.backgroundColor || "
|
|
323
|
+
const bgColor = styleWithoutBorder?.backgroundColor || "";
|
|
324
324
|
// Build border CSS for the div wrapper.
|
|
325
325
|
// When the parent grid already has a divBorderStyle wrapper (border + border-radius +
|
|
326
326
|
// overflow:hidden), the cell must NOT duplicate the same border/radius — that causes
|
|
@@ -342,8 +342,10 @@ async function convertGridCellBlock(blockData, rootData, cellWidthPercent, paren
|
|
|
342
342
|
}
|
|
343
343
|
const cellDivBorderStyle = cellDivBorderParts.join(' ');
|
|
344
344
|
// Unconditional div — visible to all clients (Gmail, Outlook new/old, Apple Mail).
|
|
345
|
-
// background-color on the div covers modern clients
|
|
346
|
-
|
|
345
|
+
// background-color on the div covers modern clients when a real color is set.
|
|
346
|
+
// When no color is set, omit the property entirely — writing background-color:transparent
|
|
347
|
+
// defeats the bgcolor attribute on the parent <td> in Old Outlook's Word engine.
|
|
348
|
+
const divStyleParts = bgColor ? [`background-color:${bgColor};`] : [];
|
|
347
349
|
const formatPad = (value) => (typeof value === 'number' ? `${value}px` : (value || '0'));
|
|
348
350
|
const cellPadTop = formatPad(cellPad.top);
|
|
349
351
|
const cellPadBottom = formatPad(cellPad.bottom);
|
|
@@ -33,23 +33,23 @@ function buildVMLShape({ shape, widthPx, heightPx, imageUrl, backgroundColor, bo
|
|
|
33
33
|
const hAlign = hAlignMap[textAlign] || "center";
|
|
34
34
|
const safeFontSize = Math.max(Math.round(textSize), 10);
|
|
35
35
|
const textboxMarkup = text && !msoHasBakedText
|
|
36
|
-
? `<v:textbox inset="6pt,6pt,6pt,6pt" style="mso-fit-shape-to-text:false;">
|
|
37
|
-
<div style="display:table;width:100%;height:100%;">
|
|
38
|
-
<div style="display:table-cell;vertical-align:${vAlign};text-align:${hAlign};padding:0 6px;">
|
|
39
|
-
<div style="color:${textColor};font-family:Arial, sans-serif;font-size:${safeFontSize}px;line-height:1.3;word-wrap:break-word;">
|
|
40
|
-
${text}
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
36
|
+
? `<v:textbox inset="6pt,6pt,6pt,6pt" style="mso-fit-shape-to-text:false;">
|
|
37
|
+
<div style="display:table;width:100%;height:100%;">
|
|
38
|
+
<div style="display:table-cell;vertical-align:${vAlign};text-align:${hAlign};padding:0 6px;">
|
|
39
|
+
<div style="color:${textColor};font-family:Arial, sans-serif;font-size:${safeFontSize}px;line-height:1.3;word-wrap:break-word;">
|
|
40
|
+
${text}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
44
|
</v:textbox>`
|
|
45
45
|
: `<v:textbox inset="0,0,0,0"><div style="display:none;">.</div></v:textbox>`;
|
|
46
|
-
return `
|
|
47
|
-
<v:${tag} xmlns:v="urn:schemas-microsoft-com:vml"
|
|
48
|
-
style="width:${widthPx}px;height:${heightPx}px;display:inline-block;"
|
|
49
|
-
${borderAttrs}
|
|
50
|
-
fill="true" fillcolor="${fillColor}"${extraAttr}>
|
|
51
|
-
${fillMarkup}
|
|
52
|
-
${textboxMarkup}
|
|
46
|
+
return `
|
|
47
|
+
<v:${tag} xmlns:v="urn:schemas-microsoft-com:vml"
|
|
48
|
+
style="width:${widthPx}px;height:${heightPx}px;display:inline-block;"
|
|
49
|
+
${borderAttrs}
|
|
50
|
+
fill="true" fillcolor="${fillColor}"${extraAttr}>
|
|
51
|
+
${fillMarkup}
|
|
52
|
+
${textboxMarkup}
|
|
53
53
|
</v:${tag}>`;
|
|
54
54
|
}
|
|
55
55
|
function appendOutlookForShape(content, outerContainerWidth, innerContainerWidth, opts, visibilityClass) {
|
|
@@ -70,28 +70,28 @@ function appendOutlookForShape(content, outerContainerWidth, innerContainerWidth
|
|
|
70
70
|
const valign = opts.verticalAlign || "middle";
|
|
71
71
|
const shouldHideInOutlook = visibilityClass.includes("hide-desktop");
|
|
72
72
|
if (shouldHideInOutlook) {
|
|
73
|
-
return `<!--[if !mso]><!-->
|
|
74
|
-
<table align="${align}" border="0" cellpadding="0" cellspacing="0"
|
|
75
|
-
style="width:${widthPx}px;height:${heightPx}px;border-collapse:collapse;" class="${visibilityClass}">
|
|
76
|
-
<tr>
|
|
77
|
-
<td valign="${valign}"
|
|
78
|
-
style="padding:${pad.top || 0}px ${pad.right || 0}px ${pad.bottom || 0}px ${pad.left || 0}px;">
|
|
79
|
-
${vml}
|
|
80
|
-
</td>
|
|
81
|
-
</tr>
|
|
82
|
-
</table>
|
|
73
|
+
return `<!--[if !mso]><!-->
|
|
74
|
+
<table align="${align}" border="0" cellpadding="0" cellspacing="0"
|
|
75
|
+
style="width:${widthPx}px;height:${heightPx}px;border-collapse:collapse;" class="${visibilityClass}">
|
|
76
|
+
<tr>
|
|
77
|
+
<td valign="${valign}"
|
|
78
|
+
style="padding:${pad.top || 0}px ${pad.right || 0}px ${pad.bottom || 0}px ${pad.left || 0}px;">
|
|
79
|
+
${vml}
|
|
80
|
+
</td>
|
|
81
|
+
</tr>
|
|
82
|
+
</table>
|
|
83
83
|
<!--<![endif]-->`;
|
|
84
84
|
}
|
|
85
|
-
return `<!--[if mso]>
|
|
86
|
-
<table align="${align}" border="0" cellpadding="0" cellspacing="0"
|
|
87
|
-
style="width:${widthPx}px;height:${heightPx}px;border-collapse:collapse;" class="${visibilityClass}">
|
|
88
|
-
<tr>
|
|
89
|
-
<td valign="${valign}"
|
|
90
|
-
style="padding:${pad.top || 0}px ${pad.right || 0}px ${pad.bottom || 0}px ${pad.left || 0}px;">
|
|
91
|
-
${vml}
|
|
92
|
-
</td>
|
|
93
|
-
</tr>
|
|
94
|
-
</table>
|
|
85
|
+
return `<!--[if mso]>
|
|
86
|
+
<table align="${align}" border="0" cellpadding="0" cellspacing="0"
|
|
87
|
+
style="width:${widthPx}px;height:${heightPx}px;border-collapse:collapse;" class="${visibilityClass}">
|
|
88
|
+
<tr>
|
|
89
|
+
<td valign="${valign}"
|
|
90
|
+
style="padding:${pad.top || 0}px ${pad.right || 0}px ${pad.bottom || 0}px ${pad.left || 0}px;">
|
|
91
|
+
${vml}
|
|
92
|
+
</td>
|
|
93
|
+
</tr>
|
|
94
|
+
</table>
|
|
95
95
|
<![endif]-->`;
|
|
96
96
|
}
|
|
97
97
|
async function convertShapeBlock(blockData) {
|
|
@@ -146,58 +146,58 @@ async function convertShapeBlock(blockData) {
|
|
|
146
146
|
let nonMsoContent = "";
|
|
147
147
|
// --- Case 1: Image + Text ---
|
|
148
148
|
if (imageUrl && text) {
|
|
149
|
-
nonMsoContent = `
|
|
150
|
-
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;max-width:100%;box-sizing:border-box;
|
|
151
|
-
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
152
|
-
border-radius:${resolvedBorderRadius};
|
|
153
|
-
background-color:${finalBackgroundColor};
|
|
154
|
-
background-image:url('${imageUrl}');
|
|
155
|
-
background-position:center center;
|
|
156
|
-
background-size:cover;
|
|
157
|
-
background-repeat:no-repeat;
|
|
158
|
-
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
159
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%"
|
|
160
|
-
style="width:100%;height:${resolvedHeightPx}px;border-collapse:collapse;">
|
|
161
|
-
<tr>
|
|
162
|
-
<td align="${textAlignStyle}" valign="${verticalAlign}"
|
|
163
|
-
height="${resolvedHeightPx}"
|
|
164
|
-
style="padding:6px;vertical-align:${verticalAlign};text-align:${textAlignStyle};overflow:hidden;box-sizing:border-box;">
|
|
165
|
-
<div style="${textSizeStyle}text-align:${textAlignStyle};max-width:90%;overflow:hidden;">${text}</div>
|
|
166
|
-
</td>
|
|
167
|
-
</tr>
|
|
168
|
-
</table>
|
|
149
|
+
nonMsoContent = `
|
|
150
|
+
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;max-width:100%;box-sizing:border-box;
|
|
151
|
+
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
152
|
+
border-radius:${resolvedBorderRadius};
|
|
153
|
+
background-color:${finalBackgroundColor};
|
|
154
|
+
background-image:url('${imageUrl}');
|
|
155
|
+
background-position:center center;
|
|
156
|
+
background-size:cover;
|
|
157
|
+
background-repeat:no-repeat;
|
|
158
|
+
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
159
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%"
|
|
160
|
+
style="width:100%;height:${resolvedHeightPx}px;border-collapse:collapse;">
|
|
161
|
+
<tr>
|
|
162
|
+
<td align="${textAlignStyle}" valign="${verticalAlign}"
|
|
163
|
+
height="${resolvedHeightPx}"
|
|
164
|
+
style="padding:6px;vertical-align:${verticalAlign};text-align:${textAlignStyle};overflow:hidden;box-sizing:border-box;">
|
|
165
|
+
<div style="${textSizeStyle}text-align:${textAlignStyle};max-width:90%;overflow:hidden;">${text}</div>
|
|
166
|
+
</td>
|
|
167
|
+
</tr>
|
|
168
|
+
</table>
|
|
169
169
|
</div>`;
|
|
170
170
|
}
|
|
171
171
|
// --- Case 2: Image only ---
|
|
172
172
|
else if (imageUrl) {
|
|
173
|
-
nonMsoContent = `
|
|
174
|
-
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;max-width:100%;box-sizing:border-box;
|
|
175
|
-
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
176
|
-
border-radius:${resolvedBorderRadius};
|
|
177
|
-
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
178
|
-
<img src="${imageUrl}" alt="${text || "shape image"}"
|
|
179
|
-
width="${resolvedWidthPx}" height="${resolvedHeightPx}"
|
|
180
|
-
style="width:100%;height:100%;object-fit:cover;border-radius:${resolvedBorderRadius};display:block;" />
|
|
173
|
+
nonMsoContent = `
|
|
174
|
+
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;max-width:100%;box-sizing:border-box;
|
|
175
|
+
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
176
|
+
border-radius:${resolvedBorderRadius};
|
|
177
|
+
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
178
|
+
<img src="${imageUrl}" alt="${text || "shape image"}"
|
|
179
|
+
width="${resolvedWidthPx}" height="${resolvedHeightPx}"
|
|
180
|
+
style="width:100%;height:100%;object-fit:cover;border-radius:${resolvedBorderRadius};display:block;" />
|
|
181
181
|
</div>`;
|
|
182
182
|
}
|
|
183
183
|
// --- Case 3: Text only ---
|
|
184
184
|
else {
|
|
185
|
-
nonMsoContent = `
|
|
186
|
-
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;max-width:100%;box-sizing:border-box;
|
|
187
|
-
background-color:${finalBackgroundColor};
|
|
188
|
-
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
189
|
-
border-radius:${resolvedBorderRadius};
|
|
190
|
-
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
191
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%"
|
|
192
|
-
style="width:100%;height:${resolvedHeightPx}px;border-collapse:collapse;">
|
|
193
|
-
<tr>
|
|
194
|
-
<td align="${textAlignStyle}" valign="${verticalAlign}"
|
|
195
|
-
height="${resolvedHeightPx}"
|
|
196
|
-
style="padding:8px;vertical-align:${verticalAlign};text-align:${textAlignStyle};box-sizing:border-box;">
|
|
197
|
-
<div style="${textSizeStyle}text-align:${textAlignStyle};max-width:90%;overflow:hidden;">${text || ""}</div>
|
|
198
|
-
</td>
|
|
199
|
-
</tr>
|
|
200
|
-
</table>
|
|
185
|
+
nonMsoContent = `
|
|
186
|
+
<div style="display:inline-block;width:${resolvedWidthPx}px;height:${resolvedHeightPx}px;max-width:100%;box-sizing:border-box;
|
|
187
|
+
background-color:${finalBackgroundColor};
|
|
188
|
+
border:${borderWidth}px ${borderStyle} ${borderColor};
|
|
189
|
+
border-radius:${resolvedBorderRadius};
|
|
190
|
+
overflow:hidden;${alignmentStyle}${customCss || ""}">
|
|
191
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%"
|
|
192
|
+
style="width:100%;height:${resolvedHeightPx}px;border-collapse:collapse;">
|
|
193
|
+
<tr>
|
|
194
|
+
<td align="${textAlignStyle}" valign="${verticalAlign}"
|
|
195
|
+
height="${resolvedHeightPx}"
|
|
196
|
+
style="padding:8px;vertical-align:${verticalAlign};text-align:${textAlignStyle};box-sizing:border-box;">
|
|
197
|
+
<div style="${textSizeStyle}text-align:${textAlignStyle};max-width:90%;overflow:hidden;">${text || ""}</div>
|
|
198
|
+
</td>
|
|
199
|
+
</tr>
|
|
200
|
+
</table>
|
|
201
201
|
</div>`;
|
|
202
202
|
}
|
|
203
203
|
// Outlook (VML) fallback
|
|
@@ -242,15 +242,15 @@ async function convertShapeBlock(blockData) {
|
|
|
242
242
|
hideOnMobile: Boolean(props.hideOnMobile),
|
|
243
243
|
});
|
|
244
244
|
// Combine into table wrapper
|
|
245
|
-
return `
|
|
246
|
-
<table width="100%" style="border-collapse:collapse;table-layout:fixed;max-width:600px;" class="${visibilityClass}" data-block-type="shape" data-block-props="${shapeBlockProps}">
|
|
247
|
-
<tr>
|
|
248
|
-
<td style="padding:${padding.top || 0}px ${padding.right || 0}px ${padding.bottom || 0}px ${padding.left || 0}px;text-align:${alignment};">
|
|
249
|
-
${outlookContent}
|
|
250
|
-
<!--[if !mso]><!-->
|
|
251
|
-
${nonMsoContent}
|
|
252
|
-
<!--<![endif]-->
|
|
253
|
-
</td>
|
|
254
|
-
</tr>
|
|
245
|
+
return `
|
|
246
|
+
<table width="100%" style="border-collapse:collapse;table-layout:fixed;max-width:600px;" class="${visibilityClass}" data-block-type="shape" data-block-props="${shapeBlockProps}">
|
|
247
|
+
<tr>
|
|
248
|
+
<td style="padding:${padding.top || 0}px ${padding.right || 0}px ${padding.bottom || 0}px ${padding.left || 0}px;text-align:${alignment};">
|
|
249
|
+
${outlookContent}
|
|
250
|
+
<!--[if !mso]><!-->
|
|
251
|
+
${nonMsoContent}
|
|
252
|
+
<!--<![endif]-->
|
|
253
|
+
</td>
|
|
254
|
+
</tr>
|
|
255
255
|
</table>`;
|
|
256
256
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/text.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/utils/blocks/text.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,UAqLtE"}
|
|
@@ -101,34 +101,37 @@ function convertTextBlock(blockData, cellWidthInPx) {
|
|
|
101
101
|
return `<v:fill type="gradient" color="${c1}" color2="${c2}" angle="${vmlAngle}" />`;
|
|
102
102
|
})()
|
|
103
103
|
: `<v:fill type="frame" src="${rawBgImageUrl}" color="${fallbackBgColor}" />`;
|
|
104
|
+
const bgPosition = rest.backgroundPosition || 'center center';
|
|
105
|
+
const bgSize = rest.backgroundSize || 'cover';
|
|
106
|
+
const bgRepeat = rest.backgroundRepeat || 'no-repeat';
|
|
104
107
|
const bgCss = isGradient
|
|
105
108
|
? `background:${effectiveGradient};`
|
|
106
|
-
: `background-image:url('${rawBgImageUrl}'); background-position
|
|
107
|
-
const wrappedContent = `
|
|
108
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation"
|
|
109
|
-
style="border-collapse:collapse;width:100%;max-width:${msoWidth}px;" class="${visibilityClass}">
|
|
110
|
-
<tr>
|
|
111
|
-
<td width="100%"${(0, common_1.buildOutlookBgAttr)(fallbackBgColor)} valign="top"
|
|
112
|
-
${!isGradient && rawBgImageUrl ? `background="${rawBgImageUrl}"` : ""}
|
|
113
|
-
style="width:100%;max-width:${msoWidth}px;background-color:${fallbackBgColor};${bgCss}">
|
|
114
|
-
|
|
115
|
-
<!--[if gte mso 9]>
|
|
116
|
-
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
|
117
|
-
fill="true" stroke="false"
|
|
118
|
-
style="width:${msoWidth}px;">
|
|
119
|
-
${vmlFill}
|
|
120
|
-
<v:textbox inset="0,0,0,0">
|
|
121
|
-
<![endif]-->
|
|
122
|
-
|
|
123
|
-
${textContent}
|
|
124
|
-
|
|
125
|
-
<!--[if gte mso 9]>
|
|
126
|
-
</v:textbox>
|
|
127
|
-
</v:rect>
|
|
128
|
-
<![endif]-->
|
|
129
|
-
|
|
130
|
-
</td>
|
|
131
|
-
</tr>
|
|
109
|
+
: `background-image:url('${rawBgImageUrl}'); background-position:${bgPosition}; background-size:${bgSize}; background-repeat:${bgRepeat};`;
|
|
110
|
+
const wrappedContent = `
|
|
111
|
+
<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation"
|
|
112
|
+
style="border-collapse:collapse;width:100%;max-width:${msoWidth}px;" class="${visibilityClass}">
|
|
113
|
+
<tr>
|
|
114
|
+
<td width="100%"${(0, common_1.buildOutlookBgAttr)(fallbackBgColor)} valign="top"
|
|
115
|
+
${!isGradient && rawBgImageUrl ? `background="${rawBgImageUrl}"` : ""}
|
|
116
|
+
style="width:100%;max-width:${msoWidth}px;background-color:${fallbackBgColor};${bgCss}">
|
|
117
|
+
|
|
118
|
+
<!--[if gte mso 9]>
|
|
119
|
+
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
|
120
|
+
fill="true" stroke="false"
|
|
121
|
+
style="width:${msoWidth}px;">
|
|
122
|
+
${vmlFill}
|
|
123
|
+
<v:textbox inset="0,0,0,0">
|
|
124
|
+
<![endif]-->
|
|
125
|
+
|
|
126
|
+
${textContent}
|
|
127
|
+
|
|
128
|
+
<!--[if gte mso 9]>
|
|
129
|
+
</v:textbox>
|
|
130
|
+
</v:rect>
|
|
131
|
+
<![endif]-->
|
|
132
|
+
|
|
133
|
+
</td>
|
|
134
|
+
</tr>
|
|
132
135
|
</table>`;
|
|
133
136
|
return navigateToUrl
|
|
134
137
|
? `<a href="${navigateToUrl}" rel="noreferrer noopener" style="${linkColorStyle}text-decoration:none;cursor:pointer;">${wrappedContent}</a>`
|