@uniweb/runtime 1.2.0 → 1.2.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/dist/ssr.js +86 -106
- package/dist/ssr.js.map +1 -1
- package/package.json +3 -3
- package/src/background-shared.js +16 -10
- package/src/background.js +182 -0
- package/src/components/Background.jsx +19 -294
- package/src/components/PageRenderer.jsx +4 -2
- package/src/load-page-data.js +13 -2
- package/src/setup.js +2 -1
- package/src/ssr-renderer.js +26 -122
package/dist/ssr.js
CHANGED
|
@@ -222,9 +222,12 @@ function siteUrl(url) {
|
|
|
222
222
|
function withOpacity(color, opacity) {
|
|
223
223
|
if (typeof color !== "string" || !color) return color;
|
|
224
224
|
if (color.startsWith("#")) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
let hex = color.slice(1);
|
|
226
|
+
if (hex.length === 3 || hex.length === 4) hex = [...hex].map((c) => c + c).join("");
|
|
227
|
+
if (!/^[0-9a-f]{6}([0-9a-f]{2})?$/i.test(hex)) return color;
|
|
228
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
229
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
230
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
228
231
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
229
232
|
}
|
|
230
233
|
if (color.startsWith("rgb")) {
|
|
@@ -233,6 +236,76 @@ function withOpacity(color, opacity) {
|
|
|
233
236
|
}
|
|
234
237
|
return color;
|
|
235
238
|
}
|
|
239
|
+
const h = React.createElement;
|
|
240
|
+
const FILL = { position: "absolute", inset: 0 };
|
|
241
|
+
function ColorLayer({ color }) {
|
|
242
|
+
if (!color) return null;
|
|
243
|
+
return h("div", { className: "background-color", style: { ...FILL, backgroundColor: color }, "aria-hidden": "true" });
|
|
244
|
+
}
|
|
245
|
+
function GradientLayer({ gradient }) {
|
|
246
|
+
if (!gradient) return null;
|
|
247
|
+
if (typeof gradient === "string") {
|
|
248
|
+
return h("div", { className: "background-gradient", style: { ...FILL, background: gradient }, "aria-hidden": "true" });
|
|
249
|
+
}
|
|
250
|
+
const start = gradient.start ?? "transparent";
|
|
251
|
+
const end = gradient.end ?? "transparent";
|
|
252
|
+
const startOpacity = gradient.startOpacity ?? 1;
|
|
253
|
+
const endOpacity = gradient.endOpacity ?? 1;
|
|
254
|
+
const startColor = startOpacity < 1 ? withOpacity(start, startOpacity) : start;
|
|
255
|
+
const endColor = endOpacity < 1 ? withOpacity(end, endOpacity) : end;
|
|
256
|
+
const background = `linear-gradient(${gradient.angle ?? 0}deg, ${startColor} ${gradient.startPosition ?? 0}%, ${endColor} ${gradient.endPosition ?? 100}%)`;
|
|
257
|
+
return h("div", { className: "background-gradient", style: { ...FILL, background }, "aria-hidden": "true" });
|
|
258
|
+
}
|
|
259
|
+
function ImageLayer({ image }) {
|
|
260
|
+
if (!image?.src) return null;
|
|
261
|
+
const style = {
|
|
262
|
+
...FILL,
|
|
263
|
+
backgroundImage: `url(${siteUrl(image.src)})`,
|
|
264
|
+
backgroundPosition: image.position ?? "center",
|
|
265
|
+
backgroundSize: image.size ?? "cover",
|
|
266
|
+
backgroundRepeat: "no-repeat"
|
|
267
|
+
};
|
|
268
|
+
return h("div", { className: "background-image", style, "aria-hidden": "true" });
|
|
269
|
+
}
|
|
270
|
+
function VideoPoster({ video }) {
|
|
271
|
+
if (!video?.src || !video.poster) return null;
|
|
272
|
+
return h(ImageLayer, { image: { src: video.poster, size: "cover", position: "center" } });
|
|
273
|
+
}
|
|
274
|
+
function Overlay({ overlay }) {
|
|
275
|
+
if (!overlay?.enabled) return null;
|
|
276
|
+
const opacity = overlay.opacity ?? 0.5;
|
|
277
|
+
if (overlay.gradient) {
|
|
278
|
+
const g = overlay.gradient;
|
|
279
|
+
const background = `linear-gradient(${g.angle ?? 180}deg, ${g.start ?? "rgba(0,0,0,0.7)"} ${g.startPosition ?? 0}%, ${g.end ?? "rgba(0,0,0,0)"} ${g.endPosition ?? 100}%)`;
|
|
280
|
+
return h("div", {
|
|
281
|
+
className: "background-overlay background-overlay--gradient",
|
|
282
|
+
style: { ...FILL, background, opacity, pointerEvents: "none" },
|
|
283
|
+
"aria-hidden": "true"
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
const base = overlay.type === "light" ? "255, 255, 255" : "0, 0, 0";
|
|
287
|
+
return h("div", {
|
|
288
|
+
className: "background-overlay background-overlay--solid",
|
|
289
|
+
style: { ...FILL, backgroundColor: `rgba(${base}, ${opacity})`, pointerEvents: "none" },
|
|
290
|
+
"aria-hidden": "true"
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
function Background({ mode, color, gradient, image, video, overlay, className = "", Video = VideoPoster }) {
|
|
294
|
+
if (!mode) return null;
|
|
295
|
+
return h(
|
|
296
|
+
"div",
|
|
297
|
+
{
|
|
298
|
+
className: `background background--${mode} ${className}`.trim(),
|
|
299
|
+
style: { ...FILL, overflow: "hidden", zIndex: 0 },
|
|
300
|
+
"aria-hidden": "true"
|
|
301
|
+
},
|
|
302
|
+
mode === "color" ? h(ColorLayer, { color }) : null,
|
|
303
|
+
mode === "gradient" ? h(GradientLayer, { gradient }) : null,
|
|
304
|
+
mode === "image" ? h(ImageLayer, { image }) : null,
|
|
305
|
+
mode === "video" ? h(Video, { video }) : null,
|
|
306
|
+
h(Overlay, { overlay })
|
|
307
|
+
);
|
|
308
|
+
}
|
|
236
309
|
function default404Html(basePath = "") {
|
|
237
310
|
const homeHref = basePath ? `${basePath}/` : "/";
|
|
238
311
|
return `<div class="page-not-found" style="min-height:80vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center"><h1 style="font-size:3rem;font-weight:bold;color:#1f2937;margin-bottom:1rem">404</h1><p style="color:#64748b;margin-bottom:2rem">Page not found</p><a href="${homeHref}" style="color:#3b82f6;text-decoration:underline">Go to homepage</a></div>`;
|
|
@@ -452,105 +525,7 @@ function getWrapperProps(block) {
|
|
|
452
525
|
}
|
|
453
526
|
function renderBackground(background) {
|
|
454
527
|
if (!background?.mode) return null;
|
|
455
|
-
|
|
456
|
-
position: "absolute",
|
|
457
|
-
inset: "0",
|
|
458
|
-
overflow: "hidden",
|
|
459
|
-
zIndex: 0
|
|
460
|
-
};
|
|
461
|
-
const children = [];
|
|
462
|
-
if (background.mode === "color" && background.color) {
|
|
463
|
-
children.push(
|
|
464
|
-
React.createElement("div", {
|
|
465
|
-
key: "bg-color",
|
|
466
|
-
className: "background-color",
|
|
467
|
-
style: { position: "absolute", inset: "0", backgroundColor: background.color },
|
|
468
|
-
"aria-hidden": "true"
|
|
469
|
-
})
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
if (background.mode === "gradient" && background.gradient) {
|
|
473
|
-
const g = background.gradient;
|
|
474
|
-
let bgValue;
|
|
475
|
-
if (typeof g === "string") {
|
|
476
|
-
bgValue = g;
|
|
477
|
-
} else {
|
|
478
|
-
const {
|
|
479
|
-
start = "transparent",
|
|
480
|
-
end = "transparent",
|
|
481
|
-
angle = 0,
|
|
482
|
-
startPosition = 0,
|
|
483
|
-
endPosition = 100,
|
|
484
|
-
startOpacity = 1,
|
|
485
|
-
endOpacity = 1
|
|
486
|
-
} = g;
|
|
487
|
-
const startColor = startOpacity < 1 ? withOpacity(start, startOpacity) : start;
|
|
488
|
-
const endColor = endOpacity < 1 ? withOpacity(end, endOpacity) : end;
|
|
489
|
-
bgValue = `linear-gradient(${angle}deg, ${startColor} ${startPosition}%, ${endColor} ${endPosition}%)`;
|
|
490
|
-
}
|
|
491
|
-
children.push(
|
|
492
|
-
React.createElement("div", {
|
|
493
|
-
key: "bg-gradient",
|
|
494
|
-
className: "background-gradient",
|
|
495
|
-
style: { position: "absolute", inset: "0", background: bgValue },
|
|
496
|
-
"aria-hidden": "true"
|
|
497
|
-
})
|
|
498
|
-
);
|
|
499
|
-
}
|
|
500
|
-
if (background.mode === "image" && background.image?.src) {
|
|
501
|
-
const img = background.image;
|
|
502
|
-
children.push(
|
|
503
|
-
React.createElement("div", {
|
|
504
|
-
key: "bg-image",
|
|
505
|
-
className: "background-image",
|
|
506
|
-
style: {
|
|
507
|
-
position: "absolute",
|
|
508
|
-
inset: "0",
|
|
509
|
-
backgroundImage: `url(${siteUrl(img.src)})`,
|
|
510
|
-
backgroundPosition: img.position || "center",
|
|
511
|
-
backgroundSize: img.size || "cover",
|
|
512
|
-
backgroundRepeat: "no-repeat"
|
|
513
|
-
},
|
|
514
|
-
"aria-hidden": "true"
|
|
515
|
-
})
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
if (background.overlay?.enabled) {
|
|
519
|
-
const ov = background.overlay;
|
|
520
|
-
let overlayStyle;
|
|
521
|
-
if (ov.gradient) {
|
|
522
|
-
const g = ov.gradient;
|
|
523
|
-
overlayStyle = {
|
|
524
|
-
position: "absolute",
|
|
525
|
-
inset: "0",
|
|
526
|
-
pointerEvents: "none",
|
|
527
|
-
background: `linear-gradient(${g.angle || 180}deg, ${g.start || "rgba(0,0,0,0.7)"} ${g.startPosition || 0}%, ${g.end || "rgba(0,0,0,0)"} ${g.endPosition || 100}%)`,
|
|
528
|
-
opacity: ov.opacity ?? 0.5
|
|
529
|
-
};
|
|
530
|
-
} else {
|
|
531
|
-
const baseColor = ov.type === "light" ? "255, 255, 255" : "0, 0, 0";
|
|
532
|
-
overlayStyle = {
|
|
533
|
-
position: "absolute",
|
|
534
|
-
inset: "0",
|
|
535
|
-
pointerEvents: "none",
|
|
536
|
-
backgroundColor: `rgba(${baseColor}, ${ov.opacity ?? 0.5})`
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
children.push(
|
|
540
|
-
React.createElement("div", {
|
|
541
|
-
key: "bg-overlay",
|
|
542
|
-
className: ov.gradient ? "background-overlay background-overlay--gradient" : "background-overlay background-overlay--solid",
|
|
543
|
-
style: overlayStyle,
|
|
544
|
-
"aria-hidden": "true"
|
|
545
|
-
})
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
if (children.length === 0) return null;
|
|
549
|
-
return React.createElement("div", {
|
|
550
|
-
className: `background background--${background.mode}`,
|
|
551
|
-
style: containerStyle,
|
|
552
|
-
"aria-hidden": "true"
|
|
553
|
-
}, ...children);
|
|
528
|
+
return React.createElement(Background, background);
|
|
554
529
|
}
|
|
555
530
|
function renderBlock(block, { as = "section", stickySelf = false } = {}) {
|
|
556
531
|
const Component = block.initComponent();
|
|
@@ -563,10 +538,13 @@ function renderBlock(block, { as = "section", stickySelf = false } = {}) {
|
|
|
563
538
|
const meta = getComponentMeta(block.type);
|
|
564
539
|
const entityStore = block.website?.entityStore;
|
|
565
540
|
let entityData = null;
|
|
541
|
+
let pending = false;
|
|
566
542
|
if (entityStore) {
|
|
567
543
|
const resolved = entityStore.resolve(block, meta);
|
|
568
544
|
if (resolved.status === "ready") entityData = resolved.data;
|
|
545
|
+
pending = resolved.status === "pending";
|
|
569
546
|
}
|
|
547
|
+
block.dataLoading = pending;
|
|
570
548
|
const prepared = prepareProps(block, meta, entityData);
|
|
571
549
|
const params = prepared.params;
|
|
572
550
|
const content = { ...prepared.content, ...block.properties };
|
|
@@ -691,9 +669,7 @@ function initPrerender(content, foundation, extensionsOrOptions, maybeOptions) {
|
|
|
691
669
|
)
|
|
692
670
|
);
|
|
693
671
|
};
|
|
694
|
-
uniweb.backgroundRenderer =
|
|
695
|
-
return renderBackground(background);
|
|
696
|
-
};
|
|
672
|
+
uniweb.backgroundRenderer = Background;
|
|
697
673
|
wireFoundationCapabilities(uniweb, foundation);
|
|
698
674
|
ensureThemeCss(uniweb, foundation);
|
|
699
675
|
const website = uniweb.activeWebsite;
|
|
@@ -1227,15 +1203,19 @@ async function loadPageData({ website, route, fetch: fetch2, dev = false, locale
|
|
|
1227
1203
|
const key = deriveCacheKey$1(request);
|
|
1228
1204
|
if (!entries.has(key)) entries.set(key, entry);
|
|
1229
1205
|
};
|
|
1206
|
+
const answered = new DataStore();
|
|
1230
1207
|
const recording = {
|
|
1231
1208
|
peek: (request, ctx) => dispatcher.peek(request, ctx),
|
|
1232
|
-
peekRecord: (id) =>
|
|
1209
|
+
peekRecord: (id) => answered.getRecord(id),
|
|
1233
1210
|
dispatch: async (request, ctx) => {
|
|
1234
1211
|
if (prerender === "author" && request?.prerender === false) {
|
|
1235
1212
|
record(request, { config: request, outcome: "skipped", data: null });
|
|
1236
1213
|
return { data: null };
|
|
1237
1214
|
}
|
|
1238
1215
|
const result = await dispatcher.dispatch(request, ctx);
|
|
1216
|
+
if (!result?.error && result?.data != null) {
|
|
1217
|
+
answered.set(deriveCacheKey$1(request), result.meta ? { data: result.data, meta: result.meta } : { data: result.data });
|
|
1218
|
+
}
|
|
1239
1219
|
record(request, result?.error ? { config: request, outcome: "failed", data: null, error: result.error } : { config: request, outcome: "fetched", data: result?.data ?? null, ...result?.meta ? { meta: result.meta } : {} });
|
|
1240
1220
|
return result;
|
|
1241
1221
|
}
|