meno-core 1.0.1 → 1.0.2
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/lib/server/ssrRenderer.ts +39 -3
- package/package.json +1 -1
|
@@ -995,11 +995,47 @@ async function renderNode(
|
|
|
995
995
|
}
|
|
996
996
|
|
|
997
997
|
// Render as <picture> element if AVIF is available
|
|
998
|
+
// Split classes: layout/sizing on <picture>, image-specific on <img>
|
|
998
999
|
if (metadata?.avifSrcset) {
|
|
999
|
-
|
|
1000
|
+
// Image-specific class prefixes that should stay on <img>
|
|
1001
|
+
// objf- (object-fit), objp- (object-position), flt- (filter), tm- (transform), bs- (box-shadow)
|
|
1002
|
+
// Border classes: br- (border-radius), bt- (border-top), bb- (border-bottom),
|
|
1003
|
+
// bl- (border-left), border-r- (border-right), bc- (border-color)
|
|
1004
|
+
// Note: 'b-' is border, but 'b' alone is display:block - need hyphen
|
|
1005
|
+
const imgClassPrefixes = [
|
|
1006
|
+
'objf-', 'objp-', 'flt-', 'tm-', 'bs-',
|
|
1007
|
+
'br-', 'bt-', 'bb-', 'bl-', 'border-r-', 'bc-', 'b-'
|
|
1008
|
+
];
|
|
1009
|
+
// Opacity classes (o-NUMBER) go on img, but overflow (o-h, o-a, o-s, o-v) stays on picture
|
|
1010
|
+
const opacityPattern = /^o-\d/;
|
|
1011
|
+
|
|
1012
|
+
// Parse classes from classAttr
|
|
1013
|
+
const classMatch = classAttr.match(/class="([^"]*)"/);
|
|
1014
|
+
const allClasses = classMatch ? classMatch[1].split(/\s+/).filter(Boolean) : [];
|
|
1015
|
+
|
|
1016
|
+
// Split classes between picture and img
|
|
1017
|
+
const imgClasses: string[] = [];
|
|
1018
|
+
const pictureClasses: string[] = [];
|
|
1019
|
+
|
|
1020
|
+
for (const cls of allClasses) {
|
|
1021
|
+
if (imgClassPrefixes.some(prefix => cls.startsWith(prefix)) || opacityPattern.test(cls)) {
|
|
1022
|
+
imgClasses.push(cls);
|
|
1023
|
+
} else {
|
|
1024
|
+
pictureClasses.push(cls);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
const pictureClassAttr = pictureClasses.length > 0
|
|
1029
|
+
? ` class="${escapeHtml(pictureClasses.join(' '))}"`
|
|
1030
|
+
: '';
|
|
1031
|
+
const imgClassAttr = imgClasses.length > 0
|
|
1032
|
+
? ` class="${escapeHtml(imgClasses.join(' '))}"`
|
|
1033
|
+
: '';
|
|
1034
|
+
|
|
1035
|
+
return `<picture${pictureClassAttr}>` +
|
|
1000
1036
|
`<source type="image/avif" srcset="${escapeHtml(metadata.avifSrcset)}" sizes="${escapeHtml(sizesAttr)}" />` +
|
|
1001
1037
|
`<source type="image/webp" srcset="${escapeHtml(metadata.srcset)}" sizes="${escapeHtml(sizesAttr)}" />` +
|
|
1002
|
-
`<img${
|
|
1038
|
+
`<img${imgClassAttr}${imgAttrs}${blurStyle}${attrs} />` +
|
|
1003
1039
|
`</picture>`;
|
|
1004
1040
|
}
|
|
1005
1041
|
|
|
@@ -1024,7 +1060,7 @@ async function renderNode(
|
|
|
1024
1060
|
function buildAttributes(props: Record<string, unknown>, exclude: string[] = []): string {
|
|
1025
1061
|
const attrs: string[] = [];
|
|
1026
1062
|
// Internal props that should never be rendered as HTML attributes
|
|
1027
|
-
const internalProps = ['
|
|
1063
|
+
const internalProps = ['tag', 'component', 'props', 'children', 'src', 'alt', 'loading', 'width', 'height', 'sizes', 'srcset'];
|
|
1028
1064
|
const defaultExclude = [...internalProps, ...exclude];
|
|
1029
1065
|
|
|
1030
1066
|
// Regex to detect unresolved template strings like {{link.target}}
|