@maizzle/framework
Version:
Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.
76 lines (75 loc) • 2.55 kB
JavaScript
import { walk } from "../utils/ast/walker.js";
import "../utils/ast/index.js";
import { horizontalBorderPx, horizontalPaddingPx, lengthToPx } from "../utils/cssBox.js";
import safeParser from "postcss-safe-parser";
//#region src/transformers/imgWidth.ts
const MARKER = "data-maizzle-img-width";
function firstDeclValue(root, prop) {
let found;
root.walkDecls(prop, (d) => {
found = d.value;
return false;
});
return found;
}
/**
* Resolve an element's own pixel width from its inlined style (`max-width`
* then `width`) or, failing that, its `width` attribute. Percentages and
* other non-pixel lengths return null — the caller leaves the image fluid.
*/
function pixelWidthOf(el, root) {
if (root) {
const fromStyle = firstDeclValue(root, "max-width") ?? "";
const styleMax = fromStyle ? lengthToPx(fromStyle) : null;
if (styleMax != null) return styleMax;
const w = firstDeclValue(root, "width");
const styleWidth = w ? lengthToPx(w) : null;
if (styleWidth != null) return styleWidth;
}
const attrWidth = el.attribs?.width;
return attrWidth ? lengthToPx(attrWidth) : null;
}
/**
* Backfill the `width` attribute on `<Img>`-emitted images that were left
* without an explicit width. Runs after `columnWidth`, so every
* Container/Section/Column ancestor already carries a resolved pixel
* width in its inline style.
*
* For each marked `<img>`, walk up the ancestor chain accumulating
* horizontal padding+border, stopping at the nearest ancestor with a
* resolvable pixel width. The image width is that source minus the
* accumulated inset (so padding on wrappers narrows the image to its
* content box). When no pixel width is found anywhere, the marker is
* dropped and the image stays fluid.
*/
function imgWidthDom(dom) {
const targets = [];
walk(dom, (node) => {
const el = node;
if (el.attribs && MARKER in el.attribs) targets.push(el);
});
for (const img of targets) {
let cur = img.parent;
let insetPx = 0;
let resolvedPx = null;
while (cur) {
const el = cur;
if (el.attribs) {
const root = el.attribs.style ? safeParser(el.attribs.style) : null;
if (root) insetPx += horizontalPaddingPx(root) + horizontalBorderPx(root);
const px = pixelWidthOf(el, root);
if (px != null) {
resolvedPx = px;
break;
}
}
cur = cur.parent ?? null;
}
if (resolvedPx != null) img.attribs.width = String(Math.max(0, Math.round(resolvedPx - insetPx)));
delete img.attribs[MARKER];
}
return dom;
}
//#endregion
export { imgWidthDom };
//# sourceMappingURL=imgWidth.js.map