Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 4 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /trusted-types/Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-non-TT-realm.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="require-trusted-types-for 'script';"
/>
<title>
trusted-types (TT): `setAttribute`/`setAttributeNode` for an element
adopted from a non-TT realm respects TT's Content-Security-Policy (CSP)
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="nonSVGTestElements">
<iframe srcdoc="v"></iframe>
<script src="v"></script>
</div>
<svg id="svgTestElements">
<script href="v"></script>
<script xlink:href="v"></script>
</svg>
<script>
const passThroughPolicy = trustedTypes.createPolicy("passThrough", {
createHTML: (s) => s,
});
function runTest(aTestElement) {
const testAttr = aTestElement.attributes[0];
async_test(
(t) => {
const sourceFrame = document.createElement("iframe");
// The markup requires the parent element to ensure the attribute is associated with the
// correct namespace.
sourceFrame.srcdoc = passThroughPolicy.createHTML(
`<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<body>
<` +
aTestElement.parentElement.localName +
`>
<` +
aTestElement.localName +
` ` +
testAttr.name +
`="` +
testAttr.value +
`">
</` +
aTestElement.localName +
`>
</` +
aTestElement.parentElement.localName +
`>
doc without TT CSP.
</body>`
);
t.add_cleanup(() => {
sourceFrame.remove();
});
sourceFrame.addEventListener(
"load",
t.step_func_done(() => {
// A window is a global object which has 1-to-1 mapping to a realm, see the first
// and its following paragraph. Here, `sourceElement`'s node document's global
// belongs to a non-TT realm.
const sourceElement =
sourceFrame.contentDocument.body.querySelector(
aTestElement.localName
);
const sourceAttr = sourceElement.getAttributeNode(
testAttr.name
);
sourceElement.removeAttributeNode(sourceAttr);
document.body.append(sourceElement);
// Now `sourceElement`'s node document's global should belong to
// a TT-realm.
// Hence below calls to `setAttributeNode` and `setAttributeNS`
// should throw, because
// The latter should throw when executing step 5.
assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
sourceElement.setAttributeNode(sourceAttr);
});
assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
sourceElement.setAttributeNS(
sourceAttr.namespaceURI,
sourceAttr.name,
sourceAttr.value
);
});
})
);
document.body.append(sourceFrame);
},
`setAttribute and setAttributeNode respect the element's node document's global's CSP;
Element=${aTestElement.localName}; Parent=${aTestElement.parentElement.localName}; Attribute=${testAttr.name}`
);
}
for (const testElement of document.querySelectorAll(
"#nonSVGTestElements *"
)) {
runTest(testElement);
}
for (const testElement of document.querySelectorAll(
"#svgTestElements *"
)) {
runTest(testElement);
}
</script>
</body>
</html>