email-builder-utils 1.1.50 → 1.1.52
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.js +30 -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 +74 -64
- package/dist/utils/blocks/shape.js +89 -89
- package/dist/utils/blocks/text.js +25 -25
- package/dist/utils/blocks/video.js +56 -56
- package/dist/utils/convertJsonToHtml.js +183 -183
- package/dist/utils/outlookSupport.d.ts.map +1 -1
- package/dist/utils/outlookSupport.js +59 -52
- package/package.json +34 -34
|
@@ -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,18 @@ 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
|
-
<v:textbox inset="0,0,0,0">
|
|
83
|
-
<center style="color:${safeColor};font-family:${safeFF};font-size:${fs}px;font-weight:${fontWeight};mso-line-height-rule:exactly;line-height:${finalHeight}px;text-decoration:none;">${text}</center>
|
|
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
|
+
<v:textbox inset="0,0,0,0">
|
|
83
|
+
<center style="color:${safeColor};font-family:${safeFF};font-size:${fs}px;font-weight:${fontWeight};mso-line-height-rule:exactly;line-height:${finalHeight}px;text-decoration:none;">${text}</center>
|
|
84
|
+
</v:textbox>
|
|
85
|
+
</v:roundrect>
|
|
86
86
|
<![endif]-->`;
|
|
87
87
|
const innerContent = containerAlign === "center"
|
|
88
88
|
? `<center>${msoButton}${nonMsoAnchor}</center>`
|
|
@@ -167,14 +167,14 @@ function convertButtonBlock(blockData) {
|
|
|
167
167
|
hideOnDesktop: Boolean(props.hideOnDesktop),
|
|
168
168
|
hideOnMobile: Boolean(props.hideOnMobile),
|
|
169
169
|
});
|
|
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>
|
|
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>
|
|
179
179
|
`;
|
|
180
180
|
}
|
|
@@ -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,
|
|
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;;;GAwG5B"}
|
|
@@ -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>";
|
|
@@ -157,47 +157,57 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
157
157
|
const visibilityClass = (0, common_1.getVisibilityClass)(childProps);
|
|
158
158
|
if (childVisible) {
|
|
159
159
|
const { html: childHtml, styles } = await convertGridCellBlock(child, rootData, widthPercent, adjustedTableWidth, Boolean(divBorderStyle));
|
|
160
|
-
// bgcolor on the cell <td>
|
|
161
|
-
//
|
|
160
|
+
// bgcolor on the cell <td> for Old Outlook (Word engine).
|
|
161
|
+
// When the cell has no border-radius and the grid has no border, use the grid's
|
|
162
|
+
// backgroundColor as the fallback so the grid background shows through empty cells.
|
|
163
|
+
// Skipped for border-radius cells — bgcolor is rectangular and would bleed through
|
|
164
|
+
// the div's rounded-corner clip in CSS-capable clients (corner squares).
|
|
162
165
|
const cellBgColor = cellStyle.backgroundColor || '';
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
${
|
|
166
|
+
const cellHasBorderRadius = Boolean(cellStyle.borderRadius);
|
|
167
|
+
const canApplyGridBgFallback = !cellHasBorderRadius && !divBorderStyle;
|
|
168
|
+
const effectiveCellBg = cellBgColor || (canApplyGridBgFallback ? msoBgColor : '');
|
|
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}
|
|
171
177
|
</td>`;
|
|
172
178
|
// Spacer td between columns — uses width attribute only (no inline style width) so
|
|
173
179
|
// Outlook mobile (which strips <style>) treats it proportionally, not as a fixed blocker.
|
|
174
180
|
// col-gap-spacer class hides it when columns stack via CSS media query.
|
|
175
181
|
if (columnGap > 0 && c !== lastVisibleCol) {
|
|
176
|
-
|
|
182
|
+
const gapBgAttr = divBorderStyle ? '' : (0, common_1.buildOutlookBgAttr)(msoBgColor);
|
|
183
|
+
html += `<td width="${columnGap}"${gapBgAttr} class="col-gap-spacer" style="font-size:0;line-height:0;padding:0;" aria-hidden="true"></td>`;
|
|
177
184
|
}
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
else {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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;">
|
|
185
194
|
</td>`;
|
|
186
195
|
if (columnGap > 0 && c !== lastVisibleCol) {
|
|
187
|
-
|
|
196
|
+
const gapBgAttr = divBorderStyle ? '' : (0, common_1.buildOutlookBgAttr)(msoBgColor);
|
|
197
|
+
html += `<td width="${columnGap}"${gapBgAttr} class="col-gap-spacer" style="font-size:0;line-height:0;padding:0;" aria-hidden="true"></td>`;
|
|
188
198
|
}
|
|
189
199
|
}
|
|
190
200
|
}
|
|
191
201
|
html += "</tr>";
|
|
192
202
|
}
|
|
193
203
|
// Close both MSO and non-MSO tables
|
|
194
|
-
html += `
|
|
195
|
-
<!--[if mso]>
|
|
196
|
-
</table>
|
|
197
|
-
<![endif]-->
|
|
198
|
-
<!--[if !mso]><!-->
|
|
199
|
-
</table>
|
|
200
|
-
<!--<![endif]-->
|
|
204
|
+
html += `
|
|
205
|
+
<!--[if mso]>
|
|
206
|
+
</table>
|
|
207
|
+
<![endif]-->
|
|
208
|
+
<!--[if !mso]><!-->
|
|
209
|
+
</table>
|
|
210
|
+
<!--<![endif]-->
|
|
201
211
|
`;
|
|
202
212
|
// ── Background image: canonical multi-client approach ────────────────────
|
|
203
213
|
//
|
|
@@ -223,35 +233,35 @@ async function convertGridBlock(blockData, rootData, cellWidthInPx) {
|
|
|
223
233
|
return `<v:fill type="gradient" color="${c1}" color2="${c2}" angle="${vmlAngle}" />`;
|
|
224
234
|
})()
|
|
225
235
|
: `<v:fill type="frame" src="${rawBgImageUrl}" color="${fallbackBgColor}" />`;
|
|
226
|
-
html = `
|
|
227
|
-
<table border="0" cellpadding="0" cellspacing="0" width="100%" role="presentation"
|
|
228
|
-
style="border-collapse:collapse;table-layout:fixed;width:100%;max-width:${msoTableWidth}px;">
|
|
229
|
-
<tr>
|
|
230
|
-
<td width="100%"${(0, common_1.buildOutlookBgAttr)(fallbackBgColor)} valign="top"
|
|
231
|
-
${!isGradient && rawBgImageUrl ? `background="${rawBgImageUrl}"` : ""}
|
|
232
|
-
style="
|
|
233
|
-
width:100%;max-width:${msoTableWidth}px;
|
|
234
|
-
background-color:${fallbackBgColor};
|
|
235
|
-
${isGradient ? `background:${effectiveGradient};` : `background-image:url('${rawBgImageUrl}'); background-position:center center; background-size:cover; background-repeat:no-repeat;`}
|
|
236
|
-
">
|
|
237
|
-
|
|
238
|
-
<!--[if gte mso 9]>
|
|
239
|
-
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
|
240
|
-
fill="true" stroke="false"
|
|
241
|
-
style="width:${msoTableWidth}px;">
|
|
242
|
-
${vmlFill}
|
|
243
|
-
<v:textbox inset="0,0,0,0">
|
|
244
|
-
<![endif]-->
|
|
245
|
-
|
|
246
|
-
${html}
|
|
247
|
-
|
|
248
|
-
<!--[if gte mso 9]>
|
|
249
|
-
</v:textbox>
|
|
250
|
-
</v:rect>
|
|
251
|
-
<![endif]-->
|
|
252
|
-
|
|
253
|
-
</td>
|
|
254
|
-
</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>
|
|
255
265
|
</table>`;
|
|
256
266
|
}
|
|
257
267
|
// Wrap the entire grid (including any bg-image outer table) in a div when the block
|
|
@@ -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
|
}
|
|
@@ -104,31 +104,31 @@ function convertTextBlock(blockData, cellWidthInPx) {
|
|
|
104
104
|
const bgCss = isGradient
|
|
105
105
|
? `background:${effectiveGradient};`
|
|
106
106
|
: `background-image:url('${rawBgImageUrl}'); background-position:center center; background-size:cover; background-repeat:no-repeat;`;
|
|
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>
|
|
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>
|
|
132
132
|
</table>`;
|
|
133
133
|
return navigateToUrl
|
|
134
134
|
? `<a href="${navigateToUrl}" rel="noreferrer noopener" style="${linkColorStyle}text-decoration:none;cursor:pointer;">${wrappedContent}</a>`
|