form-associated-callback.html (8591B)
1 <!DOCTYPE html> 2 <title>formAssociatedCallback, and form IDL attribute of ElementInternals</title> 3 <body> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script> 7 class PreDefined extends HTMLElement { 8 static get formAssociated() { return true; } 9 10 constructor() { 11 super(); 12 this.internals_ = this.attachInternals(); 13 this.formHistory_ = []; 14 } 15 16 formAssociatedCallback(nullableForm) { 17 this.formHistory_.push(nullableForm); 18 } 19 formHistory() { 20 return this.formHistory_; 21 } 22 23 get form() { 24 return this.internals_.form; 25 } 26 } 27 customElements.define('pre-defined', PreDefined); 28 </script> 29 <div id="container"> 30 31 <fieldset id="fs1"> 32 <form id="form1"> 33 <input> 34 <pre-defined id="pd1"></pre-defined> 35 <select></select> 36 </form> 37 </fieldset> 38 39 <fieldset id="fs2"> 40 <pre-defined id="pd2" form="form2"></pre-defined> 41 <form id="form2"> 42 <input> 43 <select></select> 44 </form> 45 </fieldset> 46 <pre-defined id="pd3" form="form2"></pre-defined> 47 48 <table> 49 <fieldset id="fs3"> 50 <form id="form3"> 51 <tr><td><select></select></tr> 52 <tr><td><pre-defined id="pd4"></pre-defined></tr> 53 <tr><td><input></tr> 54 </form> <!-- The end tag is bogus. --> 55 </fieldset> <!-- The end tag is bogus. --> 56 <table> 57 58 </div> 59 60 <script> 61 const $ = document.querySelector.bind(document); 62 63 test(() => { 64 let controls = $('#form1').elements; 65 assert_equals(controls.length, 3); 66 assert_equals(controls[1], $('#pd1'), 'form.elements'); 67 assert_equals($('#pd1').form, $('#form1')); 68 assert_array_equals($('#pd1').formHistory(), [$('#form1')]); 69 assert_equals($('#fs1').elements[1], $('#pd1'), 'fieldset.elements'); 70 71 controls = $('#form2').elements; 72 assert_equals(controls.length, 4); 73 assert_equals(controls[0], $('#pd2'), 'form.elements'); 74 assert_equals(controls[3], $('#pd3')); 75 assert_equals($('#pd2').form, $('#form2')); 76 assert_equals($('#pd3').form, $('#form2')); 77 assert_array_equals($('#pd2').formHistory(), [$('#form2')]); 78 assert_array_equals($('#pd3').formHistory(), [$('#form2')]); 79 controls = $('#fs2').elements; 80 assert_equals(controls.length, 3); 81 assert_equals(controls[0], $('#pd2'), 'fieldset.elements'); 82 83 controls = $('#form3').elements; 84 assert_equals(controls.length, 2); 85 assert_not_equals(controls[1], $('#pd4')); 86 assert_equals($('#fs3').elements.length, 0); 87 }, 'Associate by parser, customized at element creation'); 88 89 test(() => { 90 $('#container').innerHTML = '<fieldset id="fs1"><form id="form1"><input><will-be-defined id="wbd1">' + 91 '</will-be-defined><select></select></form></fieldset>' + 92 '<fieldset id="fs2"><will-be-defined id="wbd2" form="form2"></will-be-defined>' + 93 '<form id="form2"></form></fieldset><will-be-defined id="wbd3" form="form2"></will-be-defined>'; 94 let controls = $('#form1').elements; 95 assert_equals(controls.length, 2); 96 assert_not_equals(controls[1], $('#wbd1')); 97 controls = $('#fs1').elements; 98 assert_equals(controls.length, 2); 99 assert_not_equals(controls[1], $('#wbd1')); 100 101 assert_equals($('#form2').elements.length, 0); 102 assert_equals($('#fs2').elements.length, 0); 103 104 class WillBeDefined extends HTMLElement { 105 static get formAssociated() { return true; } 106 107 constructor() { 108 super(); 109 this.internals_ = this.attachInternals(); 110 this.formHistory_ = []; 111 } 112 113 formAssociatedCallback(nullableForm) { 114 this.formHistory_.push(nullableForm); 115 } 116 formHistory() { 117 return this.formHistory_; 118 } 119 120 get form() { 121 return this.internals_.form; 122 } 123 } 124 customElements.define('will-be-defined', WillBeDefined); 125 customElements.upgrade($('#container')); 126 127 controls = $('#form1').elements; 128 assert_equals(controls.length, 3, 'form.elements.length'); 129 assert_equals(controls[1], $('#wbd1')); 130 assert_equals($('#wbd1').form, $('#form1')); 131 controls = $('#fs1').elements; 132 assert_equals(controls.length, 3, 'fieldset.elements.length'); 133 assert_equals(controls[1], $('#wbd1')); 134 135 controls = $('#form2').elements; 136 assert_equals($('#wbd2').form, $('#form2')); 137 assert_equals($('#wbd3').form, $('#form2')); 138 assert_array_equals($('#wbd2').formHistory(), [$('#form2')]); 139 assert_array_equals($('#wbd3').formHistory(), [$('#form2')]); 140 assert_equals(controls.length, 2, 'form.elements.length'); 141 assert_equals(controls[0], $('#wbd2')); 142 assert_equals(controls[1], $('#wbd3')); 143 controls = $('#fs2').elements; 144 assert_equals(controls.length, 1, 'fieldset.elements.length'); 145 assert_equals(controls[0], $('#wbd2')); 146 }, 'Parsed, connected, then upgraded'); 147 148 test(() => { 149 $('#container').innerHTML = '<fieldset id="fs1"><form id="form1"><input><pre-defined id="pd1">' + 150 '</pre-defined><select></select></form></fieldset>' + 151 '<fieldset id="fs2"><pre-defined id="pd2" form="form2"></pre-defined>' + 152 '<form id="form2"></form></fieldset><pre-defined id="pd3" form="form2"></pre-defined>'; 153 154 const pd1 = $('#pd1'); 155 assert_equals($('#form1').elements.length, 3, 'form.elements.length before removal'); 156 assert_equals($('#fs1').elements.length, 3, 'fildset.elements.length before removal'); 157 pd1.remove(); 158 assert_equals(pd1.form, null); 159 assert_array_equals(pd1.formHistory(), [$('#form1'), null]); 160 assert_equals($('#form1').elements.length, 2, 'form.elements.length after removal'); 161 assert_equals($('#fs1').elements.length, 2, 'fildset.elements.length after removal'); 162 163 const pd2 = $('#pd2'); 164 const pd3 = $('#pd3'); 165 assert_equals($('#form2').elements.length, 2, 'form.elements.length before removal'); 166 assert_equals($('#fs2').elements.length, 1, 'fieldset.elements.length before removal'); 167 pd2.remove(); 168 pd3.remove(); 169 assert_equals(pd2.form, null); 170 assert_equals(pd3.form, null); 171 assert_array_equals(pd2.formHistory(), [$('#form2'), null]); 172 assert_array_equals(pd3.formHistory(), [$('#form2'), null]); 173 assert_equals($('#form2').elements.length, 0, 'form.elements.length after removal'); 174 assert_equals($('#fs2').elements.length, 0, 'fieldset.elements.length after removal'); 175 }, 'Disassociation'); 176 177 test(() => { 178 $('#container').innerHTML = '<form id="form1"></form>' + 179 '<pre-defined id="pd1"></pre-defined><form id="form2">' + 180 '</form><form id="form3"></form>'; 181 const pd1 = $('#pd1'); 182 const form1 = $('#form1'); 183 const form2 = $('#form2'); 184 const form3 = $('#form3'); 185 assert_equals(pd1.form, null); 186 assert_array_equals(pd1.formHistory(), []); 187 188 pd1.setAttribute('form', 'form1'); 189 assert_equals(pd1.form, form1); 190 assert_array_equals(pd1.formHistory(), [form1]); 191 192 pd1.setAttribute('form', 'invalid'); 193 assert_equals(pd1.form, null); 194 assert_array_equals(pd1.formHistory(), [form1, null]); 195 196 pd1.setAttribute('form', 'form2'); 197 assert_equals(pd1.form, form2); 198 assert_array_equals(pd1.formHistory(), [form1, null, form2]); 199 200 pd1.setAttribute('form', 'form3'); 201 assert_equals(pd1.form, form3); 202 assert_array_equals(pd1.formHistory(), [form1, null, form2, form3]); 203 204 $('#container').innerHTML = ''; 205 assert_equals(pd1.form, null); 206 assert_array_equals(pd1.formHistory(), [form1, null, form2, form3, null]); 207 }, 'Updating "form" content attribute'); 208 209 test(() => { 210 $('#container').innerHTML = '<form></form>' + 211 '<pre-defined id="pd1" form="target"></pre-defined>' + 212 '<form></form><form></form>'; 213 const pd1 = $('#pd1'); 214 const [form1, form2, form3] = document.forms; 215 assert_equals(pd1.form, null); 216 assert_array_equals(pd1.formHistory(), []); 217 218 // The form1 is the only form element with id='target'. 219 form1.setAttribute('id', 'target'); 220 assert_equals(pd1.form, form1); 221 assert_array_equals(pd1.formHistory(), [form1]); 222 223 // The first form element with id='target' is still form1. 224 form3.setAttribute('id', 'target'); 225 assert_equals(pd1.form, form1); 226 assert_array_equals(pd1.formHistory(), [form1]); 227 228 // The form3 is the only form element with id='target'. 229 form1.removeAttribute('id'); 230 assert_equals(pd1.form, form3); 231 assert_array_equals(pd1.formHistory(), [form1, form3]); 232 233 // The first form element with id='target' is form2 now. 234 form2.setAttribute('id', 'target'); 235 assert_equals(pd1.form, form2); 236 assert_array_equals(pd1.formHistory(), [form1, form3, form2]); 237 238 // The form2 is the only form element with id='target'. 239 form3.removeAttribute('id'); 240 assert_equals(pd1.form, form2); 241 assert_array_equals(pd1.formHistory(), [form1, form3, form2]); 242 243 // No form element has id='target'. 244 form2.removeAttribute('id'); 245 assert_equals(pd1.form, null); 246 assert_array_equals(pd1.formHistory(), [form1, form3, form2, null]); 247 }, 'Updating "id" attribute of form element'); 248 </script> 249 </body>