Pre Release New Changes
This commit is contained in:
@@ -46,7 +46,9 @@ function jsResponse(code: string): Response {
|
||||
return new Response(code, {
|
||||
headers: {
|
||||
"content-type": "text/javascript; charset=utf-8",
|
||||
"cache-control": "no-cache",
|
||||
"cache-control": "no-store, max-age=0",
|
||||
pragma: "no-cache",
|
||||
expires: "0",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -607,6 +607,7 @@ export const HMR_CLIENT_JS = `
|
||||
var from = document.getElementById("app");
|
||||
var to = doc.getElementById("app");
|
||||
|
||||
syncWrnStyles(doc);
|
||||
if (from && to) {
|
||||
morph(from, to);
|
||||
}
|
||||
@@ -638,6 +639,62 @@ export const HMR_CLIENT_JS = `
|
||||
);
|
||||
}
|
||||
|
||||
function currentDocumentNonce() {
|
||||
var node = document.querySelector("script[nonce],style[nonce]");
|
||||
if (!node) return "";
|
||||
return node.nonce || node.getAttribute("nonce") || "";
|
||||
}
|
||||
|
||||
function syncWrnStyles(nextDocument) {
|
||||
var current = Array.prototype.slice.call(
|
||||
document.querySelectorAll("style[data-wrnexus-style-id]"),
|
||||
);
|
||||
var next = Array.prototype.slice.call(
|
||||
nextDocument.querySelectorAll("style[data-wrnexus-style-id]"),
|
||||
);
|
||||
var currentById = Object.create(null);
|
||||
var nextIds = Object.create(null);
|
||||
var nonce = currentDocumentNonce();
|
||||
|
||||
current.forEach(function (style) {
|
||||
var id = style.getAttribute("data-wrnexus-style-id");
|
||||
if (id) currentById[id] = style;
|
||||
});
|
||||
|
||||
next.forEach(function (nextStyle) {
|
||||
var id = nextStyle.getAttribute("data-wrnexus-style-id");
|
||||
if (!id) return;
|
||||
nextIds[id] = true;
|
||||
|
||||
var currentStyle = currentById[id];
|
||||
if (!currentStyle) {
|
||||
currentStyle = document.createElement("style");
|
||||
currentStyle.setAttribute("data-wrnexus-style-id", id);
|
||||
}
|
||||
|
||||
["data-wrnexus-style-owner", "data-wrnexus-style-kind"].forEach(function (name) {
|
||||
var value = nextStyle.getAttribute(name);
|
||||
if (value == null) currentStyle.removeAttribute(name);
|
||||
else currentStyle.setAttribute(name, value);
|
||||
});
|
||||
|
||||
if (nonce) currentStyle.setAttribute("nonce", nonce);
|
||||
if (currentStyle.textContent !== nextStyle.textContent) {
|
||||
currentStyle.textContent = nextStyle.textContent;
|
||||
}
|
||||
|
||||
// Appending an existing node moves it. This keeps every local style after
|
||||
// global stylesheets and in the exact layout -> page -> component order
|
||||
// produced by the incoming SSR document.
|
||||
document.head.appendChild(currentStyle);
|
||||
});
|
||||
|
||||
current.forEach(function (style) {
|
||||
var id = style.getAttribute("data-wrnexus-style-id");
|
||||
if (id && !nextIds[id]) style.remove();
|
||||
});
|
||||
}
|
||||
|
||||
// Minimal index-based DOM morph: preserve matching nodes (keeps state/focus),
|
||||
// patch text and attributes, clone genuinely new nodes, drop removed ones.
|
||||
// Preserve a hydrated subtree only while its server hydration signature and
|
||||
@@ -1401,6 +1458,7 @@ export function createHandlers(deps: RuntimeDeps): Handlers {
|
||||
.join("\n") || undefined,
|
||||
htmlAttrs,
|
||||
documentTemplate,
|
||||
styleNonce: (ctx.locals.cspNonce as string | undefined) ?? undefined,
|
||||
});
|
||||
// Conditional GET: hash the page CONTENT (`body`), not the assembled shell —
|
||||
// the shell carries a per-request CSP nonce in dev, which would otherwise make
|
||||
|
||||
@@ -26,3 +26,11 @@ test("HMR preserves the active browser theme and accent", () => {
|
||||
|
||||
expect(HMR_CLIENT_JS).toContain('new CustomEvent("wrnexus:hmr-updated"');
|
||||
});
|
||||
|
||||
test("HMR synchronizes local WRN styles with the current document nonce", () => {
|
||||
expect(HMR_CLIENT_JS).toContain("style[data-wrnexus-style-id]");
|
||||
expect(HMR_CLIENT_JS).toContain("function currentDocumentNonce()");
|
||||
expect(HMR_CLIENT_JS).toContain('currentStyle.setAttribute("nonce", nonce)');
|
||||
expect(HMR_CLIENT_JS).toContain("document.head.appendChild(currentStyle)");
|
||||
expect(HMR_CLIENT_JS).toContain("syncWrnStyles(doc)");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user