blob: b5e84d036da2d1d01f128771aba6230374338ee8 [file] [log] [blame]
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
class PreDefined extends HTMLElement {
static get formAssociated() { return true; }
constructor() {
super();
this.internals_ = this.attachInternals();
this.formHistory_ = [];
}
restoreValueCallback(v) {}
formAssociatedCallback(nullableForm) {
this.formHistory_.push(nullableForm);
}
formHistory() {
return this.formHistory_;
}
get form() {
return this.internals_.form;
}
}
customElements.define('pre-defined', PreDefined);
</script>
<div id="container">
<fieldset id="fs1">
<form id="form1">
<input>
<pre-defined id="pd1"></pre-defined>
<select></select>
</form>
</fieldset>
<fieldset id="fs2">
<pre-defined id="pd2" form="form2"></pre-defined>
<form id="form2">
<input>
<select></select>
</form>
</fieldset>
<pre-defined id="pd3" form="form2"></pre-defined>
<table>
<fieldset id="fs3">
<form id="form3">
<tr><td><select></select></tr>
<tr><td><pre-defined id="pd4"></pre-defined></tr>
<tr><td><input></tr>
</form> <!-- The end tag is bogus. -->
</fieldset> <!-- The end tag is bogus. -->
<table>
</div>
<script>
const $ = document.querySelector.bind(document);
test(() => {
class MyControl extends HTMLElement {
static get formAssociated() { return true; }
}
assert_throws("TypeMismatchError", () => { customElements.define('my-control', MyControl) });
assert_throws("TypeMismatchError", () => { customElements.define('my-control2', class extends MyControl {}); });
}, 'define() requires restoreValueCallback');
test(() => {
class MyControlBase extends HTMLElement {
static get formAssociated() { return true; }
restoreValueCallback(v) { }
}
class MyControlDerived extends MyControlBase {}
try {
customElements.define('my-control-derived', MyControlDerived);
} catch (exception) {
assert_unreached('define() should not throw anything');
}
}, 'define() accepts restoreValueCallback on a base class');
test(() => {
let controls = $('#form1').elements;
assert_equals(controls.length, 3);
assert_equals(controls[1], $('#pd1'), 'form.elements');
assert_equals($('#pd1').form, $('#form1'));
assert_array_equals($('#pd1').formHistory(), [$('#form1')]);
assert_equals($('#fs1').elements[1], $('#pd1'), 'fieldset.elements');
controls = $('#form2').elements;
assert_equals(controls.length, 4);
assert_equals(controls[0], $('#pd2'), 'form.elements');
assert_equals(controls[3], $('#pd3'));
assert_equals($('#pd2').form, $('#form2'));
assert_equals($('#pd3').form, $('#form2'));
assert_array_equals($('#pd2').formHistory(), [$('#form2')]);
assert_array_equals($('#pd3').formHistory(), [$('#form2')]);
controls = $('#fs2').elements;
assert_equals(controls.length, 3);
assert_equals(controls[0], $('#pd2'), 'fieldset.elements');
controls = $('#form3').elements;
assert_equals(controls.length, 2);
assert_not_equals(controls[1], $('#pd4'));
assert_equals($('#fs3').elements.length, 0);
}, 'Associate by parser, customized at element creation');
test(() => {
$('#container').innerHTML = '<fieldset id="fs1"><form id="form1"><input><will-be-defined id="wbd1">' +
'</will-be-defined><select></select></form></fieldset>' +
'<fieldset id="fs2"><will-be-defined id="wbd2" form="form2"></will-be-defined>' +
'<form id="form2"></form></fieldset><will-be-defined id="wbd3" form="form2"></will-be-defined>';
let controls = $('#form1').elements;
assert_equals(controls.length, 2);
assert_not_equals(controls[1], $('#wbd1'));
controls = $('#fs1').elements;
assert_equals(controls.length, 2);
assert_not_equals(controls[1], $('#wbd1'));
assert_equals($('#form2').elements.length, 0);
assert_equals($('#fs2').elements.length, 0);
class WillBeDefined extends HTMLElement {
static get formAssociated() { return true; }
constructor() {
super();
this.internals_ = this.attachInternals();
this.formHistory_ = [];
}
restoreValueCallback(v) {}
formAssociatedCallback(nullableForm) {
this.formHistory_.push(nullableForm);
}
formHistory() {
return this.formHistory_;
}
get form() {
return this.internals_.form;
}
}
customElements.define('will-be-defined', WillBeDefined);
customElements.upgrade(container);
controls = $('#form1').elements;
assert_equals(controls.length, 3, 'form.elements.length');
assert_equals(controls[1], $('#wbd1'));
assert_equals($('#wbd1').form, $('#form1'));
controls = $('#fs1').elements;
assert_equals(controls.length, 3, 'fieldset.elements.length');
assert_equals(controls[1], $('#wbd1'));
controls = $('#form2').elements;
assert_equals($('#wbd2').form, $('#form2'));
assert_equals($('#wbd3').form, $('#form2'));
assert_array_equals($('#wbd2').formHistory(), [$('#form2')]);
assert_array_equals($('#wbd3').formHistory(), [$('#form2')]);
assert_equals(controls.length, 2, 'form.elements.length');
assert_equals(controls[0], $('#wbd2'));
assert_equals(controls[1], $('#wbd3'));
controls = $('#fs2').elements;
assert_equals(controls.length, 1, 'fieldset.elements.length');
assert_equals(controls[0], $('#wbd2'));
}, 'Parsed, connected, then upgraded');
test(() => {
$('#container').innerHTML = '<fieldset id="fs1"><form id="form1"><input><pre-defined id="pd1">' +
'</pre-defined><select></select></form></fieldset>' +
'<fieldset id="fs2"><pre-defined id="pd2" form="form2"></pre-defined>' +
'<form id="form2"></form></fieldset><pre-defined id="pd3" form="form2"></pre-defined>';
const pd1 = $('#pd1');
assert_equals($('#form1').elements.length, 3, 'form.elements.length before removal');
assert_equals($('#fs1').elements.length, 3, 'fildset.elements.length before removal');
pd1.remove();
assert_equals(pd1.form, null);
assert_array_equals(pd1.formHistory(), [$('#form1'), null]);
assert_equals($('#form1').elements.length, 2, 'form.elements.length after removal');
assert_equals($('#fs1').elements.length, 2, 'fildset.elements.length after removal');
const pd2 = $('#pd2');
const pd3 = $('#pd3');
assert_equals($('#form2').elements.length, 2, 'form.elements.length before removal');
assert_equals($('#fs2').elements.length, 1, 'fieldset.elements.length before removal');
pd2.remove();
pd3.remove();
assert_equals(pd2.form, null);
assert_equals(pd3.form, null);
assert_array_equals(pd2.formHistory(), [$('#form2'), null]);
assert_array_equals(pd3.formHistory(), [$('#form2'), null]);
assert_equals($('#form2').elements.length, 0, 'form.elements.length after removal');
assert_equals($('#fs2').elements.length, 0, 'fieldset.elements.length after removal');
}, 'Disassociation');
test(() => {
$('#container').innerHTML = '<form id="form1"></form>' +
'<pre-defined id="pd1"></pre-defined><form id="form2"></form>';
const pd1 = $('#pd1');
const form1 = $('#form1');
const form2 = $('#form2');
assert_equals(pd1.form, null);
pd1.setAttribute('form', 'form1');
assert_equals(pd1.form, form1);
pd1.setAttribute('form', 'form2');
assert_equals(pd1.form, form2);
$('#container').innerHTML = '';
assert_equals(pd1.form, null);
}, 'Updating "form" content attribute');
</script>