diff --git a/testing/web-platform/tests/custom-elements/reactions/AriaMixin-element-attributes.html b/testing/web-platform/tests/custom-elements/reactions/AriaMixin-element-attributes.html index b8f14273b80c5..09e62b2d39c5e 100644 --- a/testing/web-platform/tests/custom-elements/reactions/AriaMixin-element-attributes.html +++ b/testing/web-platform/tests/custom-elements/reactions/AriaMixin-element-attributes.html @@ -16,7 +16,7 @@ <div id="parentElement"></div> <script> -function testElementReflectAttribute(jsAttributeName, contentAttributeName, validValue1, contentValue1, validValue2, contentValue2, name, getParentElement) { +function testElementReflectAttribute(jsAttributeName, contentAttributeName, validValue1, validValue2, name, getParentElement) { test(function () { let element = define_new_custom_element([contentAttributeName]); let instance = document.createElement(element.name); @@ -27,7 +27,7 @@ let logEntries = element.takeLog(); assert_array_equals(logEntries.types(), ['attributeChanged']); - assert_attribute_log_entry(logEntries.last(), {name: contentAttributeName, oldValue: null, newValue: contentValue1, namespace: null}); + assert_attribute_log_entry(logEntries.last(), {name: contentAttributeName, oldValue: null, newValue: "", namespace: null}); }, name + ' must enqueue an attributeChanged reaction when adding ' + contentAttributeName + ' content attribute'); test(function () { @@ -39,7 +39,7 @@ instance[jsAttributeName] = validValue2; var logEntries = element.takeLog(); assert_array_equals(logEntries.types(), ['attributeChanged']); - assert_attribute_log_entry(logEntries.last(), {name: contentAttributeName, oldValue: contentValue1, newValue: contentValue2, namespace: null}); + assert_attribute_log_entry(logEntries.last(), {name: contentAttributeName, oldValue: "", newValue: "", namespace: null}); }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute'); } @@ -51,14 +51,14 @@ dummy2.id = 'dummy2'; document.body.appendChild(dummy2); -testElementReflectAttribute('ariaActiveDescendantElement', 'aria-activedescendant', dummy1, 'dummy1', dummy2, 'dummy2', 'ariaActiveDescendantElement in Element'); -testElementReflectAttribute('ariaControlsElements', 'aria-controls', [dummy1], 'dummy1', [dummy2], 'dummy2', 'ariaControlsElements in Element'); -testElementReflectAttribute('ariaDescribedByElements', 'aria-describedby', [dummy1], 'dummy1', [dummy2], 'dummy2', 'ariaDescribedByElements in Element'); -testElementReflectAttribute('ariaDetailsElements', 'aria-details', [dummy1], 'dummy1', [dummy2], 'dummy2', 'ariaDetailsElements in Element'); -testElementReflectAttribute('ariaErrorMessageElement', 'aria-errormessage', dummy1, 'dummy1', dummy2, 'dummy2', 'ariaErrorMessageElement in Element'); -testElementReflectAttribute('ariaFlowToElements', 'aria-flowto', [dummy1], 'dummy1', [dummy2], 'dummy2', 'ariaFlowToElements in Element'); -testElementReflectAttribute('ariaLabelledByElements', 'aria-labelledby', [dummy1], 'dummy1', [dummy2], 'dummy2', 'ariaLabelledByElements in Element') -testElementReflectAttribute('ariaOwnsElements', 'aria-owns', [dummy1], 'dummy1', [dummy2], 'dummy2', 'ariaOwnsElements in Element') +testElementReflectAttribute('ariaActiveDescendantElement', 'aria-activedescendant', dummy1, dummy2, 'ariaActiveDescendantElement in Element'); +testElementReflectAttribute('ariaControlsElements', 'aria-controls', [dummy1], [dummy2], 'ariaControlsElements in Element'); +testElementReflectAttribute('ariaDescribedByElements', 'aria-describedby', [dummy1], [dummy2], 'ariaDescribedByElements in Element'); +testElementReflectAttribute('ariaDetailsElements', 'aria-details', [dummy1], [dummy2], 'ariaDetailsElements in Element'); +testElementReflectAttribute('ariaErrorMessageElement', 'aria-errormessage', dummy1, dummy2, 'ariaErrorMessageElement in Element'); +testElementReflectAttribute('ariaFlowToElements', 'aria-flowto', [dummy1], [dummy2], 'ariaFlowToElements in Element'); +testElementReflectAttribute('ariaLabelledByElements', 'aria-labelledby', [dummy1], [dummy2], 'ariaLabelledByElements in Element') +testElementReflectAttribute('ariaOwnsElements', 'aria-owns', [dummy1], [dummy2], 'ariaOwnsElements in Element') </script> </body> diff --git a/testing/web-platform/tests/html/dom/aria-element-reflection.html b/testing/web-platform/tests/html/dom/aria-element-reflection.html index 742c01557dc83..991f7c7aa12d8 100644 --- a/testing/web-platform/tests/html/dom/aria-element-reflection.html +++ b/testing/web-platform/tests/html/dom/aria-element-reflection.html @@ -31,10 +31,10 @@ assert_equals(parentListbox.ariaActiveDescendantElement, i2, "setting the content attribute updates the element reference."); assert_equals(parentListbox.ariaActiveDescendantElement, parentListbox.ariaActiveDescendantElement, "check idl attribute caching after update."); - // Setting the element reference should be reflected in the content attribute. + // Setting the element reference should set the empty string in the content attribute. parentListbox.ariaActiveDescendantElement = i1; assert_equals(parentListbox.ariaActiveDescendantElement, i1, "getter should return the right element reference."); - assert_equals(parentListbox.getAttribute("aria-activedescendant"), "i1", "content attribute should reflect the element reference."); + assert_equals(parentListbox.getAttribute("aria-activedescendant"), "", "content attribute should be empty."); // Both content and IDL attribute should be nullable. parentListbox.ariaActiveDescendantElement = null; @@ -123,7 +123,8 @@ <script> test(function(t) { startTime.ariaErrorMessageElement = errorMessage; - assert_equals(startTime.getAttribute("aria-errormessage"), "errorMessage"); + assert_equals(startTime.getAttribute("aria-errormessage"), ""); + assert_equals(startTime.ariaErrorMessageElement, errorMessage); startTime.ariaErrorMessageElement = null; assert_equals(startTime.ariaErrorMessageElement, null, "blah"); @@ -151,10 +152,12 @@ test(function(t) { assert_array_equals(passwordField.ariaDetailsElements, []); passwordField.ariaDetailsElements = [ listItem1 ]; - assert_equals(passwordField.getAttribute("aria-details"), "listItem1"); + assert_equals(passwordField.getAttribute("aria-details"), ""); + assert_array_equals(passwordField.ariaDetailsElements, [ listItem1 ]); passwordField.ariaDetailsElements = [ listItem2 ]; - assert_equals(passwordField.getAttribute("aria-details"), "listItem2"); + assert_equals(passwordField.getAttribute("aria-details"), ""); + assert_array_equals(passwordField.ariaDetailsElements, [ listItem2 ]); }, "aria-details"); </script> @@ -182,14 +185,14 @@ // Deleting an element set via the IDL attribute. deletionParent.ariaActiveDescendantElement = idlAttrElement; - assert_equals(deletionParent.getAttribute("aria-activedescendant"), "idlAttrElement"); + assert_equals(deletionParent.getAttribute("aria-activedescendant"), ""); deletionParent.removeChild(idlAttrElement); assert_equals(deletionParent.ariaActiveDescendantElement, null); - // The content attribute will still reflect the id. - assert_equals(deletionParent.getAttribute("aria-activedescendant"), "idlAttrElement"); - }, "Deleting a reflected element should return null for the IDL attribute and cause the content attribute to become stale."); + // The content attribute is still empty. + assert_equals(deletionParent.getAttribute("aria-activedescendant"), ""); + }, "Deleting a reflected element should return null for the IDL attribute and the content attribute will be empty."); </script> <div id="parentNode" role="listbox" aria-activedescendant="changingIdElement"> @@ -211,15 +214,16 @@ assert_equals(parentNode.ariaActiveDescendantElement, null, "Element set via content attribute with a changed id will return null on getting"); parentNode.ariaActiveDescendantElement = changingIdElement; - assert_equals(parentNode.getAttribute("aria-activedescendant"), "new-id"); + assert_equals(parentNode.getAttribute("aria-activedescendant"), ""); + assert_equals(parentNode.ariaActiveDescendantElement, changingIdElement); // The explicitly set element takes precendance over the content attribute. // This means that we still return the same element reference, but the - // content attribute reflects the old id. + // content attribute is empty. changingIdElement.setAttribute("id", "newer-id"); assert_equals(parentNode.ariaActiveDescendantElement, changingIdElement, "explicitly set element is still present even after the id has been changed"); - assert_equals(parentNode.getAttribute("aria-activedescendant"), "new-id", "content attribute reflects the id that was present upon explicitly setting the element reference."); - }, "Changing the ID of an element causes the content attribute to become out of sync."); + assert_equals(parentNode.getAttribute("aria-activedescendant"), "", "content attribute is empty."); + }, "Changing the ID of an element doesn't lose the reference."); </script> <!-- TODO(chrishall): change naming scheme to inner/outer --> @@ -238,7 +242,7 @@ lightParent.ariaActiveDescendantElement = lightElement; assert_equals(lightParent.ariaActiveDescendantElement, lightElement); - assert_equals(lightParent.getAttribute('aria-activedescendant'), "lightElement"); + assert_equals(lightParent.getAttribute('aria-activedescendant'), ""); // Move the referenced element into shadow DOM. // This will cause the computed attr-associated element to be null as the @@ -248,7 +252,7 @@ // then reflect shadowRoot.appendChild(lightElement); assert_equals(lightParent.ariaActiveDescendantElement, null, "computed attr-assoc element should be null as referenced element is in an invalid scope"); - assert_equals(lightParent.getAttribute("aria-activedescendant"), "lightElement"); + assert_equals(lightParent.getAttribute("aria-activedescendant"), ""); // Move the referenced element back into light DOM. // Since the underlying reference was kept intact, after moving the @@ -256,7 +260,7 @@ // computed attr-associated element. lightParent.appendChild(lightElement); assert_equals(lightParent.ariaActiveDescendantElement, lightElement, "computed attr-assoc element should be restored as referenced element is back in a valid scope"); - assert_equals(lightParent.getAttribute("aria-activedescendant"), "lightElement"); + assert_equals(lightParent.getAttribute("aria-activedescendant"), ""); }, "Reparenting an element into a descendant shadow scope hides the element reference."); </script> @@ -274,13 +278,13 @@ fruitbowl.ariaActiveDescendantElement = apple; assert_equals(fruitbowl.ariaActiveDescendantElement, apple); - assert_equals(fruitbowl.getAttribute("aria-activedescendant"), "apple"); + assert_equals(fruitbowl.getAttribute("aria-activedescendant"), ""); // Move the referenced element into shadow DOM. shadowRoot.appendChild(apple); assert_equals(fruitbowl.ariaActiveDescendantElement, null, "computed attr-assoc element should be null as referenced element is in an invalid scope"); - // Note that the content attribute is NOT cleared. - assert_equals(fruitbowl.getAttribute("aria-activedescendant"), "apple"); + // The content attribute is still empty. + assert_equals(fruitbowl.getAttribute("aria-activedescendant"), ""); // let us rename our banana to an apple banana.setAttribute("id", "apple"); @@ -289,12 +293,10 @@ // our ariaActiveDescendantElement thankfully isn't tricked. // this is thanks to the underlying reference being kept intact, it is - // checked and found to be in an invalid scope and therefore the content - // attribute fallback isn't used. + // checked and found to be in an invalid scope. assert_equals(fruitbowl.ariaActiveDescendantElement, null); - // our content attribute still returns "apple", - // even though fetching that by id would give us our lying banana. - assert_equals(fruitbowl.getAttribute("aria-activedescendant"), "apple"); + // our content attribute is empty. + assert_equals(fruitbowl.getAttribute("aria-activedescendant"), ""); // when we remove our IDL attribute, the content attribute is also thankfully cleared. fruitbowl.ariaActiveDescendantElement = null; @@ -350,7 +352,7 @@ input2.ariaLabelledByElements = [billingElement, addressElement]; assert_array_equals(input2.ariaLabelledByElements, [billingElement, addressElement], "Testing IDL setter/getter."); assert_equals(input1.ariaLabelledByElements, input1.ariaLabelledByElements, "check idl attribute caching after update"); - assert_equals(input2.getAttribute("aria-labelledby"), "billingElement addressElement"); + assert_equals(input2.getAttribute("aria-labelledby"), ""); // Remove the billingElement from the DOM. // As it was explicitly set the underlying association will remain intact, @@ -399,13 +401,15 @@ assert_equals(link1.getAttribute("aria-controls"), ""); link2.ariaControlsElements = [panel1, panel2]; - assert_equals(link2.getAttribute("aria-controls"), "panel1 panel2"); + assert_equals(link2.getAttribute("aria-controls"), ""); + assert_array_equals(link2.ariaControlsElements, [panel1, panel2]); link2.removeAttribute("aria-controls"); assert_equals(link2.ariaControlsElements, null); link2.ariaControlsElements = [panel1, panel2]; - assert_equals(link2.getAttribute("aria-controls"), "panel1 panel2"); + assert_equals(link2.getAttribute("aria-controls"), ""); + assert_array_equals(link2.ariaControlsElements, [panel1, panel2]); link2.ariaControlsElements = null; assert_false(link2.hasAttribute("aria-controls", "Nullifying the IDL attribute should remove the content attribute.")); @@ -421,7 +425,8 @@ assert_array_equals(describedLink.ariaDescribedByElements, [description1, description2]); describedLink.ariaDescribedByElements = [description1, description2]; - assert_equals(describedLink.getAttribute("aria-describedby"), "description1 description2"); + assert_equals(describedLink.getAttribute("aria-describedby"), ""); + assert_array_equals(describedLink.ariaDescribedByElements, [description1, description2]); describedLink.ariaDescribedByElements = []; assert_equals(describedLink.getAttribute("aria-describedby"), ""); @@ -433,7 +438,8 @@ assert_equals(describedLink.ariaDescribedByElements, null); describedLink.ariaDescribedByElements = [description1, description2]; - assert_equals(describedLink.getAttribute("aria-describedby"), "description1 description2"); + assert_equals(describedLink.getAttribute("aria-describedby"), ""); + assert_array_equals(describedLink.ariaDescribedByElements, [description1, description2]); describedLink.ariaDescribedByElements = null; assert_false(describedLink.hasAttribute("aria-describedby", "Nullifying the IDL attribute should remove the content attribute.")); @@ -453,7 +459,8 @@ <h2 id="titleHeading" aria-flowto="article1 article2">Title</h2> assert_array_equals(titleHeading.ariaFlowToElements, [article1, article2]); titleHeading.ariaFlowToElements = [article1, article2]; - assert_equals(titleHeading.getAttribute("aria-flowto"), "article1 article2"); + assert_equals(titleHeading.getAttribute("aria-flowto"), ""); + assert_array_equals(titleHeading.ariaFlowToElements, [article1, article2]); titleHeading.ariaFlowToElements = []; assert_equals(titleHeading.getAttribute("aria-flowto"), ""); @@ -465,7 +472,8 @@ <h2 id="titleHeading" aria-flowto="article1 article2">Title</h2> assert_equals(titleHeading.ariaFlowToElements, null); titleHeading.ariaFlowToElements = [article1, article2]; - assert_equals(titleHeading.getAttribute("aria-flowto"), "article1 article2"); + assert_equals(titleHeading.getAttribute("aria-flowto"), ""); + assert_array_equals(titleHeading.ariaFlowToElements, [article1, article2]); titleHeading.ariaFlowToElements = null; assert_false(titleHeading.hasAttribute("aria-flowto", "Nullifying the IDL attribute should remove the content attribute.")); @@ -487,7 +495,8 @@ <h2 id="titleHeading" aria-flowto="article1 article2">Title</h2> assert_equals(listItemOwner.ariaOwnsElements, null); listItemOwner.ariaOwnsElements = [child1, child2]; - assert_equals(listItemOwner.getAttribute("aria-owns"), "child1 child2"); + assert_equals(listItemOwner.getAttribute("aria-owns"), ""); + assert_array_equals(listItemOwner.ariaOwnsElements, [child1, child2]); listItemOwner.ariaOwnsElements = []; assert_equals(listItemOwner.getAttribute("aria-owns"), ""); @@ -496,7 +505,8 @@ <h2 id="titleHeading" aria-flowto="article1 article2">Title</h2> assert_array_equals(listItemOwner.ariaOwnsElements, [child1]); listItemOwner.ariaOwnsElements = [child1, child2]; - assert_equals(listItemOwner.getAttribute("aria-owns"), "child1 child2"); + assert_equals(listItemOwner.getAttribute("aria-owns"), ""); + assert_array_equals(listItemOwner.ariaOwnsElements, [child1, child2]); listItemOwner.ariaOwnsElements = null; assert_false(listItemOwner.hasAttribute("aria-owns", "Nullifying the IDL attribute should remove the content attribute.")); @@ -570,16 +580,16 @@ <h2 id="lightDomHeading" aria-flowto="shadowChild1 shadowChild2">Light DOM Headi describedButtonContainer.appendChild(describedElement); describedElement.ariaDescribedByElements = [description1, description2]; - // All elements were in the same scope, so elements are gettable and the content attribute reflects the ids. + // All elements were in the same scope, so elements are gettable and the content attribute is empty. assert_array_equals(describedElement.ariaDescribedByElements, [description1, description2], "same scope reference"); - assert_equals(describedElement.getAttribute("aria-describedby"), "buttonDescription1 buttonDescription2"); + assert_equals(describedElement.getAttribute("aria-describedby"), ""); outerShadowRoot.appendChild(describedElement); // Explicitly set attr-associated-elements should still be gettable because we are referencing elements in a lighter scope. - // The content attr still reflects the ids from the explicit elements because they were in a valid scope at the time of setting. + // The content attr is empty. assert_array_equals(describedElement.ariaDescribedByElements, [description1, description2], "lighter scope reference"); - assert_equals(describedElement.getAttribute("aria-describedby"), "buttonDescription1 buttonDescription2"); + assert_equals(describedElement.getAttribute("aria-describedby"), ""); // Move the explicitly set elements into a deeper shadow DOM to test the relationship should not be gettable. innerShadowRoot.appendChild(description1); @@ -587,13 +597,12 @@ <h2 id="lightDomHeading" aria-flowto="shadowChild1 shadowChild2">Light DOM Headi // Explicitly set elements are no longer retrievable, because they are no longer in a valid scope. assert_array_equals(describedElement.ariaDescribedByElements, [], "invalid scope reference"); - assert_equals(describedElement.getAttribute("aria-describedby"), "buttonDescription1 buttonDescription2"); + assert_equals(describedElement.getAttribute("aria-describedby"), ""); - // Move into the same shadow scope as the explicitly set elements to test that the elements are gettable - // and reflect the correct IDs onto the content attribute. + // Move into the same shadow scope as the explicitly set elements to test that the elements are gettable. innerShadowRoot.appendChild(describedElement); assert_array_equals(describedElement.ariaDescribedByElements, [description1, description2], "restored valid scope reference"); - assert_equals(describedElement.getAttribute("aria-describedby"), "buttonDescription1 buttonDescription2"); + assert_equals(describedElement.getAttribute("aria-describedby"), ""); }, "Moving explicitly set elements across shadow DOM boundaries."); </script> @@ -618,38 +627,38 @@ <h2 id="lightDomHeading" aria-flowto="shadowChild1 shadowChild2">Light DOM Headi // Explicitly set elements are in a lighter shadow DOM, so that's ok. headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2]; assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Lighter elements are gettable when explicitly set."); - assert_equals(headingElement.getAttribute("aria-labelledby"), "", "Crosses shadow DOM boundary, so content attribute should be empty string."); + assert_equals(headingElement.getAttribute("aria-labelledby"), ""); // Move into Light DOM, explicitly set elements should still be gettable. - // Note that the content attribute still reflects the element ids - when scope changes it becomes stale. + // Note that the content attribute is still empty. sameScopeContainer.appendChild(headingElement); assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Elements are all in same scope, so gettable."); - assert_equals(headingElement.getAttribute("aria-labelledby"), "", "Content attribute is empty, as on setting the explicitly set elements they were in a different scope."); + assert_equals(headingElement.getAttribute("aria-labelledby"), "", "Content attribute is empty."); - // Reset the association, to update the content attribute. + // Reset the association, the content attribute is sitll empty. headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2]; - assert_equals(headingElement.getAttribute("aria-labelledby"), "headingLabel1 headingLabel2", "Elements are set again, so the content attribute is updated."); + assert_equals(headingElement.getAttribute("aria-labelledby"), ""); // Remove the referring element from the DOM, elements are no longer longer exposed, // underlying internal reference is still kept intact. headingElement.remove(); assert_array_equals(headingElement.ariaLabelledByElements, [], "Element is no longer in the document, so references should no longer be exposed."); - assert_equals(headingElement.getAttribute("aria-labelledby"), "headingLabel1 headingLabel2"); + assert_equals(headingElement.getAttribute("aria-labelledby"), ""); // Insert it back in. sameScopeContainer.appendChild(headingElement); assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Element is restored to valid scope, so should be gettable."); - assert_equals(headingElement.getAttribute("aria-labelledby"), "headingLabel1 headingLabel2"); + assert_equals(headingElement.getAttribute("aria-labelledby"), ""); // Remove everything from the DOM, nothing is exposed again. headingLabel1.remove(); headingLabel2.remove(); assert_array_equals(headingElement.ariaLabelledByElements, []); - assert_equals(headingElement.getAttribute("aria-labelledby"), "headingLabel1 headingLabel2"); + assert_equals(headingElement.getAttribute("aria-labelledby"), ""); assert_equals(document.getElementById("headingLabel1"), null); assert_equals(document.getElementById("headingLabel2"), null); - // Reset the association to update the content attribute. + // Reset the association. headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2]; assert_array_equals(headingElement.ariaLabelledByElements, []); assert_equals(headingElement.getAttribute("aria-labelledby"), "");