cloudflare-next-intl 0.8.55 → 0.8.56
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.
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
function toBase64(str) {
|
|
2
|
+
if (typeof Buffer !== "undefined") {
|
|
3
|
+
return Buffer.from(str).toString("base64");
|
|
4
|
+
}
|
|
5
|
+
if (typeof btoa === "function") {
|
|
6
|
+
return btoa(unescape(encodeURIComponent(str)));
|
|
7
|
+
}
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
1
10
|
export function getImageBlurSvg(blurDataURL, blurWidth, blurHeight, objectFit, stdDeviation = 20) {
|
|
2
11
|
const std = stdDeviation;
|
|
3
12
|
const viewBox = blurWidth && blurHeight
|
|
@@ -11,6 +20,6 @@ export function getImageBlurSvg(blurDataURL, blurWidth, blurHeight, objectFit, s
|
|
|
11
20
|
? "xMidYMid slice"
|
|
12
21
|
: "none";
|
|
13
22
|
const svg = `<svg xmlns='http://www.w3.org/2000/svg' ${viewBox}><filter id='b' color-interpolation-filters='sRGB'><feGaussianBlur stdDeviation='${std}'/><feColorMatrix values='1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1' result='s'/><feFlood x='0' y='0' width='100%' height='100%'/><feComposite operator='out' in='s'/><feComposite in2='SourceGraphic'/><feGaussianBlur stdDeviation='${std}'/></filter><image width='100%' height='100%' x='0' y='0' preserveAspectRatio='${preserveAspectRatio}' style='filter: url(#b);' href='${blurDataURL}'/></svg>`;
|
|
14
|
-
const base64 =
|
|
23
|
+
const base64 = toBase64(svg);
|
|
15
24
|
return `data:image/svg+xml;base64,${base64}`;
|
|
16
25
|
}
|
|
@@ -6,26 +6,71 @@ const manifestData = manifest;
|
|
|
6
6
|
const images = (manifestData && typeof manifestData === "object" && manifestData.images)
|
|
7
7
|
? manifestData.images
|
|
8
8
|
: {};
|
|
9
|
+
function findEntry(srcVal) {
|
|
10
|
+
if (!srcVal)
|
|
11
|
+
return undefined;
|
|
12
|
+
const raw = typeof srcVal === "string"
|
|
13
|
+
? srcVal
|
|
14
|
+
: (typeof srcVal === "object" && srcVal !== null && "src" in srcVal)
|
|
15
|
+
? String(srcVal.src)
|
|
16
|
+
: String(srcVal);
|
|
17
|
+
if (images[raw])
|
|
18
|
+
return images[raw];
|
|
19
|
+
const withoutPublic = raw.replace(/^\/?public/, "");
|
|
20
|
+
if (images[withoutPublic])
|
|
21
|
+
return images[withoutPublic];
|
|
22
|
+
const withSlash = withoutPublic.startsWith("/") ? withoutPublic : "/" + withoutPublic;
|
|
23
|
+
if (images[withSlash])
|
|
24
|
+
return images[withSlash];
|
|
25
|
+
const clean = withSlash.split("?")[0].split("#")[0];
|
|
26
|
+
if (images[clean])
|
|
27
|
+
return images[clean];
|
|
28
|
+
for (const [key, entry] of Object.entries(images)) {
|
|
29
|
+
const filename = key.split("/").pop();
|
|
30
|
+
if (filename && (clean.endsWith("/" + filename) || clean.includes(filename.split(".")[0]))) {
|
|
31
|
+
return entry;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
9
36
|
function resolveProps(props) {
|
|
10
37
|
let src = props.src;
|
|
11
38
|
let blurDataURL = props.blurDataURL;
|
|
12
39
|
let width = props.width;
|
|
13
40
|
let height = props.height;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
41
|
+
let style = props.style;
|
|
42
|
+
const entry = findEntry(src);
|
|
43
|
+
if (entry) {
|
|
44
|
+
if (entry.src) {
|
|
45
|
+
if (typeof src === "string") {
|
|
18
46
|
src = entry.src;
|
|
19
|
-
if (!blurDataURL && props.placeholder === "blur" && entry.blurDataURL) {
|
|
20
|
-
blurDataURL = getImageBlurSvg(entry.blurDataURL, entry.blurWidth, entry.blurHeight, props.style?.objectFit);
|
|
21
47
|
}
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
|
|
48
|
+
else if (typeof src === "object" && src !== null && "src" in src) {
|
|
49
|
+
src = { ...src, src: entry.src };
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
src = entry.src;
|
|
25
53
|
}
|
|
26
54
|
}
|
|
55
|
+
if (!blurDataURL && props.placeholder === "blur" && entry.blurDataURL) {
|
|
56
|
+
blurDataURL = getImageBlurSvg(entry.blurDataURL, entry.blurWidth, entry.blurHeight, props.style?.objectFit);
|
|
57
|
+
}
|
|
58
|
+
if (!width && !props.fill && entry.width) {
|
|
59
|
+
width = entry.width;
|
|
60
|
+
height = entry.height;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (props.placeholder === "blur" && blurDataURL) {
|
|
64
|
+
const objectFit = props.style?.objectFit || (props.className?.includes("object-contain") ? "contain" : "cover");
|
|
65
|
+
style = {
|
|
66
|
+
backgroundSize: objectFit,
|
|
67
|
+
backgroundPosition: "50% 50%",
|
|
68
|
+
backgroundRepeat: "no-repeat",
|
|
69
|
+
backgroundImage: `url("${blurDataURL}")`,
|
|
70
|
+
...style,
|
|
71
|
+
};
|
|
27
72
|
}
|
|
28
|
-
return { ...props, src, blurDataURL, width, height };
|
|
73
|
+
return { ...props, src, blurDataURL, width, height, style };
|
|
29
74
|
}
|
|
30
75
|
export default function Image(props) {
|
|
31
76
|
const resolved = resolveProps(props);
|