custom-element-move-reactions.html (6047B)
1 <!DOCTYPE html> 2 <title>Node.moveBefore custom element reactions</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script> 6 ; 7 </script> 8 9 <body> 10 <section id="section"></section> 11 <script> 12 let index = 0; 13 function unique_element_name() { 14 return `ce-${++index}`; 15 } 16 promise_test(async t => { 17 const ce = document.getElementById("ce"); 18 let reactions = []; 19 const element_name = unique_element_name(); 20 customElements.define(element_name, 21 class MockCustomElement extends HTMLElement { 22 connectedCallback() { reactions.push("connected"); } 23 disconnectedCallback() { reactions.push("disconnected"); } 24 }); 25 const element = document.createElement(element_name); 26 t.add_cleanup(() => element.remove()); 27 document.body.append(element); 28 await Promise.resolve(); 29 reactions = []; 30 document.getElementById("section").moveBefore(element, null); 31 await Promise.resolve(); 32 assert_array_equals(reactions, ["disconnected", "connected"]); 33 }, "the disconnected/connected callbacks should be called when no other callback is defined"); 34 35 promise_test(async t => { 36 const ce = document.getElementById("ce"); 37 let reactions = []; 38 const element_name = unique_element_name(); 39 customElements.define(element_name, 40 class MockCustomElement extends HTMLElement { 41 connectedCallback() { reactions.push(this.isConnected); } 42 disconnectedCallback() { reactions.push(this.isConnected); } 43 }); 44 const element = document.createElement(element_name); 45 t.add_cleanup(() => element.remove()); 46 document.body.append(element); 47 await Promise.resolve(); 48 reactions = []; 49 document.getElementById("section").moveBefore(element, null); 50 await Promise.resolve(); 51 assert_array_equals(reactions, [true, true]); 52 }, "the element should stay connected during the callbacks"); 53 54 promise_test(async t => { 55 const ce = document.getElementById("ce"); 56 let reactions = []; 57 const element_name = unique_element_name(); 58 customElements.define(element_name, 59 class MockCustomElement extends HTMLElement { 60 connectedMoveCallback() { reactions.push("connectedMove"); } 61 connectedCallback() { reactions.push("connected"); } 62 disconnectedCallback() { reactions.push("disconnected"); } 63 }); 64 const element = document.createElement(element_name); 65 t.add_cleanup(() => element.remove()); 66 document.body.append(element); 67 await Promise.resolve(); 68 reactions = []; 69 document.getElementById("section").moveBefore(element, null); 70 await Promise.resolve(); 71 assert_array_equals(reactions, ["connectedMove"]); 72 }, "When connectedMoveCallback is defined, it is called instead of disconnectedCallback/connectedCallback"); 73 74 promise_test(async t => { 75 const ce = document.getElementById("ce"); 76 let reactions = []; 77 const outer_element_name = unique_element_name(); 78 const inner_element_name = unique_element_name(); 79 customElements.define(outer_element_name, 80 class MockCustomElement extends HTMLElement { 81 connectedCallback() { reactions.push("outer connected"); } 82 disconnectedCallback() { reactions.push("outer disconnected"); } 83 }); 84 customElements.define(inner_element_name, 85 class MockCustomElement extends HTMLElement { 86 connectedCallback() { reactions.push("inner connected"); } 87 disconnectedCallback() { reactions.push("inner disconnected"); } 88 }); 89 const outer = document.createElement(outer_element_name); 90 const inner = document.createElement(inner_element_name); 91 t.add_cleanup(() => outer.remove()); 92 outer.append(inner); 93 document.body.append(outer); 94 await Promise.resolve(); 95 reactions = []; 96 document.getElementById("section").moveBefore(outer, null); 97 await Promise.resolve(); 98 assert_array_equals(reactions, ["outer disconnected", "outer connected", "inner disconnected", "inner connected"]); 99 }, "Reactions to atomic move are called in order of element, not in order of operation"); 100 101 promise_test(async t => { 102 const ce = document.getElementById("ce"); 103 let reactions = []; 104 const element_name = unique_element_name(); 105 customElements.define(element_name, 106 class MockCustomElement extends HTMLElement { 107 disconnectedCallback() { reactions.push("disconnected"); } 108 }); 109 const element = document.createElement(element_name); 110 t.add_cleanup(() => element.remove()); 111 document.body.append(element); 112 await Promise.resolve(); 113 reactions = []; 114 document.getElementById("section").moveBefore(element, null); 115 await Promise.resolve(); 116 assert_array_equals(reactions, ["disconnected"]); 117 }, "When connectedCallback is not defined, no crash"); 118 119 promise_test(async t => { 120 const ce = document.getElementById("ce"); 121 let reactions = []; 122 const element_name = unique_element_name(); 123 customElements.define(element_name, 124 class MockCustomElement extends HTMLElement { 125 connectedCallback() { reactions.push("connected"); } 126 }); 127 const element = document.createElement(element_name); 128 t.add_cleanup(() => element.remove()); 129 document.body.append(element); 130 await Promise.resolve(); 131 reactions = []; 132 document.getElementById("section").moveBefore(element, null); 133 await Promise.resolve(); 134 assert_array_equals(reactions, ["connected"]); 135 }, "When disconnectedCallback is not defined, no crash"); 136 </script> 137 </body>