Pre Release New Changes

This commit is contained in:
2026-07-31 16:30:13 +05:30
parent 358a520bc5
commit 3e565e8d03
189 changed files with 36727 additions and 17249 deletions
+55
View File
@@ -69,6 +69,59 @@ export const NAV_RUNTIME = String.raw`
return rel.indexOf("external") === -1;
}
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;
}
document.head.appendChild(currentStyle);
});
current.forEach(function (style) {
var id = style.getAttribute("data-wrnexus-style-id");
if (id && !nextIds[id]) style.remove();
});
}
function loadedScriptPaths() {
var loaded = {};
@@ -317,6 +370,8 @@ export const NAV_RUNTIME = String.raw`
document.title = doc.title;
}
syncWrnStyles(doc);
var importedNodes = [];
for (
+21
View File
@@ -126,3 +126,24 @@ test("unmounts and remounts package runtimes during client navigation", async ()
expect(mounts).toBe(1);
expect(win.document.getElementById("app").textContent).toContain("New");
});
test("synchronizes page styles during client navigation and preserves the current nonce", async () => {
install(
`<script nonce="current-nonce"></script>` +
`<style data-wrnexus-style-id="home" data-wrnexus-style-kind="page" nonce="current-nonce">.page{color:red}</style>` +
`<div id="app"><a href="/about" id="lnk">About</a></div>`,
);
nextHtml =
`<html><head>` +
`<style data-wrnexus-style-id="about" data-wrnexus-style-owner="About" data-wrnexus-style-kind="page" nonce="response-nonce">.page{color:blue}</style>` +
`</head><body><div id="app"><h1 class="page">About</h1></div></body></html>`;
win.document.getElementById("lnk").click();
await flush();
expect(win.document.querySelector('style[data-wrnexus-style-id="home"]')).toBeNull();
const style = win.document.querySelector('style[data-wrnexus-style-id="about"]');
expect(style).not.toBeNull();
expect(style.textContent).toContain("color:blue");
expect(style.getAttribute("nonce")).toBe("current-nonce");
});
+36
View File
@@ -333,3 +333,39 @@ test("data-for preserves arrays of objects from encoded component scope", () =>
"Four",
]);
});
test("$emit inside component functions does not depend on a global browser event", () => {
const behavior = Buffer.from(
JSON.stringify({
functions: `
function showOverlay(sourceEvent) {
visible = true
$emit("open", { source: sourceEvent.type })
}
`,
watches: [],
lifecycle: {},
}),
).toString("base64");
delete (globalThis as Record<string, unknown>).event;
const win = mount(
`<div data-scope="visible: false" data-wrn-events="open" data-wrn-behavior="${behavior}">
<button data-on-click="showOverlay(event)">Open overlay</button>
<span>{visible}</span>
</div>`,
);
const root = win.document.querySelector("[data-wrn-events]")!;
let detail: Record<string, unknown> | undefined;
root.addEventListener("open", (event) => {
detail = (event as unknown as CustomEvent).detail;
});
win.document.querySelector("button")!.click();
expect(win.document.querySelector("span")!.textContent).toBe("true");
expect(detail).toEqual({ source: "click" });
});