aria-element-reflection-disconnected.html (3177B)
1 <!DOCTYPE HTML> 2 <meta charset="utf-8" /> 3 <link rel=help href="https://html.spec.whatwg.org/#attr-associated-element"> 4 <link rel="author" href="masonf@chromium.org"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 8 <div id=single_element> 9 <input aria-activedescendant=foo> 10 <p id=foo></p> 11 </div> 12 13 <div id=array> 14 <input aria-describedby="foo1 foo2"> 15 <div id=targets> 16 <p id=foo1></p> 17 <p id=foo2></p> 18 </div> 19 </div> 20 21 <script> 22 function isIterable(obj) { 23 if (obj === null) 24 return false; 25 return typeof obj[Symbol.iterator] === 'function'; 26 } 27 function toSet(elementOrList) { 28 if (!isIterable(elementOrList)) { 29 return new Set([elementOrList]); 30 } 31 return new Set(elementOrList); 32 } 33 function assert_equal_elements(arr1, arr2, msg) { 34 msg = msg || "Arrays not equal"; 35 arr1 = toSet(arr1); 36 arr2 = toSet(arr2); 37 assert_true(arr1.size === arr2.size && 38 [...arr1].every((x) => arr2.has(x)), msg); 39 } 40 function single_test(container, targets, contentAttr, idlAttr, isSingleTarget) { 41 // Start with idref-based reference: 42 const el = container.querySelector('input'); 43 assert_true(el.getAttribute(contentAttr) != null && el.getAttribute(contentAttr) != '','Should start with idref attribute'); 44 assert_equal_elements(el[idlAttr],targets); 45 container.remove(); 46 assert_equal_elements(el[idlAttr],targets,'idrefs should continue to work when target is disconnected'); 47 document.body.appendChild(container); 48 assert_equal_elements(el[idlAttr],targets,'functional when reconnected'); 49 50 // Now set up an attr-associated element: 51 el[idlAttr] = isSingleTarget ? targets[0] : targets; 52 assert_equal_elements(el[idlAttr],targets); 53 assert_equals(el.getAttribute(contentAttr),'','Content attribute is present but empty'); 54 container.remove(); 55 assert_equal_elements(el[idlAttr],targets,'attr-associated element still functional'); 56 assert_equals(el.getAttribute(contentAttr),'','Attribute still blank'); 57 document.body.appendChild(container); 58 assert_equal_elements(el[idlAttr],targets,'still functional when reconnected'); 59 60 // Sanity check: 61 el.removeAttribute(contentAttr); 62 assert_equal_elements(el[idlAttr],null); 63 assert_equals(el.getAttribute(contentAttr),null); 64 container.remove(); 65 assert_equal_elements(el[idlAttr],null); 66 assert_equals(el.getAttribute(contentAttr),null); 67 document.body.appendChild(container); 68 } 69 70 test(() => { 71 const container = document.getElementById('single_element'); 72 const targets = [container.querySelector('#foo')]; 73 single_test(container, targets, 'aria-activedescendant', 'ariaActiveDescendantElement', true); 74 },'Element references should stay valid when content is disconnected (single element)'); 75 76 test(() => { 77 const container = document.getElementById('array'); 78 const targets = Array.from(container.querySelector('#targets').children); 79 single_test(container, targets, 'aria-describedby', 'ariaDescribedByElements', false); 80 },'Element references should stay valid when content is disconnected (element array)'); 81 </script>