Files
browser/src/browser/tests/custom_elements/constructor.html
Karl Seguin 74c0d55a6c Fix cloning custom element with constructor which attaches the element
This is a follow up to ca0f77bdee that applies
the same fix to all places where cloneNode is used and then the cloned element
is inserted. A helper was added more of a means of documentation than to DRY
up the code.
2026-03-06 17:38:16 +08:00

131 lines
3.8 KiB
HTML

<!DOCTYPE html>
<script src="../testing.js"></script>
<script id="constructor">
{
let constructorCalled = false;
let constructorThis = null;
class MyElement extends HTMLElement {
constructor() {
super();
constructorCalled = true;
constructorThis = this;
this.customProperty = 'initialized';
}
}
customElements.define('my-element', MyElement);
const el = document.createElement('my-element');
testing.expectEqual(true, constructorCalled);
testing.expectEqual(el, constructorThis);
testing.expectEqual('initialized', el.customProperty);
}
{
class CounterElement extends HTMLElement {
constructor() {
super();
this.count = 0;
}
increment() {
this.count++;
}
}
customElements.define('counter-element', CounterElement);
const counter = document.createElement('counter-element');
testing.expectEqual(0, counter.count);
counter.increment();
testing.expectEqual(1, counter.count);
counter.increment();
testing.expectEqual(2, counter.count);
}
{
class NoConstructorElement extends HTMLElement {}
customElements.define('no-constructor-element', NoConstructorElement);
const el = document.createElement('no-constructor-element');
testing.expectEqual('NO-CONSTRUCTOR-ELEMENT', el.tagName);
}
</script>
<div id=clone_container></div>
<script id=clone>
{
let calls = 0;
class MyCloneElementA extends HTMLElement {
constructor() {
super();
calls += 1;
$('#clone_container').appendChild(this);
}
}
customElements.define('my-clone_element_a', MyCloneElementA);
const original = document.createElement('my-clone_element_a');
$('#clone_container').cloneNode(true);
testing.expectEqual(2, calls);
}
</script>
<div id=fragment_clone_container></div>
<script id=clone_fragment>
{
let calls = 0;
class MyFragmentCloneElement extends HTMLElement {
constructor() {
super();
calls += 1;
$('#fragment_clone_container').appendChild(this);
}
}
customElements.define('my-fragment-clone-element', MyFragmentCloneElement);
// Create a DocumentFragment with a custom element
const fragment = document.createDocumentFragment();
const customEl = document.createElement('my-fragment-clone-element');
fragment.appendChild(customEl);
// Clone the fragment - this should trigger the crash
// because the constructor will attach the element during cloning
const clonedFragment = fragment.cloneNode(true);
testing.expectEqual(2, calls);
}
</script>
<div id=range_clone_container></div>
<script id=clone_range>
{
let calls = 0;
class MyRangeCloneElement extends HTMLElement {
constructor() {
super();
calls += 1;
$('#range_clone_container').appendChild(this);
}
}
customElements.define('my-range-clone-element', MyRangeCloneElement);
// Create a container with a custom element
const container = document.createElement('div');
const customEl = document.createElement('my-range-clone-element');
container.appendChild(customEl);
// Create a range that includes the custom element
const range = document.createRange();
range.selectNodeContents(container);
// Clone the range contents - this should trigger the crash
// because the constructor will attach the element during cloning
const clonedContents = range.cloneContents();
testing.expectEqual(2, calls);
}
</script>