toggleEvent.html (7958B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>The details element</title> 4 <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org"> 5 <link rel=help href="https://html.spec.whatwg.org/multipage/#the-details-element"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <div id="log"></div> 9 <details id=details1> 10 <summary>Lorem ipsum</summary> 11 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 12 </details> 13 <details id=details2> 14 <summary>Lorem ipsum</summary> 15 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 16 </details> 17 <details id=details3 style="display:none;"> 18 <summary>Lorem ipsum</summary> 19 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 20 </details> 21 <details id=details4> 22 </details> 23 <details id=details6> 24 <summary>Lorem ipsum</summary> 25 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 26 </details> 27 <details id=details7> 28 <summary>Lorem ipsum</summary> 29 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 30 </details> 31 <details id=details8> 32 <summary>Lorem ipsum</summary> 33 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 34 </details> 35 <script> 36 window.details9TogglePromise = new Promise(resolve => { 37 window.details9TogglePromiseResolver = resolve; 38 }); 39 </script> 40 <details id=details9 ontoggle="window.details9TogglePromiseResolver()" open> 41 <summary>Lorem ipsum</summary> 42 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 43 </details> 44 <details id=details10> 45 <summary>Lorem ipsum</summary> 46 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 47 </details> 48 <script> 49 var t1 = async_test("Adding open to 'details' should fire a toggle event at the 'details' element, with 'oldState: closed' and 'newState: open'"), 50 t2 = async_test("Adding open to 'details' and then removing open from that 'details' should fire only one toggle event at the 'details' element, with 'oldState: closed' and 'newState: closed'"), 51 t3 = async_test("Adding open to 'details' (display:none) should fire a toggle event at the 'details' element, with 'oldState: closed' and 'newState: open'"), 52 t4 = async_test("Adding open to 'details' (no children) should fire a toggle event at the 'details' element, with 'oldState: closed' and 'newState: open'"), 53 t6 = async_test("Adding open to 'details' and then removing open from that 'details' and then again adding open to that 'details' should fire only one toggle event at the 'details' element, with 'oldState: closed' and 'newState: closed'"), 54 t7 = async_test("Adding open to 'details' using setAttribute('open', '') should fire a toggle event at the 'details' element, with 'oldState: closed' and 'newState: open'"), 55 t8 = async_test("Adding open to 'details' and then calling removeAttribute('open') should fire only one toggle event at the 'details' element, with 'oldState: closed' and 'newState: closed'"), 56 t9 = async_test("Setting open=true on an opened 'details' element should not fire a toggle event at the 'details' element"), 57 t10 = async_test("Setting open=false on a closed 'details' element should not fire a toggle event at the 'details' element"), 58 59 details1 = document.getElementById('details1'), 60 details2 = document.getElementById('details2'), 61 details3 = document.getElementById('details3'), 62 details4 = document.getElementById('details4'), 63 details6 = document.getElementById('details6'), 64 details7 = document.getElementById('details7'), 65 details8 = document.getElementById('details8'), 66 details9 = document.getElementById('details9'), 67 details10 = document.getElementById('details10'), 68 loop=false; 69 70 function testEvent(evt) { 71 assert_true(evt.isTrusted, "event is trusted"); 72 assert_false(evt.bubbles, "event doesn't bubble"); 73 assert_false(evt.cancelable, "event is not cancelable"); 74 assert_equals(Object.getPrototypeOf(evt), ToggleEvent.prototype, "Prototype of toggle event is ToggleEvent.prototype"); 75 } 76 77 details1.ontoggle = t1.step_func_done(function(evt) { 78 assert_equals(evt.oldState, "closed"); 79 assert_equals(evt.newState, "open"); 80 assert_true(details1.open); 81 testEvent(evt) 82 }); 83 details1.open = true; // opens details1 84 85 details2.ontoggle = t2.step_func_done(function(evt) { 86 assert_equals(evt.oldState, "closed"); 87 assert_equals(evt.newState, "closed"); 88 assert_false(details2.open); 89 testEvent(evt); 90 }); 91 details2.open = true; 92 details2.open = false; // closes details2 93 94 details3.ontoggle = t3.step_func_done(function(evt) { 95 assert_equals(evt.oldState, "closed"); 96 assert_equals(evt.newState, "open"); 97 assert_true(details3.open); 98 testEvent(evt); 99 }); 100 details3.open = true; // opens details3 101 102 details4.ontoggle = t4.step_func_done(function(evt) { 103 assert_equals(evt.oldState, "closed"); 104 assert_equals(evt.newState, "open"); 105 assert_true(details4.open); 106 testEvent(evt); 107 }); 108 details4.open = true; // opens details4 109 110 async_test(function(t) { 111 var details5 = document.createElement("details"); 112 details5.ontoggle = t.step_func_done(function(evt) { 113 assert_equals(evt.oldState, "closed"); 114 assert_equals(evt.newState, "open"); 115 assert_true(details5.open); 116 testEvent(evt); 117 }) 118 details5.open = true; 119 }, "Adding open to 'details' (not in the document) should fire a toggle event at the 'details' element, with 'oldState: closed' and 'newState: open'"); 120 121 details6.open = true; 122 details6.open = false; 123 details6.ontoggle = t6.step_func(function(evt) { 124 if (loop) { 125 assert_unreached("toggle event fired twice"); 126 } else { 127 assert_equals(evt.oldState, "closed"); 128 assert_equals(evt.newState, "closed"); 129 loop = true; 130 } 131 }); 132 t6.step_timeout(function() { 133 assert_true(loop); 134 t6.done(); 135 }, 0); 136 137 details7.ontoggle = t7.step_func_done(function(evt) { 138 assert_equals(evt.oldState, "closed"); 139 assert_equals(evt.newState, "open"); 140 assert_true(details7.open); 141 testEvent(evt) 142 }); 143 details7.setAttribute('open', ''); // opens details7 144 145 details8.ontoggle = t8.step_func_done(function(evt) { 146 assert_equals(evt.oldState, "closed"); 147 assert_equals(evt.newState, "closed"); 148 assert_false(details8.open); 149 testEvent(evt) 150 }); 151 details8.open = true; 152 details8.removeAttribute('open'); // closes details8 153 154 window.details9TogglePromise.then(t9.step_func(() => { 155 // The toggle event should be fired once when declaring details9 with open 156 // attribute. 157 details9.ontoggle = t9.step_func(() => { 158 assert_unreached("toggle event fired twice on opened details element"); 159 }); 160 // setting open=true on details9 should not fire another event since it is 161 // already open. 162 details9.open = true; 163 t9.step_timeout(() => { 164 assert_true(details9.open); 165 t9.done(); 166 }); 167 })); 168 169 details10.ontoggle = t10.step_func_done(function(evt) { 170 assert_unreached("toggle event fired on closed details element"); 171 }); 172 details10.open = false; // closes details10 173 t10.step_timeout(function() { 174 assert_false(details10.open); 175 t10.done(); 176 }, 0); 177 178 async_test(function(t) { 179 new DOMParser().parseFromString("<details open>", "text/html").querySelector("details").ontoggle = t.step_func_done(function(e) { 180 assert_true(e.target.open); 181 }); 182 }, "Setting open from the parser fires a toggle event"); 183 </script>