Skip to content

Commit a3ae179

Browse files
evilpiemoz-wptsync-bot
authored andcommitted
Sanitizer: Remove custom element state when |is| attribute is blocked.
Implements WICG/sanitizer-api#396 Differential Revision: https://phabricator.services.mozilla.com/D301304 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=2040656 gecko-commit: d8f0a20748554395560938baabeaa80986c758cc gecko-commit-git: beca389380ebb98e7631ffc4c3f06e55d765b009 gecko-reviewers: emilio
1 parent ca80830 commit a3ae179

2 files changed

Lines changed: 95 additions & 35 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
</head>
7+
<body>
8+
<script>
9+
10+
let constructor_called = false;
11+
let connectedCallback_called = false;
12+
13+
class FooBarElement extends HTMLDivElement {
14+
constructor() {
15+
super();
16+
constructor_called = true;
17+
}
18+
19+
connectedCallback() {
20+
connectedCallback_called = true;
21+
}
22+
}
23+
24+
customElements.define("foo-bar", FooBarElement, { extends: "div" });
25+
26+
function assert_removed(sanitizer) {
27+
constructor_called = connectedCallback_called = false;
28+
29+
let d = document.createElement("div");
30+
document.body.append(d);
31+
d.setHTML(`<div is="foo-bar">hello</div>`, { sanitizer } );
32+
assert_equals(d.innerHTML, `<div>hello</div>`);
33+
assert_false(d.firstChild.hasAttribute("is"));
34+
assert_true(d.firstChild.matches(":defined"));
35+
36+
assert_false(constructor_called);
37+
assert_false(connectedCallback_called);
38+
39+
d.remove();
40+
}
41+
42+
test(t => {
43+
assert_removed("default");
44+
}, "The is= attribute is removed by the default sanitizer config.");
45+
46+
test(t => {
47+
assert_removed({ removeAttributes: ["is"] });
48+
}, "The is= attribute is removed by the global removeAttributes");
49+
50+
test(t => {
51+
assert_removed({ elements: [{ name: "div", removeAttributes: ["is"] }], removeAttributes: [] });
52+
}, "The is= attribute is removed by the local removeAttributes");
53+
54+
test(t => {
55+
assert_removed({ elements: [{ name: "div", attributes: [] }], attributes: [] });
56+
}, "The is= attribute is removed by the local missing attributes");
57+
58+
function assert_kept(sanitizer) {
59+
constructor_called = connectedCallback_called = false;
60+
61+
let d = document.createElement("div");
62+
document.body.append(d);
63+
d.setHTML(`<div is="foo-bar">hello</div>`, { sanitizer });
64+
assert_equals(d.innerHTML, `<div is="foo-bar">hello</div>`);
65+
assert_true(d.firstChild.hasAttribute("is"));
66+
assert_true(d.firstChild.matches(":defined"));
67+
68+
// "is" is re-created even after removing the attribute.
69+
d.firstChild.removeAttribute("is");
70+
assert_equals(d.innerHTML, `<div is="foo-bar">hello</div>`);
71+
72+
assert_true(constructor_called);
73+
assert_true(connectedCallback_called);
74+
75+
d.remove();
76+
}
77+
78+
test(t => {
79+
assert_kept({ })
80+
}, "The is= attribute is kept when allowed with an empty config.");
81+
82+
test(t => {
83+
assert_kept({ attributes: ["is"] })
84+
}, "The is= attribute is kept when allowed by global attributes.");
85+
86+
test(t => {
87+
assert_kept({ removeAttributes: [] })
88+
}, "The is= attribute is kept when allowed by global removeAttributes.");
89+
90+
test(t => {
91+
assert_kept({ elements: [{ name: "div", attributes: ["is"] }], attributes: [] });
92+
}, "The is= attribute is kept when allowed by local attributes.");
93+
</script>
94+
</body>
95+
</html>

sanitizer-api/sanitizer-unknown.tentative.html

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,41 +33,6 @@
3333
{ sanitizer: { attributes: ["hello", "world"] } });
3434
assert_equals(d.innerHTML, `<b hello="1" world=""></b>`);
3535
}, "Unknown attribute names pass when allowed.");
36-
37-
test(t => {
38-
let d = document.createElement("div")
39-
d.setHTML(`<div is="foo-bar">hello</div>`);
40-
assert_equals(d.innerHTML, `<div>hello</div>`);
41-
assert_false(d.firstChild.hasAttribute("is"));
42-
assert_true(d.firstChild.matches(":defined"));
43-
}, "The is= attribute is removed by the default sanitizer config.");
44-
45-
test(t => {
46-
let d = document.createElement("div")
47-
d.setHTML(`<span is="foo-bar">hello</span>`);
48-
assert_equals(d.innerHTML, `<span>hello</span>`);
49-
assert_false(d.firstChild.hasAttribute("is"));
50-
assert_true(d.firstChild.matches(":defined"));
51-
}, "The is= attribute is removed from span by the default sanitizer config.");
52-
53-
54-
test(t => {
55-
let d = document.createElement("div")
56-
d.setHTML(`<div is="foo-bar">hello</div>`,
57-
{ sanitizer: { attributes: ["is"] } });
58-
assert_equals(d.innerHTML, `<div is="foo-bar">hello</div>`);
59-
assert_true(d.firstChild.hasAttribute("is"));
60-
assert_false(d.firstChild.matches(":defined"));
61-
}, "The is= attribute is kept when explicitly allowed.");
62-
63-
test(t => {
64-
let d = document.createElement("div")
65-
d.setHTML(`<div is="foo-bar">hello</div>`,
66-
{ sanitizer: { attributes: [] } });
67-
assert_equals(d.innerHTML, `<div>hello</div>`);
68-
assert_false(d.firstChild.hasAttribute("is"));
69-
assert_true(d.firstChild.matches(":defined"));
70-
}, "The is= attribute gets blocked with a custom config.");
7136
</script>
7237
</body>
7338
</html>

0 commit comments

Comments
 (0)