Preserve inert control scripts during client navigation
This commit is contained in:
1 parent
41383960f8
commit
c3818f0041
4 files changed
+14
-4
No files matched your search
@@ -375,7 +375,7 @@
|
|||||||
},
|
},
|
||||||
"packages/csr": {
|
"packages/csr": {
|
||||||
"name": "@wrnexus/csr",
|
"name": "@wrnexus/csr",
|
||||||
"version": "0.8.43",
|
"version": "0.8.44",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "workspace:*",
|
"@wrnexus/core": "workspace:*",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/csr",
|
"name": "@wrnexus/csr",
|
||||||
"version": "0.8.43",
|
"version": "0.8.44",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -576,7 +576,10 @@ export const NAV_RUNTIME = String.raw`
|
|||||||
|
|
||||||
document.querySelectorAll('script[data-wrn-controls]').forEach(function (node) { node.remove(); });
|
document.querySelectorAll('script[data-wrn-controls]').forEach(function (node) { node.remove(); });
|
||||||
doc.querySelectorAll('script[data-wrn-controls]').forEach(function (node) {
|
doc.querySelectorAll('script[data-wrn-controls]').forEach(function (node) {
|
||||||
document.body.appendChild(document.importNode(node, true));
|
// Preserve parser-created inert JSON nodes. Deep cloning script text
|
||||||
|
// makes Chrome recheck it as a modified script under Trusted Types.
|
||||||
|
if (node.getAttribute("type") !== "application/json") return;
|
||||||
|
document.body.appendChild(document.adoptNode(node));
|
||||||
});
|
});
|
||||||
|
|
||||||
var importedNodes = [];
|
var importedNodes = [];
|
||||||
|
|||||||
@@ -106,11 +106,18 @@ test("navigation supplies TrustedHTML to the document parser", async () => {
|
|||||||
|
|
||||||
test("navigation replaces document control registries before hydration", async () => {
|
test("navigation replaces document control registries before hydration", async () => {
|
||||||
install('<div id="app"><a href="/next" id="lnk">Next</a></div><script type="application/json" data-wrn-controls id="old">[]</script>');
|
install('<div id="app"><a href="/next" id="lnk">Next</a></div><script type="application/json" data-wrn-controls id="old">[]</script>');
|
||||||
nextHtml = '<html><body><div id="app">Next</div><script type="application/json" data-wrn-controls id="new">[[{"cond":null,"body":"Ready"}]]</script></body></html>';
|
const importNode = win.document.importNode.bind(win.document);
|
||||||
|
win.document.importNode = (node: any, deep: boolean) => {
|
||||||
|
if (node.nodeName === "SCRIPT") throw new Error("Script text must not be cloned under Trusted Types");
|
||||||
|
return importNode(node, deep);
|
||||||
|
};
|
||||||
|
nextHtml = '<html><body><div id="app">Next</div><script type="application/json" data-wrn-controls id="new">[[{"cond":null,"body":"Ready"}]]</script><script data-wrn-controls id="executable">window.bad = true</script></body></html>';
|
||||||
win.document.getElementById("lnk").click();
|
win.document.getElementById("lnk").click();
|
||||||
await flush();
|
await flush();
|
||||||
expect(win.document.getElementById("old")).toBeNull();
|
expect(win.document.getElementById("old")).toBeNull();
|
||||||
expect(win.document.getElementById("new")?.textContent).toContain("Ready");
|
expect(win.document.getElementById("new")?.textContent).toContain("Ready");
|
||||||
|
expect(win.document.getElementById("new")?.type).toBe("application/json");
|
||||||
|
expect(win.document.getElementById("executable")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("prefetches focused routes once and reuses the document during navigation", async () => {
|
test("prefetches focused routes once and reuses the document during navigation", async () => {
|
||||||
|
|||||||
Reference in new issue
Block a user