| <!DOCTYPE HTML> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| |
| <div class="container"> |
| <ul id="future_parent" aria-owns="future_child"></ul> |
| </div> |
| |
| <script> |
| test(function(t) { |
| const axFutureParent = accessibilityController.accessibleElementById("future_parent"); |
| assert_equals(axFutureParent.childrenCount, 0); |
| const futureParent = document.getElementById("future_parent"); |
| const child = document.createElement("li"); |
| child.id = "future_child"; |
| assert_equals(axFutureParent.childrenCount, 0, "before appending child"); |
| |
| futureParent.parentElement.appendChild(child); |
| assert_equals(axFutureParent.childrenCount, 1, "after appending child"); |
| assert_array_equals(futureParent.ariaOwnsElements, [child]); |
| |
| child.id = ""; |
| assert_equals(axFutureParent.childrenCount, 0, "after clearing id"); |
| assert_equals(futureParent.ariaOwnsElements, null); |
| |
| child.id = "future_child"; |
| assert_equals(axFutureParent.childrenCount, 1, "after setting id"); |
| assert_array_equals(futureParent.ariaOwnsElements, [child]); |
| |
| futureParent.setAttribute("aria-owns", ""); |
| assert_equals(axFutureParent.childrenCount, 0, "after clearing aria-owns"); |
| assert_equals(futureParent.ariaOwnsElements, null); |
| |
| futureParent.setAttribute("aria-owns", "future_child"); |
| assert_equals(axFutureParent.childrenCount, 1, "after setting aria-oens"); |
| assert_array_equals(futureParent.ariaOwnsElements, [child]); |
| |
| child.style.visibility = 'hidden'; |
| assert_equals(axFutureParent.childrenCount, 1, "after setting hidden"); |
| assert_true(axFutureParent.childAtIndex(0).isIgnored); |
| assert_array_equals(futureParent.ariaOwnsElements, [child]); |
| |
| child.style.visibility = 'visible'; |
| assert_equals(axFutureParent.childrenCount, 1, "after setting visible"); |
| assert_array_equals(futureParent.ariaOwnsElements, [child]); |
| |
| child.remove(); |
| assert_equals(axFutureParent.childrenCount, 0); |
| assert_equals(futureParent.ariaOwnsElements, null); |
| }, "Aria-owns is dynamically recomputed."); |
| </script> |
| |
| <div class="container"> |
| <div id="explicitParent"></div> |
| </div> |
| |
| <script> |
| test(function(t) { |
| const axParent = accessibilityController.accessibleElementById("explicitParent"); |
| const child = document.createElement("li"); |
| |
| // Check element reflection before inserting into the DOM. |
| explicitParent.ariaOwnsElements = [child]; |
| |
| assert_array_equals(explicitParent.ariaOwnsElements, [], "Element is not reflected as was not in valid scope on insertion."); |
| assert_equals(explicitParent.getAttribute("aria-owns"), "", "Content attribute should be set to empty string due to invalid element."); |
| assert_equals(axParent.childrenCount, 0, "Accessible node should have no children."); |
| |
| |
| // Add the element into the DOM, and set the IDL attribute. |
| explicitParent.parentElement.appendChild(child); |
| explicitParent.ariaOwnsElements = [child]; |
| |
| assert_array_equals(explicitParent.ariaOwnsElements, [child], "Element reference is reflected, despite the element having no id"); |
| assert_equals(explicitParent.getAttribute("aria-owns"), "", "Content attribute is empty string, as element has no id"); |
| assert_equals(axParent.childrenCount, 1, "If explicitly set, even without an ID the node should be in the accessibility tree."); |
| |
| child.id = "futureExplicitElement"; |
| const axChild = accessibilityController.accessibleElementById("futureExplicitElement"); |
| |
| assert_array_equals(explicitParent.ariaOwnsElements, [child], "Element has the attr associated element now."); |
| assert_equals(explicitParent.getAttribute("aria-owns"), "", "Content attribute reflects an empty string because the id was missing at the time of setting."); |
| assert_equals(axParent.childrenCount, 1, "After inserting child into DOM and explicitly setting it.") |
| assert_equals(axParent.childAtIndex(0), axChild); |
| |
| // Remove the explicitly set attr by removing the content attribute. |
| explicitParent.removeAttribute("aria-owns"); |
| assert_equals(explicitParent.ariaOwnsElements, null, "Reflected elements should be null since content attribute was removed."); |
| assert_equals(axParent.childrenCount, 0, "Accessible node should have no children since content attribute was removed."); |
| |
| // Set the content attribute. |
| explicitParent.setAttribute("aria-owns", "futureExplicitElement"); |
| assert_equals(axParent.childrenCount, 1, "Accessible node should be updated to have child since content attribute was set"); |
| assert_equals(axParent.childAtIndex(0), axChild); |
| }, "Explicitly set elements are reflected in the AXTree"); |
| </script> |
| |
| <div class="container"> |
| <div id="source1" aria-owns="target1"></div> |
| <div id="target"></div> |
| </div> |
| |
| <script> |
| test(function(t) { |
| const source1 = document.getElementById("source1"); |
| const target = document.getElementById("target"); |
| const axSource1 = accessibilityController.accessibleElementById("source1"); |
| |
| assert_equals(axSource1.childrenCount, 0); |
| |
| target.id = "target1"; |
| assert_equals(axSource1.childrenCount, 1); |
| |
| target.id = "target"; |
| assert_equals(axSource1.childrenCount, 0); |
| }, "Aria-owns is dynamically recomputed (2)."); |
| </script> |
| |
| <div class="container"> |
| <div id="logical_parent" role="group" aria-owns="logical_1 logical_2 logical_3 logical_4"> |
| <div id="logical_3">3</div> |
| <div id="logical_4">4</div> |
| <div id="logical_2">2</div> |
| <div id="logical_1">1</div> |
| </div> |
| </div> |
| |
| <script> |
| test(function(t) |
| { |
| const axLogicalParent = accessibilityController.accessibleElementById("logical_parent"); |
| |
| assert_equals(axLogicalParent.childrenCount, 4); |
| assert_equals(axLogicalParent.childAtIndex(0).childAtIndex(0).name, "1"); |
| assert_equals(axLogicalParent.childAtIndex(1).childAtIndex(0).name, "2"); |
| assert_equals(axLogicalParent.childAtIndex(2).childAtIndex(0).name, "3"); |
| assert_equals(axLogicalParent.childAtIndex(3).childAtIndex(0).name, "4"); |
| |
| document.getElementById("logical_parent").setAttribute( |
| "aria-owns", |
| "logical_2 logical_4 logical_1 logical_3"); |
| |
| assert_equals(axLogicalParent.childrenCount, 4); |
| assert_equals(axLogicalParent.childAtIndex(0).childAtIndex(0).name, "2"); |
| assert_equals(axLogicalParent.childAtIndex(1).childAtIndex(0).name, "4"); |
| assert_equals(axLogicalParent.childAtIndex(2).childAtIndex(0).name, "1"); |
| assert_equals(axLogicalParent.childAtIndex(3).childAtIndex(0).name, "3"); |
| }, "A parent can use aria-owns to reorder its children into a more logical AX ordering."); |
| </script> |
| |
| <div class="container"> |
| <div id="original_parent" role="group" aria-owns="kidnapping_target"></div> |
| <div id="kidnapping_target">Target</div> |
| <div id="kidnapping_parent" role="group"></div> |
| <div id="new_parent" role="group"></div> |
| </div> |
| |
| <script> |
| test(function(t) { |
| const axOriginalParent = accessibilityController.accessibleElementById("original_parent"); |
| const axKidnappingParent = accessibilityController.accessibleElementById("kidnapping_parent"); |
| const axNewParent = accessibilityController.accessibleElementById("new_parent"); |
| assert_equals(axOriginalParent.childrenCount, 1); |
| assert_equals(axOriginalParent.childAtIndex(0).childAtIndex(0).name, "Target"); |
| |
| // The child cannot be "kidnapped" while a valid aria-owns still exists. |
| kidnapping_parent.setAttribute("aria-owns", "kidnapping_target"); |
| assert_equals(axKidnappingParent.childrenCount, 0); |
| assert_equals(axOriginalParent.childrenCount, 1); |
| assert_equals(axOriginalParent.childAtIndex(0).childAtIndex(0).name, "Target"); |
| kidnapping_parent.removeAttribute("aria-owns"); |
| |
| // If the parentage is removed, the child can be owned by something else. |
| original_parent.removeAttribute("aria-owns"); |
| |
| // TODO(meredithl): investigate how to set this attribute before removing it from |
| // the original parent. |
| new_parent.setAttribute("aria-owns", "kidnapping_target"); |
| assert_equals(axNewParent.childrenCount, 1); |
| assert_equals(axNewParent.childAtIndex(0).childAtIndex(0).name, "Target"); |
| }, "An element can be reparented by aria-owns if the original relationship is removed"); |
| </script> |