@templatical/renderer 0.44.3 → 0.46.0
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/assets/social/circle/behance.png +0 -0
- package/assets/social/circle/discord.png +0 -0
- package/assets/social/circle/dribbble.png +0 -0
- package/assets/social/circle/email.png +0 -0
- package/assets/social/circle/facebook.png +0 -0
- package/assets/social/circle/github.png +0 -0
- package/assets/social/circle/instagram.png +0 -0
- package/assets/social/circle/linkedin.png +0 -0
- package/assets/social/circle/pinterest.png +0 -0
- package/assets/social/circle/reddit.png +0 -0
- package/assets/social/circle/snapchat.png +0 -0
- package/assets/social/circle/telegram.png +0 -0
- package/assets/social/circle/tiktok.png +0 -0
- package/assets/social/circle/twitter.png +0 -0
- package/assets/social/circle/website.png +0 -0
- package/assets/social/circle/whatsapp.png +0 -0
- package/assets/social/circle/youtube.png +0 -0
- package/assets/social/circle-dark/behance.png +0 -0
- package/assets/social/circle-dark/discord.png +0 -0
- package/assets/social/circle-dark/dribbble.png +0 -0
- package/assets/social/circle-dark/email.png +0 -0
- package/assets/social/circle-dark/facebook.png +0 -0
- package/assets/social/circle-dark/github.png +0 -0
- package/assets/social/circle-dark/instagram.png +0 -0
- package/assets/social/circle-dark/linkedin.png +0 -0
- package/assets/social/circle-dark/pinterest.png +0 -0
- package/assets/social/circle-dark/reddit.png +0 -0
- package/assets/social/circle-dark/snapchat.png +0 -0
- package/assets/social/circle-dark/telegram.png +0 -0
- package/assets/social/circle-dark/tiktok.png +0 -0
- package/assets/social/circle-dark/twitter.png +0 -0
- package/assets/social/circle-dark/website.png +0 -0
- package/assets/social/circle-dark/whatsapp.png +0 -0
- package/assets/social/circle-dark/youtube.png +0 -0
- package/assets/social/circle-light/behance.png +0 -0
- package/assets/social/circle-light/discord.png +0 -0
- package/assets/social/circle-light/dribbble.png +0 -0
- package/assets/social/circle-light/email.png +0 -0
- package/assets/social/circle-light/facebook.png +0 -0
- package/assets/social/circle-light/github.png +0 -0
- package/assets/social/circle-light/instagram.png +0 -0
- package/assets/social/circle-light/linkedin.png +0 -0
- package/assets/social/circle-light/pinterest.png +0 -0
- package/assets/social/circle-light/reddit.png +0 -0
- package/assets/social/circle-light/snapchat.png +0 -0
- package/assets/social/circle-light/telegram.png +0 -0
- package/assets/social/circle-light/tiktok.png +0 -0
- package/assets/social/circle-light/twitter.png +0 -0
- package/assets/social/circle-light/website.png +0 -0
- package/assets/social/circle-light/whatsapp.png +0 -0
- package/assets/social/circle-light/youtube.png +0 -0
- package/assets/social/outlined/behance.png +0 -0
- package/assets/social/outlined/discord.png +0 -0
- package/assets/social/outlined/dribbble.png +0 -0
- package/assets/social/outlined/email.png +0 -0
- package/assets/social/outlined/facebook.png +0 -0
- package/assets/social/outlined/github.png +0 -0
- package/assets/social/outlined/instagram.png +0 -0
- package/assets/social/outlined/linkedin.png +0 -0
- package/assets/social/outlined/pinterest.png +0 -0
- package/assets/social/outlined/reddit.png +0 -0
- package/assets/social/outlined/snapchat.png +0 -0
- package/assets/social/outlined/telegram.png +0 -0
- package/assets/social/outlined/tiktok.png +0 -0
- package/assets/social/outlined/twitter.png +0 -0
- package/assets/social/outlined/website.png +0 -0
- package/assets/social/outlined/whatsapp.png +0 -0
- package/assets/social/outlined/youtube.png +0 -0
- package/assets/social/outlined-dark/behance.png +0 -0
- package/assets/social/outlined-dark/discord.png +0 -0
- package/assets/social/outlined-dark/dribbble.png +0 -0
- package/assets/social/outlined-dark/email.png +0 -0
- package/assets/social/outlined-dark/facebook.png +0 -0
- package/assets/social/outlined-dark/github.png +0 -0
- package/assets/social/outlined-dark/instagram.png +0 -0
- package/assets/social/outlined-dark/linkedin.png +0 -0
- package/assets/social/outlined-dark/pinterest.png +0 -0
- package/assets/social/outlined-dark/reddit.png +0 -0
- package/assets/social/outlined-dark/snapchat.png +0 -0
- package/assets/social/outlined-dark/telegram.png +0 -0
- package/assets/social/outlined-dark/tiktok.png +0 -0
- package/assets/social/outlined-dark/twitter.png +0 -0
- package/assets/social/outlined-dark/website.png +0 -0
- package/assets/social/outlined-dark/whatsapp.png +0 -0
- package/assets/social/outlined-dark/youtube.png +0 -0
- package/assets/social/outlined-light/behance.png +0 -0
- package/assets/social/outlined-light/discord.png +0 -0
- package/assets/social/outlined-light/dribbble.png +0 -0
- package/assets/social/outlined-light/email.png +0 -0
- package/assets/social/outlined-light/facebook.png +0 -0
- package/assets/social/outlined-light/github.png +0 -0
- package/assets/social/outlined-light/instagram.png +0 -0
- package/assets/social/outlined-light/linkedin.png +0 -0
- package/assets/social/outlined-light/pinterest.png +0 -0
- package/assets/social/outlined-light/reddit.png +0 -0
- package/assets/social/outlined-light/snapchat.png +0 -0
- package/assets/social/outlined-light/telegram.png +0 -0
- package/assets/social/outlined-light/tiktok.png +0 -0
- package/assets/social/outlined-light/twitter.png +0 -0
- package/assets/social/outlined-light/website.png +0 -0
- package/assets/social/outlined-light/whatsapp.png +0 -0
- package/assets/social/outlined-light/youtube.png +0 -0
- package/assets/social/plain/behance.png +0 -0
- package/assets/social/plain/discord.png +0 -0
- package/assets/social/plain/dribbble.png +0 -0
- package/assets/social/plain/email.png +0 -0
- package/assets/social/plain/facebook.png +0 -0
- package/assets/social/plain/github.png +0 -0
- package/assets/social/plain/instagram.png +0 -0
- package/assets/social/plain/linkedin.png +0 -0
- package/assets/social/plain/pinterest.png +0 -0
- package/assets/social/plain/reddit.png +0 -0
- package/assets/social/plain/snapchat.png +0 -0
- package/assets/social/plain/telegram.png +0 -0
- package/assets/social/plain/tiktok.png +0 -0
- package/assets/social/plain/twitter.png +0 -0
- package/assets/social/plain/website.png +0 -0
- package/assets/social/plain/whatsapp.png +0 -0
- package/assets/social/plain/youtube.png +0 -0
- package/assets/social/plain-dark/behance.png +0 -0
- package/assets/social/plain-dark/discord.png +0 -0
- package/assets/social/plain-dark/dribbble.png +0 -0
- package/assets/social/plain-dark/email.png +0 -0
- package/assets/social/plain-dark/facebook.png +0 -0
- package/assets/social/plain-dark/github.png +0 -0
- package/assets/social/plain-dark/instagram.png +0 -0
- package/assets/social/plain-dark/linkedin.png +0 -0
- package/assets/social/plain-dark/pinterest.png +0 -0
- package/assets/social/plain-dark/reddit.png +0 -0
- package/assets/social/plain-dark/snapchat.png +0 -0
- package/assets/social/plain-dark/telegram.png +0 -0
- package/assets/social/plain-dark/tiktok.png +0 -0
- package/assets/social/plain-dark/twitter.png +0 -0
- package/assets/social/plain-dark/website.png +0 -0
- package/assets/social/plain-dark/whatsapp.png +0 -0
- package/assets/social/plain-dark/youtube.png +0 -0
- package/assets/social/plain-light/behance.png +0 -0
- package/assets/social/plain-light/discord.png +0 -0
- package/assets/social/plain-light/dribbble.png +0 -0
- package/assets/social/plain-light/email.png +0 -0
- package/assets/social/plain-light/facebook.png +0 -0
- package/assets/social/plain-light/github.png +0 -0
- package/assets/social/plain-light/instagram.png +0 -0
- package/assets/social/plain-light/linkedin.png +0 -0
- package/assets/social/plain-light/pinterest.png +0 -0
- package/assets/social/plain-light/reddit.png +0 -0
- package/assets/social/plain-light/snapchat.png +0 -0
- package/assets/social/plain-light/telegram.png +0 -0
- package/assets/social/plain-light/tiktok.png +0 -0
- package/assets/social/plain-light/twitter.png +0 -0
- package/assets/social/plain-light/website.png +0 -0
- package/assets/social/plain-light/whatsapp.png +0 -0
- package/assets/social/plain-light/youtube.png +0 -0
- package/assets/social/rounded/behance.png +0 -0
- package/assets/social/rounded/discord.png +0 -0
- package/assets/social/rounded/dribbble.png +0 -0
- package/assets/social/rounded/email.png +0 -0
- package/assets/social/rounded/facebook.png +0 -0
- package/assets/social/rounded/github.png +0 -0
- package/assets/social/rounded/instagram.png +0 -0
- package/assets/social/rounded/linkedin.png +0 -0
- package/assets/social/rounded/pinterest.png +0 -0
- package/assets/social/rounded/reddit.png +0 -0
- package/assets/social/rounded/snapchat.png +0 -0
- package/assets/social/rounded/telegram.png +0 -0
- package/assets/social/rounded/tiktok.png +0 -0
- package/assets/social/rounded/twitter.png +0 -0
- package/assets/social/rounded/website.png +0 -0
- package/assets/social/rounded/whatsapp.png +0 -0
- package/assets/social/rounded/youtube.png +0 -0
- package/assets/social/rounded-dark/behance.png +0 -0
- package/assets/social/rounded-dark/discord.png +0 -0
- package/assets/social/rounded-dark/dribbble.png +0 -0
- package/assets/social/rounded-dark/email.png +0 -0
- package/assets/social/rounded-dark/facebook.png +0 -0
- package/assets/social/rounded-dark/github.png +0 -0
- package/assets/social/rounded-dark/instagram.png +0 -0
- package/assets/social/rounded-dark/linkedin.png +0 -0
- package/assets/social/rounded-dark/pinterest.png +0 -0
- package/assets/social/rounded-dark/reddit.png +0 -0
- package/assets/social/rounded-dark/snapchat.png +0 -0
- package/assets/social/rounded-dark/telegram.png +0 -0
- package/assets/social/rounded-dark/tiktok.png +0 -0
- package/assets/social/rounded-dark/twitter.png +0 -0
- package/assets/social/rounded-dark/website.png +0 -0
- package/assets/social/rounded-dark/whatsapp.png +0 -0
- package/assets/social/rounded-dark/youtube.png +0 -0
- package/assets/social/rounded-light/behance.png +0 -0
- package/assets/social/rounded-light/discord.png +0 -0
- package/assets/social/rounded-light/dribbble.png +0 -0
- package/assets/social/rounded-light/email.png +0 -0
- package/assets/social/rounded-light/facebook.png +0 -0
- package/assets/social/rounded-light/github.png +0 -0
- package/assets/social/rounded-light/instagram.png +0 -0
- package/assets/social/rounded-light/linkedin.png +0 -0
- package/assets/social/rounded-light/pinterest.png +0 -0
- package/assets/social/rounded-light/reddit.png +0 -0
- package/assets/social/rounded-light/snapchat.png +0 -0
- package/assets/social/rounded-light/telegram.png +0 -0
- package/assets/social/rounded-light/tiktok.png +0 -0
- package/assets/social/rounded-light/twitter.png +0 -0
- package/assets/social/rounded-light/website.png +0 -0
- package/assets/social/rounded-light/whatsapp.png +0 -0
- package/assets/social/rounded-light/youtube.png +0 -0
- package/assets/social/solid/behance.png +0 -0
- package/assets/social/solid/discord.png +0 -0
- package/assets/social/solid/dribbble.png +0 -0
- package/assets/social/solid/email.png +0 -0
- package/assets/social/solid/facebook.png +0 -0
- package/assets/social/solid/github.png +0 -0
- package/assets/social/solid/instagram.png +0 -0
- package/assets/social/solid/linkedin.png +0 -0
- package/assets/social/solid/pinterest.png +0 -0
- package/assets/social/solid/reddit.png +0 -0
- package/assets/social/solid/snapchat.png +0 -0
- package/assets/social/solid/telegram.png +0 -0
- package/assets/social/solid/tiktok.png +0 -0
- package/assets/social/solid/twitter.png +0 -0
- package/assets/social/solid/website.png +0 -0
- package/assets/social/solid/whatsapp.png +0 -0
- package/assets/social/solid/youtube.png +0 -0
- package/assets/social/solid-dark/behance.png +0 -0
- package/assets/social/solid-dark/discord.png +0 -0
- package/assets/social/solid-dark/dribbble.png +0 -0
- package/assets/social/solid-dark/email.png +0 -0
- package/assets/social/solid-dark/facebook.png +0 -0
- package/assets/social/solid-dark/github.png +0 -0
- package/assets/social/solid-dark/instagram.png +0 -0
- package/assets/social/solid-dark/linkedin.png +0 -0
- package/assets/social/solid-dark/pinterest.png +0 -0
- package/assets/social/solid-dark/reddit.png +0 -0
- package/assets/social/solid-dark/snapchat.png +0 -0
- package/assets/social/solid-dark/telegram.png +0 -0
- package/assets/social/solid-dark/tiktok.png +0 -0
- package/assets/social/solid-dark/twitter.png +0 -0
- package/assets/social/solid-dark/website.png +0 -0
- package/assets/social/solid-dark/whatsapp.png +0 -0
- package/assets/social/solid-dark/youtube.png +0 -0
- package/assets/social/solid-light/behance.png +0 -0
- package/assets/social/solid-light/discord.png +0 -0
- package/assets/social/solid-light/dribbble.png +0 -0
- package/assets/social/solid-light/email.png +0 -0
- package/assets/social/solid-light/facebook.png +0 -0
- package/assets/social/solid-light/github.png +0 -0
- package/assets/social/solid-light/instagram.png +0 -0
- package/assets/social/solid-light/linkedin.png +0 -0
- package/assets/social/solid-light/pinterest.png +0 -0
- package/assets/social/solid-light/reddit.png +0 -0
- package/assets/social/solid-light/snapchat.png +0 -0
- package/assets/social/solid-light/telegram.png +0 -0
- package/assets/social/solid-light/tiktok.png +0 -0
- package/assets/social/solid-light/twitter.png +0 -0
- package/assets/social/solid-light/website.png +0 -0
- package/assets/social/solid-light/whatsapp.png +0 -0
- package/assets/social/solid-light/youtube.png +0 -0
- package/assets/social/square/behance.png +0 -0
- package/assets/social/square/discord.png +0 -0
- package/assets/social/square/dribbble.png +0 -0
- package/assets/social/square/email.png +0 -0
- package/assets/social/square/facebook.png +0 -0
- package/assets/social/square/github.png +0 -0
- package/assets/social/square/instagram.png +0 -0
- package/assets/social/square/linkedin.png +0 -0
- package/assets/social/square/pinterest.png +0 -0
- package/assets/social/square/reddit.png +0 -0
- package/assets/social/square/snapchat.png +0 -0
- package/assets/social/square/telegram.png +0 -0
- package/assets/social/square/tiktok.png +0 -0
- package/assets/social/square/twitter.png +0 -0
- package/assets/social/square/website.png +0 -0
- package/assets/social/square/whatsapp.png +0 -0
- package/assets/social/square/youtube.png +0 -0
- package/assets/social/square-dark/behance.png +0 -0
- package/assets/social/square-dark/discord.png +0 -0
- package/assets/social/square-dark/dribbble.png +0 -0
- package/assets/social/square-dark/email.png +0 -0
- package/assets/social/square-dark/facebook.png +0 -0
- package/assets/social/square-dark/github.png +0 -0
- package/assets/social/square-dark/instagram.png +0 -0
- package/assets/social/square-dark/linkedin.png +0 -0
- package/assets/social/square-dark/pinterest.png +0 -0
- package/assets/social/square-dark/reddit.png +0 -0
- package/assets/social/square-dark/snapchat.png +0 -0
- package/assets/social/square-dark/telegram.png +0 -0
- package/assets/social/square-dark/tiktok.png +0 -0
- package/assets/social/square-dark/twitter.png +0 -0
- package/assets/social/square-dark/website.png +0 -0
- package/assets/social/square-dark/whatsapp.png +0 -0
- package/assets/social/square-dark/youtube.png +0 -0
- package/assets/social/square-light/behance.png +0 -0
- package/assets/social/square-light/discord.png +0 -0
- package/assets/social/square-light/dribbble.png +0 -0
- package/assets/social/square-light/email.png +0 -0
- package/assets/social/square-light/facebook.png +0 -0
- package/assets/social/square-light/github.png +0 -0
- package/assets/social/square-light/instagram.png +0 -0
- package/assets/social/square-light/linkedin.png +0 -0
- package/assets/social/square-light/pinterest.png +0 -0
- package/assets/social/square-light/reddit.png +0 -0
- package/assets/social/square-light/snapchat.png +0 -0
- package/assets/social/square-light/telegram.png +0 -0
- package/assets/social/square-light/tiktok.png +0 -0
- package/assets/social/square-light/twitter.png +0 -0
- package/assets/social/square-light/website.png +0 -0
- package/assets/social/square-light/whatsapp.png +0 -0
- package/assets/social/square-light/youtube.png +0 -0
- package/dist/index.d.ts +17 -3
- package/dist/index.js +64 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/index.d.ts
CHANGED
|
@@ -84,9 +84,13 @@ export declare class RenderContext {
|
|
|
84
84
|
*/
|
|
85
85
|
withContainerWidth(width: number): RenderContext;
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
87
|
+
* The stack to emit for a block's or the template's `fontFamily`. A stack is
|
|
88
|
+
* the author's own fallback chain and is emitted as written, as is anything
|
|
89
|
+
* that doesn't parse as a font. A lone family gets a fallback: a custom
|
|
90
|
+
* font's own `fallback` (or `defaultFallbackFont`), a built-in's fixed stack,
|
|
91
|
+
* or, for any other family, `defaultFallbackFont`, so a client without the
|
|
92
|
+
* face falls back to it rather than to its own default (Times New Roman in
|
|
93
|
+
* Outlook on Windows). A generic family needs nothing appended.
|
|
90
94
|
*/
|
|
91
95
|
resolveFontFamily(fontFamily: string): string;
|
|
92
96
|
}
|
|
@@ -170,6 +174,16 @@ export declare function richTextGapClass(gap: number): string;
|
|
|
170
174
|
*/
|
|
171
175
|
export declare function resolveParagraphGap(spacing: number | undefined): number;
|
|
172
176
|
//#endregion
|
|
177
|
+
//#region src/renderers/button.d.ts
|
|
178
|
+
/**
|
|
179
|
+
* Marks the `mj-button` of a full-width button. MJML gives the button's `<a>`
|
|
180
|
+
* a width only for a px `width`; for `100%` it widens the `<table>` and leaves
|
|
181
|
+
* the `<a>` at `display:inline-block`, so only the label is clickable.
|
|
182
|
+
* `renderToMjml` scopes the head rule that makes the `<a>` fill the button to
|
|
183
|
+
* this class.
|
|
184
|
+
*/
|
|
185
|
+
export declare const BUTTON_FULL_WIDTH_CSS_CLASS = "tpl-button-full";
|
|
186
|
+
//#endregion
|
|
173
187
|
//#region src/columns.d.ts
|
|
174
188
|
/**
|
|
175
189
|
* Get width percentages for each column in a layout.
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
import { HEADING_LEVEL_FONT_SIZE, RICH_TEXT_SPACING, applyLayout, assertNoSlotInContent, assertNoWrapperInContent, findOpenTagEnd, getTagAttrValue, isButton, isCustomBlock, isDivider, isHtml, isImage, isMenu, isParagraph, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, isWrapper, resolveContentDirection, toBorderDeclarations, toBorderRadiusCss } from "@templatical/types";
|
|
1
|
+
import { BUILT_IN_FONT_STACKS, HEADING_LEVEL_FONT_SIZE, RICH_TEXT_SPACING, applyLayout, assertNoSlotInContent, assertNoWrapperInContent, findOpenTagEnd, getTagAttrValue, isButton, isCustomBlock, isDivider, isGenericFontFamily, isHtml, isImage, isMenu, isParagraph, isSection, isSocialIcons, isSpacer, isTable, isTitle, isVideo, isWrapper, parseFontFamilies, quoteFontFamily, resolveContentDirection, socialIconAssetDir, toBorderDeclarations, toBorderRadiusCss } from "@templatical/types";
|
|
2
2
|
//#endregion
|
|
3
3
|
//#region src/render-context.ts
|
|
4
|
-
const DEFAULT_SOCIAL_ICONS_BASE_URL = `https://cdn.jsdelivr.net/npm/@templatical/renderer@0.
|
|
5
|
-
const BUILT_IN_FONT_FALLBACKS = {
|
|
6
|
-
arial: "Arial, sans-serif",
|
|
7
|
-
helvetica: "Helvetica, sans-serif",
|
|
8
|
-
georgia: "Georgia, serif",
|
|
9
|
-
"times new roman": "'Times New Roman', serif",
|
|
10
|
-
verdana: "Verdana, sans-serif",
|
|
11
|
-
"trebuchet ms": "'Trebuchet MS', sans-serif",
|
|
12
|
-
"courier new": "'Courier New', monospace",
|
|
13
|
-
tahoma: "Tahoma, sans-serif"
|
|
14
|
-
};
|
|
4
|
+
const DEFAULT_SOCIAL_ICONS_BASE_URL = `https://cdn.jsdelivr.net/npm/@templatical/renderer@0.46.0/assets/social`;
|
|
15
5
|
/**
|
|
16
6
|
* Immutable context passed through the block rendering chain.
|
|
17
7
|
*/
|
|
@@ -42,18 +32,27 @@ var RenderContext = class RenderContext {
|
|
|
42
32
|
return new RenderContext(width, this.customFonts, this.defaultFallbackFont, this.allowHtmlBlocks, this.customBlockHtml, this.socialIconsBaseUrl, this.blockRenderers, this.contentDirection);
|
|
43
33
|
}
|
|
44
34
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
35
|
+
* The stack to emit for a block's or the template's `fontFamily`. A stack is
|
|
36
|
+
* the author's own fallback chain and is emitted as written, as is anything
|
|
37
|
+
* that doesn't parse as a font. A lone family gets a fallback: a custom
|
|
38
|
+
* font's own `fallback` (or `defaultFallbackFont`), a built-in's fixed stack,
|
|
39
|
+
* or, for any other family, `defaultFallbackFont`, so a client without the
|
|
40
|
+
* face falls back to it rather than to its own default (Times New Roman in
|
|
41
|
+
* Outlook on Windows). A generic family needs nothing appended.
|
|
48
42
|
*/
|
|
49
43
|
resolveFontFamily(fontFamily) {
|
|
50
|
-
|
|
44
|
+
const families = parseFontFamilies(fontFamily);
|
|
45
|
+
if (families.length !== 1) return fontFamily;
|
|
46
|
+
const [family] = families;
|
|
47
|
+
const key = family.name.toLowerCase();
|
|
48
|
+
for (const customFont of this.customFonts) if (customFont.name.toLowerCase() === key) {
|
|
51
49
|
const fallback = customFont.fallback ?? this.defaultFallbackFont;
|
|
52
50
|
return `'${customFont.name}', ${fallback}`;
|
|
53
51
|
}
|
|
54
|
-
const builtIn =
|
|
52
|
+
const builtIn = BUILT_IN_FONT_STACKS[key];
|
|
55
53
|
if (builtIn) return builtIn;
|
|
56
|
-
return fontFamily;
|
|
54
|
+
if (isGenericFontFamily(family)) return fontFamily;
|
|
55
|
+
return `${quoteFontFamily(family.name)}, ${this.defaultFallbackFont}`;
|
|
57
56
|
}
|
|
58
57
|
};
|
|
59
58
|
//#endregion
|
|
@@ -177,6 +176,18 @@ function escapeCssValue(text) {
|
|
|
177
176
|
if (text === "") return "";
|
|
178
177
|
return escapeAttr(text).replace(/[;{}\r\n]/g, "");
|
|
179
178
|
}
|
|
179
|
+
const FONT_FAMILY_ENTITY_REGEX = /[&<>"]/g;
|
|
180
|
+
/**
|
|
181
|
+
* Escape a font stack for a double-quoted `font-family="…"` MJML attribute.
|
|
182
|
+
* A `"`-quoted family (`"Helvetica Neue", Arial`) must not end the attribute,
|
|
183
|
+
* or the compiler reads it as empty. Unlike `escapeAttr`, single quotes are
|
|
184
|
+
* left alone: they can't end a double-quoted attribute, and they're how the
|
|
185
|
+
* renderer quotes families itself (`'Times New Roman', serif`), so every
|
|
186
|
+
* stack without `&<>"` is emitted byte-for-byte.
|
|
187
|
+
*/
|
|
188
|
+
function escapeFontFamily(text) {
|
|
189
|
+
return text.replace(FONT_FAMILY_ENTITY_REGEX, (char) => HTML_ENTITIES[char] ?? char);
|
|
190
|
+
}
|
|
180
191
|
/**
|
|
181
192
|
* Replace merge tag span elements with their data attribute values.
|
|
182
193
|
* Converts `<span data-merge-tag="{{name}}">Label</span>` to `{{name}}`.
|
|
@@ -442,7 +453,7 @@ function unwrapParagraph(html) {
|
|
|
442
453
|
}
|
|
443
454
|
function renderFontFamilyAttr$3(fontFamily, context) {
|
|
444
455
|
if (!fontFamily) return "";
|
|
445
|
-
return ` font-family="${context.resolveFontFamily(fontFamily)}"`;
|
|
456
|
+
return ` font-family="${escapeFontFamily(context.resolveFontFamily(fontFamily))}"`;
|
|
446
457
|
}
|
|
447
458
|
//#endregion
|
|
448
459
|
//#region src/renderers/paragraph.ts
|
|
@@ -495,6 +506,14 @@ function renderImage(block, context) {
|
|
|
495
506
|
//#endregion
|
|
496
507
|
//#region src/renderers/button.ts
|
|
497
508
|
/**
|
|
509
|
+
* Marks the `mj-button` of a full-width button. MJML gives the button's `<a>`
|
|
510
|
+
* a width only for a px `width`; for `100%` it widens the `<table>` and leaves
|
|
511
|
+
* the `<a>` at `display:inline-block`, so only the label is clickable.
|
|
512
|
+
* `renderToMjml` scopes the head rule that makes the `<a>` fill the button to
|
|
513
|
+
* this class.
|
|
514
|
+
*/
|
|
515
|
+
const BUTTON_FULL_WIDTH_CSS_CLASS = "tpl-button-full";
|
|
516
|
+
/**
|
|
498
517
|
* Render a button block to MJML markup.
|
|
499
518
|
*/
|
|
500
519
|
function renderButton(block, context) {
|
|
@@ -512,7 +531,7 @@ function renderButton(block, context) {
|
|
|
512
531
|
const targetAttr = block.openInNewTab ? " target=\"_blank\" rel=\"noopener\"" : "";
|
|
513
532
|
const fontFamilyAttr = renderFontFamilyAttr$2(block.fontFamily, context);
|
|
514
533
|
const widthAttr = renderWidthAttr(block.width);
|
|
515
|
-
const
|
|
534
|
+
const cssClassAttr = getCssClassAttr(block, block.width === "full" ? [BUTTON_FULL_WIDTH_CSS_CLASS] : []);
|
|
516
535
|
return `<mj-button${hrefAttr}${targetAttr}
|
|
517
536
|
background-color="${backgroundColor}"
|
|
518
537
|
color="${textColor}"
|
|
@@ -521,7 +540,7 @@ function renderButton(block, context) {
|
|
|
521
540
|
border-radius="${borderRadius}"${borderAttr(block.border)}
|
|
522
541
|
inner-padding="${buttonPadding}"
|
|
523
542
|
align="${block.align ?? "center"}"
|
|
524
|
-
padding="${padding}"${bgColor}${fontFamilyAttr}${widthAttr}${
|
|
543
|
+
padding="${padding}"${bgColor}${fontFamilyAttr}${widthAttr}${cssClassAttr}
|
|
525
544
|
>${text}</mj-button>`;
|
|
526
545
|
}
|
|
527
546
|
/**
|
|
@@ -534,7 +553,7 @@ function buttonBackgroundAttr(color) {
|
|
|
534
553
|
}
|
|
535
554
|
function renderFontFamilyAttr$2(fontFamily, context) {
|
|
536
555
|
if (!fontFamily) return "";
|
|
537
|
-
return ` font-family="${context.resolveFontFamily(fontFamily)}"`;
|
|
556
|
+
return ` font-family="${escapeFontFamily(context.resolveFontFamily(fontFamily))}"`;
|
|
538
557
|
}
|
|
539
558
|
/**
|
|
540
559
|
* The button has always emitted its radius, `0px` included, so a plain number
|
|
@@ -603,13 +622,14 @@ ${content}
|
|
|
603
622
|
/**
|
|
604
623
|
* Render a social icons block to MJML markup.
|
|
605
624
|
*
|
|
606
|
-
* Icons are emitted as `<img src="…/{
|
|
625
|
+
* Icons are emitted as `<img src="…/{dir}/{platform}.png">` rather than
|
|
607
626
|
* inline SVG or base64 data URIs. Outlook desktop (Word rendering engine)
|
|
608
627
|
* does not support SVG and rejects base64 in `<img src>`, so hosted PNGs are
|
|
609
628
|
* the only format that renders across every mainstream client. The base URL
|
|
610
629
|
* is read from `context.socialIconsBaseUrl` (configurable via
|
|
611
630
|
* `RenderOptions.socialIconsBaseUrl`; default is the version-pinned jsDelivr
|
|
612
|
-
* mirror of this package).
|
|
631
|
+
* mirror of this package). `{dir}` is the style, plus `-{tone}` for a
|
|
632
|
+
* one-color tone (`socialIconAssetDir`).
|
|
613
633
|
*/
|
|
614
634
|
function renderSocialIcons(block, context) {
|
|
615
635
|
if (isHiddenOnAll(block)) return "";
|
|
@@ -621,6 +641,7 @@ function renderSocialIcons(block, context) {
|
|
|
621
641
|
const align = block.align;
|
|
622
642
|
const iconSize = block.iconSize;
|
|
623
643
|
const iconStyle = block.iconStyle;
|
|
644
|
+
const assetDir = socialIconAssetDir(iconStyle, block.iconTone);
|
|
624
645
|
const spacing = block.spacing;
|
|
625
646
|
let iconSizePx;
|
|
626
647
|
switch (iconSize) {
|
|
@@ -655,7 +676,7 @@ function renderSocialIcons(block, context) {
|
|
|
655
676
|
${icons.map((icon, index) => {
|
|
656
677
|
const platform = icon.platform;
|
|
657
678
|
const url = escapeAttr(icon.url);
|
|
658
|
-
const iconSrc = `${context.socialIconsBaseUrl}/${
|
|
679
|
+
const iconSrc = `${context.socialIconsBaseUrl}/${assetDir}/${platform}.png`;
|
|
659
680
|
const rightPad = index === iconCount - 1 ? 0 : spacing;
|
|
660
681
|
return `<mj-social-element src="${iconSrc}" href="${url}" icon-size="${iconSizePx}px" padding="0 ${rightPad}px 0 0" border-radius="${borderRadius}" background-color="transparent"></mj-social-element>`;
|
|
661
682
|
}).join("\n")}
|
|
@@ -709,7 +730,7 @@ function renderMenuItem(item, linkColor) {
|
|
|
709
730
|
}
|
|
710
731
|
function renderFontFamilyAttr$1(fontFamily, context) {
|
|
711
732
|
if (!fontFamily) return "";
|
|
712
|
-
return ` font-family="${context.resolveFontFamily(fontFamily)}"`;
|
|
733
|
+
return ` font-family="${escapeFontFamily(context.resolveFontFamily(fontFamily))}"`;
|
|
713
734
|
}
|
|
714
735
|
//#endregion
|
|
715
736
|
//#region src/renderers/table.ts
|
|
@@ -762,7 +783,7 @@ function renderCell(cell, block, isHeader, borderColor, borderWidth) {
|
|
|
762
783
|
}
|
|
763
784
|
function renderFontFamilyAttr(fontFamily, context) {
|
|
764
785
|
if (!fontFamily) return "";
|
|
765
|
-
return ` font-family="${context.resolveFontFamily(fontFamily)}"`;
|
|
786
|
+
return ` font-family="${escapeFontFamily(context.resolveFontFamily(fontFamily))}"`;
|
|
766
787
|
}
|
|
767
788
|
//#endregion
|
|
768
789
|
//#region src/renderers/custom.ts
|
|
@@ -960,6 +981,19 @@ function renderBlock(block, context) {
|
|
|
960
981
|
//#endregion
|
|
961
982
|
//#region src/index.ts
|
|
962
983
|
/**
|
|
984
|
+
* Makes a full-width button's whole fill clickable. MJML sizes a button's `<a>`
|
|
985
|
+
* only for a px width, so without this rule the link of a `100%` button stays
|
|
986
|
+
* the size of its label.
|
|
987
|
+
*
|
|
988
|
+
* It sits in the inline `<mj-style>` so `mjml`'s juice pass writes it onto the
|
|
989
|
+
* `<a>`; MRML's default build emits that block as a plain `<style>` instead.
|
|
990
|
+
* `!important` lets it beat MJML's inline `display:inline-block` either way.
|
|
991
|
+
* Every template carries it, so nothing has to walk the tree for full-width
|
|
992
|
+
* buttons: juice drops a rule that matches nothing, so with `mjml` it costs
|
|
993
|
+
* nothing in the compiled HTML.
|
|
994
|
+
*/
|
|
995
|
+
const BUTTON_FULL_WIDTH_RULE = `.${BUTTON_FULL_WIDTH_CSS_CLASS} a { display: block !important; }`;
|
|
996
|
+
/**
|
|
963
997
|
* Render template content to an MJML string.
|
|
964
998
|
*
|
|
965
999
|
* The function is async because resolving custom blocks may require
|
|
@@ -990,7 +1024,7 @@ async function renderToMjml(content, options) {
|
|
|
990
1024
|
return `<mjml lang="${escapeAttr(toRender.settings.locale)}" dir="${escapeAttr(contentDirection)}">
|
|
991
1025
|
<mj-head>${previewTag}
|
|
992
1026
|
<mj-attributes>
|
|
993
|
-
<mj-all font-family="${fontFamily}" />
|
|
1027
|
+
<mj-all font-family="${escapeFontFamily(fontFamily)}" />
|
|
994
1028
|
<mj-text font-size="14px"${textColorAttr} />
|
|
995
1029
|
<mj-section padding="0" />
|
|
996
1030
|
<mj-column padding="0" />
|
|
@@ -998,6 +1032,7 @@ async function renderToMjml(content, options) {
|
|
|
998
1032
|
</mj-attributes>${fontDeclarations}
|
|
999
1033
|
<mj-style inline="inline">
|
|
1000
1034
|
${richTextStylesheet(collectParagraphGaps(blocks), contentDirection)}
|
|
1035
|
+
${BUTTON_FULL_WIDTH_RULE}
|
|
1001
1036
|
</mj-style>
|
|
1002
1037
|
<mj-style>
|
|
1003
1038
|
a { color: ${linkColor}; text-decoration: ${linkDecoration}; }
|
|
@@ -1139,6 +1174,6 @@ function renderCustomBlockStylesheets(stylesheets) {
|
|
|
1139
1174
|
return stylesheets.map((css) => `\n <mj-style>\n${css}\n </mj-style>`).join("");
|
|
1140
1175
|
}
|
|
1141
1176
|
//#endregion
|
|
1142
|
-
export { DEFAULT_SOCIAL_ICONS_BASE_URL, RICH_TEXT_CSS_CLASS, RenderContext, UNRENDERABLE_MARKER_PREFIX, convertMergeTagsToValues, escapeAttr, escapeHtml, getCssClassAttr, getCssClasses, getWidthPercentages, getWidthPixels, isHiddenOnAll, renderBlock, renderToMjml, renderUnrenderableBlock, resolveParagraphGap, richTextGapClass, toPaddingString };
|
|
1177
|
+
export { BUTTON_FULL_WIDTH_CSS_CLASS, DEFAULT_SOCIAL_ICONS_BASE_URL, RICH_TEXT_CSS_CLASS, RenderContext, UNRENDERABLE_MARKER_PREFIX, convertMergeTagsToValues, escapeAttr, escapeHtml, getCssClassAttr, getCssClasses, getWidthPercentages, getWidthPixels, isHiddenOnAll, renderBlock, renderToMjml, renderUnrenderableBlock, resolveParagraphGap, richTextGapClass, toPaddingString };
|
|
1143
1178
|
|
|
1144
1179
|
//# sourceMappingURL=index.js.map
|