Differential Revision: https://phabricator.services.mozilla.com/D295601
95 lines
3.4 KiB
HTML
95 lines
3.4 KiB
HTML
<!DOCTYPE html>
|
|
<title>Custom Elements: namespace prefix is set after construction per spec</title>
|
|
<link rel="help" content="https://dom.spec.whatwg.org/#concept-create-element">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<body>
|
|
<script>
|
|
// Step 5.1.3.9 of https://dom.spec.whatwg.org/#concept-create-element sets
|
|
// the namespace prefix AFTER the constructor returns. These tests verify that
|
|
// the prefix is not observable during construction but is correct afterwards.
|
|
|
|
test(() => {
|
|
let prefixDuringConstructor;
|
|
let tagNameDuringConstructor;
|
|
|
|
class PrefixEl extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
prefixDuringConstructor = this.prefix;
|
|
tagNameDuringConstructor = this.tagName;
|
|
}
|
|
}
|
|
customElements.define('prefix-timing-el', PrefixEl);
|
|
|
|
const el = document.createElementNS('http://www.w3.org/1999/xhtml', 'p:prefix-timing-el');
|
|
|
|
assert_equals(prefixDuringConstructor, null,
|
|
'prefix should be null during constructor (set after construction per step 5.1.3.9)');
|
|
assert_equals(tagNameDuringConstructor, 'PREFIX-TIMING-EL',
|
|
'tagName during constructor should not include prefix');
|
|
|
|
assert_equals(el.prefix, 'p',
|
|
'prefix should be set after construction');
|
|
assert_equals(el.tagName, 'P:PREFIX-TIMING-EL',
|
|
'tagName after construction should include prefix');
|
|
}, 'Autonomous custom element prefix is set after constructor returns');
|
|
|
|
test(() => {
|
|
let innerPrefix;
|
|
let outerPrefixDuringConstructor;
|
|
|
|
class ReentrantEl extends HTMLElement {
|
|
static callCount = 0;
|
|
constructor() {
|
|
super();
|
|
if (ReentrantEl.callCount++ === 0) {
|
|
// Create another instance via direct construction re-entrantly
|
|
// during outer (createElementNS-initiated) construction.
|
|
const inner = new ReentrantEl();
|
|
innerPrefix = inner.prefix;
|
|
}
|
|
outerPrefixDuringConstructor = this.prefix;
|
|
}
|
|
}
|
|
customElements.define('reentrant-prefix-el', ReentrantEl);
|
|
|
|
const el = document.createElementNS('http://www.w3.org/1999/xhtml', 'r:reentrant-prefix-el');
|
|
|
|
assert_equals(outerPrefixDuringConstructor, null,
|
|
'outer prefix should be null during constructor');
|
|
assert_equals(innerPrefix, null,
|
|
'directly-constructed inner element should not inherit outer prefix');
|
|
assert_equals(el.prefix, 'r',
|
|
'outer element prefix should be set after construction');
|
|
}, 'Reentrant construction does not leak prefix between instances');
|
|
|
|
test(() => {
|
|
let prefixDuringConstructor;
|
|
let outerElement;
|
|
|
|
class ReentrantNSEl extends HTMLElement {
|
|
static callCount = 0;
|
|
constructor() {
|
|
super();
|
|
if (ReentrantNSEl.callCount++ === 0) {
|
|
outerElement = this;
|
|
// Create another instance via createElementNS re-entrantly.
|
|
const inner = document.createElementNS('http://www.w3.org/1999/xhtml', 'q:reentrant-ns-el');
|
|
assert_equals(inner.prefix, 'q', 'inner element created during outer constructor should have its own prefix');
|
|
}
|
|
prefixDuringConstructor = this.prefix;
|
|
}
|
|
}
|
|
customElements.define('reentrant-ns-el', ReentrantNSEl);
|
|
|
|
const el = document.createElementNS('http://www.w3.org/1999/xhtml', 'p:reentrant-ns-el');
|
|
|
|
assert_equals(el.prefix, 'p',
|
|
'outer element should have its own prefix');
|
|
assert_equals(outerElement, el,
|
|
'outerElement reference should match returned element');
|
|
}, 'Nested createElementNS calls do not corrupt prefix state');
|
|
</script>
|
|
</body>
|