form-reset-callback.html (3077B)
1 <!DOCTYPE html> 2 <body> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script> 6 class MyControl extends HTMLElement { 7 static get formAssociated() { return true; } 8 9 constructor() { 10 super(); 11 this.resetCalled_ = false; 12 } 13 14 formResetCallback() { 15 this.resetCalled_ = true; 16 if (this.outputElement_) { 17 this.outputValueDuringResetCallback_ = this.outputElement_.value; 18 } 19 } 20 get resetCalled() { return this.resetCalled_; } 21 22 // This is only used in a single test below; the idea is this: before the form 23 // gets reset (i.e., before `formResetCallback()` is queued and run by the 24 // platform), we assign an `HTMLOutputElement` whose value we record *while* 25 // `formResetCallback()` runs. This lets the test verify that built-in form 26 // controls are reset *before* custom element `formResetCallback()`s are run 27 // with custom element reaction timing, at the very end of the form reset 28 // process. 29 set outputToObserve(output) { 30 this.outputElement_ = output; 31 } 32 get outputElementValueDuringResetCallback() { 33 return this.outputValueDuringResetCallback_; 34 } 35 } 36 customElements.define('my-control', MyControl); 37 38 test(() => { 39 document.body.insertAdjacentHTML('beforeend', 40 '<form><my-control></my-control></form>'); 41 let form = document.body.lastChild; 42 let custom = form.firstChild; 43 form.reset(); 44 assert_true(custom.resetCalled); 45 }, 'form.reset() should trigger formResetCallback'); 46 47 test(() => { 48 document.body.insertAdjacentHTML('beforeend', 49 '<form><my-control></my-control><output>default</output></form>'); 50 let form = document.body.lastChild; 51 let custom = form.firstChild; 52 let output = form.lastChild; 53 output.value = 'updated'; 54 55 // This is the `HTMLOutputElement` that `custom` will record the `value` of, 56 // when `custom`'s `formResetCallback()` runs. 57 custom.outputToObserve = output; 58 59 // Reset the form. 60 assert_false(custom.resetCalled, 61 "formResetCallback is not called before the form is reset"); 62 form.reset(); 63 assert_true(custom.resetCalled, "formResetCallback is called " + 64 "synchronously after the form is reset"); 65 assert_equals(custom.outputElementValueDuringResetCallback, "default", 66 "formResetCallback() runs *after* built-in form control reset " + 67 "algorithms run, and can observe their effects"); 68 }, 'form.reset(): formResetCallback is called synchronously at the end of ' + 69 'form reset, with custom element reaction timing, *after* built-in form ' + 70 'control reset algorithms run.'); 71 72 promise_test(() => { 73 document.body.insertAdjacentHTML('beforeend', 74 '<form><my-control></my-control><input type=reset></form>'); 75 let form = document.body.lastChild; 76 let custom = form.firstChild; 77 let resetButton = form.lastChild; 78 assert_false(custom.resetCalled); 79 resetButton.click(); 80 assert_false(custom.resetCalled); 81 return Promise.resolve().then(() => assert_true(custom.resetCalled)); 82 }, 'Clicking a reset button invokes formResetCallback in a microtask'); 83 </script> 84 </body>