author | Razvan Maries <rmaries@mozilla.com> |
Wed, 27 May 2020 21:04:58 +0300 | |
changeset 532562 | 1e2293c4bbd6564281f26c556252bc6c1fcadf2a |
parent 532561 | 8a881029b6f98b51a40c4910748a7fa2fe951fb7 |
child 532563 | 9b662148a7b05da8033356ad335b3b99363dec5a |
push id | 117235 |
push user | rmaries@mozilla.com |
push date | Wed, 27 May 2020 18:16:45 +0000 |
treeherder | autoland@9b662148a7b0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1624909 |
milestone | 78.0a1 |
backs out | b4c58d9afd4b5ba0eb49063d06bcfa7b479313c4 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/base/Pivot.cpp +++ b/accessible/base/Pivot.cpp @@ -528,26 +528,8 @@ Accessible* Pivot::AtPoint(int32_t aX, i } } child = child->Parent(); } return match; } - -// Role Rule - -PivotRoleRule::PivotRoleRule(mozilla::a11y::role aRole) : mRole(aRole) {} - -uint16_t PivotRoleRule::Match(Accessible* aAccessible) { - uint16_t result = nsIAccessibleTraversalRule::FILTER_IGNORE; - - if (nsAccUtils::MustPrune(aAccessible)) { - result |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE; - } - - if (aAccessible->Role() == mRole) { - result |= nsIAccessibleTraversalRule::FILTER_MATCH; - } - - return result; -}
--- a/accessible/base/Pivot.h +++ b/accessible/base/Pivot.h @@ -78,25 +78,12 @@ class Pivot final { bool aSearchCurrent); // Search in preorder for the first text accessible. HyperTextAccessible* SearchForText(Accessible* aAnchor, bool aBackward); Accessible* mRoot; }; -/** - * This rule matches accessibles on a given role. - */ -class PivotRoleRule final : public PivotRule { - public: - explicit PivotRoleRule(mozilla::a11y::role aRole); - - virtual uint16_t Match(Accessible* aAccessible) override; - - private: - mozilla::a11y::role mRole; -}; - } // namespace a11y } // namespace mozilla #endif // mozilla_a11y_Pivot_h_
--- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -14,17 +14,16 @@ #include "nsAccessiblePivot.h" #include "nsGenericHTMLElement.h" #include "NotificationController.h" #include "nsEventShell.h" #include "nsTextEquivUtils.h" #include "DocAccessibleChild.h" #include "EventTree.h" #include "GeckoProfiler.h" -#include "Pivot.h" #include "Relation.h" #include "Role.h" #include "RootAccessible.h" #include "States.h" #include "StyleInfo.h" #include "TableAccessible.h" #include "TableCellAccessible.h" #include "TreeWalker.h" @@ -1678,49 +1677,18 @@ Relation Accessible::RelationByType(Rela case RelationType::FLOWS_TO: return Relation( new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_flowto)); case RelationType::FLOWS_FROM: return Relation( new RelatedAccIterator(Document(), mContent, nsGkAtoms::aria_flowto)); - case RelationType::MEMBER_OF: { - if (Role() == roles::RADIOBUTTON) { - /* If we see a radio button role here, we're dealing with an aria - * radio button (because input=radio buttons are - * HTMLRadioButtonAccessibles) */ - Relation rel = Relation(); - Accessible* currParent = Parent(); - while (currParent && currParent->Role() != roles::RADIO_GROUP) { - currParent = currParent->Parent(); - } - - if (currParent && currParent->Role() == roles::RADIO_GROUP) { - /* If we found a radiogroup parent, search for all - * roles::RADIOBUTTON children and add them to our relation. - * This search will include the radio button this method - * was called from, which is expected. */ - Pivot p = Pivot(currParent); - PivotRoleRule rule(roles::RADIOBUTTON); - Accessible* match = currParent; - while ((match = p.Next(match, rule))) { - rel.AppendTarget(match); - } - } - - /* By webkit's standard, aria radio buttons do not get grouped - * if they lack a group parent, so we return an empty - * relation here if the above check fails. */ - - return rel; - } - + case RelationType::MEMBER_OF: return Relation(mDoc, GetAtomicRegion()); - } case RelationType::SUBWINDOW_OF: case RelationType::EMBEDS: case RelationType::EMBEDDED_BY: case RelationType::POPUP_FOR: case RelationType::PARENT_WINDOW_OF: return Relation();
--- a/accessible/html/HTMLFormControlAccessible.cpp +++ b/accessible/html/HTMLFormControlAccessible.cpp @@ -65,22 +65,16 @@ uint64_t HTMLRadioButtonAccessible::Nati HTMLInputElement* input = HTMLInputElement::FromNode(mContent); if (input && input->Checked()) state |= states::CHECKED; return state; } void HTMLRadioButtonAccessible::GetPositionAndSizeInternal(int32_t* aPosInSet, int32_t* aSetSize) { - Unused << ComputeGroupAttributes(aPosInSet, aSetSize); -} - -Relation HTMLRadioButtonAccessible::ComputeGroupAttributes( - int32_t* aPosInSet, int32_t* aSetSize) const { - Relation rel = Relation(); int32_t namespaceId = mContent->NodeInfo()->NamespaceID(); nsAutoString tagName; mContent->NodeInfo()->GetName(tagName); nsAutoString type; mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type); nsAutoString name; mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name); @@ -88,49 +82,38 @@ Relation HTMLRadioButtonAccessible::Comp RefPtr<nsContentList> inputElms; nsCOMPtr<nsIFormControl> formControlNode(do_QueryInterface(mContent)); dom::Element* formElm = formControlNode->GetFormElement(); if (formElm) inputElms = NS_GetContentList(formElm, namespaceId, tagName); else inputElms = NS_GetContentList(mContent->OwnerDoc(), namespaceId, tagName); - NS_ENSURE_TRUE(inputElms, rel); + NS_ENSURE_TRUE_VOID(inputElms); uint32_t inputCount = inputElms->Length(false); // Compute posinset and setsize. int32_t indexOf = 0; int32_t count = 0; for (uint32_t index = 0; index < inputCount; index++) { nsIContent* inputElm = inputElms->Item(index, false); if (inputElm->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, type, eCaseMatters) && inputElm->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, name, eCaseMatters) && mDoc->HasAccessible(inputElm)) { count++; - rel.AppendTarget(mDoc->GetAccessible(inputElm)); if (inputElm == mContent) indexOf = count; } } *aPosInSet = indexOf; *aSetSize = count; - return rel; -} - -Relation HTMLRadioButtonAccessible::RelationByType(RelationType aType) const { - if (aType == RelationType::MEMBER_OF) { - int32_t unusedPos, unusedSetSize; - return ComputeGroupAttributes(&unusedPos, &unusedSetSize); - } - - return Accessible::RelationByType(aType); } //////////////////////////////////////////////////////////////////////////////// // HTMLButtonAccessible //////////////////////////////////////////////////////////////////////////////// HTMLButtonAccessible::HTMLButtonAccessible(nsIContent* aContent, DocAccessible* aDoc)
--- a/accessible/html/HTMLFormControlAccessible.h +++ b/accessible/html/HTMLFormControlAccessible.h @@ -4,17 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_A11Y_HTMLFormControlAccessible_H_ #define MOZILLA_A11Y_HTMLFormControlAccessible_H_ #include "FormControlAccessible.h" #include "HyperTextAccessibleWrap.h" #include "nsAccUtils.h" -#include "Relation.h" namespace mozilla { class TextEditor; namespace a11y { /** * Accessible for HTML input@type="radio" element. */ @@ -26,20 +25,16 @@ class HTMLRadioButtonAccessible : public // state change notification. mStateFlags |= eIgnoreDOMUIEvent; } // Accessible virtual uint64_t NativeState() const override; virtual void GetPositionAndSizeInternal(int32_t* aPosInSet, int32_t* aSetSize) override; - virtual Relation RelationByType(RelationType aType) const override; - - private: - Relation ComputeGroupAttributes(int32_t* aPosInSet, int32_t* aSetSize) const; }; /** * Accessible for HTML input@type="button", @type="submit", @type="image" * and HTML button elements. */ class HTMLButtonAccessible : public HyperTextAccessibleWrap { public:
--- a/accessible/mac/AccessibleWrap.mm +++ b/accessible/mac/AccessibleWrap.mm @@ -176,21 +176,19 @@ Class a11y::GetTypeFromRole(roles::Role case roles::PUSHBUTTON: return [mozButtonAccessible class]; case roles::PAGETAB: return [mozTabAccessible class]; case roles::CHECKBUTTON: case roles::TOGGLE_BUTTON: + case roles::RADIOBUTTON: return [mozCheckboxAccessible class]; - case roles::RADIOBUTTON: - return [mozRadioButtonAccessible class]; - case roles::SPINBUTTON: case roles::SLIDER: return [mozIncrementableAccessible class]; case roles::HEADING: return [mozHeadingAccessible class]; case roles::PAGETABLIST:
--- a/accessible/mac/mozActionElements.h +++ b/accessible/mac/mozActionElements.h @@ -16,21 +16,16 @@ @interface mozPopupButtonAccessible : mozButtonAccessible @end @interface mozCheckboxAccessible : mozButtonAccessible // returns one of the constants defined in CheckboxValue - (int)isChecked; @end -// Accessible for a radio button -@interface mozRadioButtonAccessible : mozCheckboxAccessible -- (id)accessibilityAttributeValue:(NSString*)attribute; -@end - /** * Accessible for a PANE */ @interface mozPaneAccessible : mozAccessible @end /**
--- a/accessible/mac/mozActionElements.mm +++ b/accessible/mac/mozActionElements.mm @@ -4,17 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #import "mozActionElements.h" #import "MacUtils.h" #include "Accessible-inl.h" #include "DocAccessible.h" #include "XULTabAccessible.h" -#include "HTMLFormControlAccessible.h" #include "nsDeckFrame.h" #include "nsObjCExceptions.h" using namespace mozilla::a11y; enum CheckboxValue { // these constants correspond to the values in the OS @@ -150,46 +149,16 @@ enum CheckboxValue { } } return [super ignoreWithParent:parent]; } @end -@implementation mozRadioButtonAccessible - -- (id)accessibilityAttributeValue:(NSString*)attribute { - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; - - if ([attribute isEqualToString:NSAccessibilityLinkedUIElementsAttribute]) { - if (AccessibleWrap* accWrap = [self getGeckoAccessible]) { - NSMutableArray* radioSiblings = [NSMutableArray new]; - HTMLRadioButtonAccessible* radioAcc = (HTMLRadioButtonAccessible*)accWrap; - Relation rel = radioAcc->RelationByType(RelationType::MEMBER_OF); - Accessible* tempAcc; - while ((tempAcc = rel.Next())) { - [radioSiblings addObject:GetNativeFromGeckoAccessible(tempAcc)]; - } - return radioSiblings; - } - - if (ProxyAccessible* proxy = [self getProxyAccessible]) { - nsTArray<ProxyAccessible*> accs = proxy->RelationByType(RelationType::MEMBER_OF); - return ConvertToNSArray(accs); - } - } - - return [super accessibilityAttributeValue:attribute]; - - NS_OBJC_END_TRY_ABORT_BLOCK_NIL; -} - -@end - @implementation mozCheckboxAccessible - (int)isChecked { // check if we're checked or in a mixed state uint64_t state = [self stateWithMask:(states::CHECKED | states::PRESSED | states::MIXED)]; if (state & (states::CHECKED | states::PRESSED)) { return kChecked; }
--- a/accessible/tests/browser/mac/browser.ini +++ b/accessible/tests/browser/mac/browser.ini @@ -12,15 +12,14 @@ support-files = [browser_app.js] [browser_aria_current.js] [browser_details_summary.js] [browser_label_title.js] [browser_range.js] [browser_roles_elements.js] [browser_table.js] [browser_selectables.js] -[browser_radio_position.js] [browser_toggle_radio_check.js] [browser_link.js] [browser_aria_haspopup.js] [browser_required.js] [browser_popupbutton.js] [browser_mathml.js]
deleted file mode 100644 --- a/accessible/tests/browser/mac/browser_radio_position.js +++ /dev/null @@ -1,321 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -/* import-globals-from ../../mochitest/role.js */ -/* import-globals-from ../../mochitest/states.js */ -loadScripts( - { name: "role.js", dir: MOCHITESTS_DIR }, - { name: "states.js", dir: MOCHITESTS_DIR } -); - -function getChildRoles(parent) { - return parent - .getAttributeValue("AXChildren") - .map(c => c.getAttributeValue("AXRole")); -} - -function getLinkedTitles(element) { - return element - .getAttributeValue("AXLinkedUIElements") - .map(c => c.getAttributeValue("AXTitle")); -} - -/** - * Test radio group - */ -addAccessibleTask( - `<div role="radiogroup" id="radioGroup"> - <div role="radio" - id="radioGroupItem1"> - Regular crust - </div> - <div role="radio" - id="radioGroupItem2"> - Deep dish - </div> - <div role="radio" - id="radioGroupItem3"> - Thin crust - </div> - </div>`, - async (browser, accDoc) => { - let item1 = getNativeInterface(accDoc, "radioGroupItem1"); - let item2 = getNativeInterface(accDoc, "radioGroupItem2"); - let item3 = getNativeInterface(accDoc, "radioGroupItem3"); - let titleList = ["Regular crust", "Deep dish", "Thin crust"]; - - Assert.deepEqual( - titleList, - [item1, item2, item3].map(c => c.getAttributeValue("AXTitle")), - "Title list matches" - ); - - let linkedElems = item1.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Item 1 has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(item1), - titleList, - "Item one has correctly ordered linked elements" - ); - - linkedElems = item2.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Item 2 has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(item2), - titleList, - "Item two has correctly ordered linked elements" - ); - - linkedElems = item3.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Item 3 has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(item3), - titleList, - "Item three has correctly ordered linked elements" - ); - } -); - -/** - * Test dynamic add to a radio group - */ -addAccessibleTask( - `<div role="radiogroup" id="radioGroup"> - <div role="radio" - id="radioGroupItem1"> - Option One - </div> - </div>`, - async (browser, accDoc) => { - let item1 = getNativeInterface(accDoc, "radioGroupItem1"); - let linkedElems = item1.getAttributeValue("AXLinkedUIElements"); - - is(linkedElems.length, 1, "Item 1 has one linked UI elem"); - is( - linkedElems[0].getAttributeValue("AXTitle"), - item1.getAttributeValue("AXTitle"), - "Item 1 is first element" - ); - - let reorder = waitForEvent(EVENT_REORDER, "radioGroup"); - await SpecialPowers.spawn(browser, [], () => { - let d = content.document.createElement("div"); - d.setAttribute("role", "radio"); - content.document.getElementById("radioGroup").appendChild(d); - }); - await reorder; - - let radioGroup = getNativeInterface(accDoc, "radioGroup"); - let groupMembers = radioGroup.getAttributeValue("AXChildren"); - is(groupMembers.length, 2, "Radio group has two members"); - let item2 = groupMembers[1]; - item1 = getNativeInterface(accDoc, "radioGroupItem1"); - let titleList = ["Option One", ""]; - - Assert.deepEqual( - titleList, - [item1, item2].map(c => c.getAttributeValue("AXTitle")), - "Title list matches" - ); - - linkedElems = item1.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 2, "Item 1 has two linked UI elems"); - Assert.deepEqual( - getLinkedTitles(item1), - titleList, - "Item one has correctly ordered linked elements" - ); - - linkedElems = item2.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 2, "Item 2 has two linked UI elems"); - Assert.deepEqual( - getLinkedTitles(item2), - titleList, - "Item two has correctly ordered linked elements" - ); - } -); - -/** - * Test input[type=radio] for single group - */ -addAccessibleTask( - `<input type="radio" id="cat" name="animal"><label for="cat">Cat</label> - <input type="radio" id="dog" name="animal"><label for="dog">Dog</label> - <input type="radio" id="catdog" name="animal"><label for="catdog">CatDog</label>`, - async (browser, accDoc) => { - let cat = getNativeInterface(accDoc, "cat"); - let dog = getNativeInterface(accDoc, "dog"); - let catdog = getNativeInterface(accDoc, "catdog"); - let titleList = ["Cat", "Dog", "CatDog"]; - - Assert.deepEqual( - titleList, - [cat, dog, catdog].map(x => x.getAttributeValue("AXTitle")), - "Title list matches" - ); - - let linkedElems = cat.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Cat has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(cat), - titleList, - "Cat has correctly ordered linked elements" - ); - - linkedElems = dog.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Dog has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(dog), - titleList, - "Dog has correctly ordered linked elements" - ); - - linkedElems = catdog.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Catdog has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(catdog), - titleList, - "catdog has correctly ordered linked elements" - ); - } -); - -/** - * Test input[type=radio] for different groups - */ -addAccessibleTask( - `<input type="radio" id="cat" name="one"><label for="cat">Cat</label> - <input type="radio" id="dog" name="two"><label for="dog">Dog</label> - <input type="radio" id="catdog"><label for="catdog">CatDog</label>`, - async (browser, accDoc) => { - let cat = getNativeInterface(accDoc, "cat"); - let dog = getNativeInterface(accDoc, "dog"); - let catdog = getNativeInterface(accDoc, "catdog"); - - let linkedElems = cat.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 1, "Cat has one linked UI elem"); - is( - linkedElems[0].getAttributeValue("AXTitle"), - cat.getAttributeValue("AXTitle"), - "Cat is only element" - ); - - linkedElems = dog.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 1, "Dog has one linked UI elem"); - is( - linkedElems[0].getAttributeValue("AXTitle"), - dog.getAttributeValue("AXTitle"), - "Dog is only element" - ); - - linkedElems = catdog.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 0, "Catdog has no linked UI elem"); - } -); - -/** - * Test input[type=radio] for single group across DOM - */ -addAccessibleTask( - `<input type="radio" id="cat" name="animal"><label for="cat">Cat</label> - <div> - <span> - <input type="radio" id="dog" name="animal"><label for="dog">Dog</label> - </span> - </div> - <div> - <input type="radio" id="catdog" name="animal"><label for="catdog">CatDog</label> - </div>`, - async (browser, accDoc) => { - let cat = getNativeInterface(accDoc, "cat"); - let dog = getNativeInterface(accDoc, "dog"); - let catdog = getNativeInterface(accDoc, "catdog"); - let titleList = ["Cat", "Dog", "CatDog"]; - - Assert.deepEqual( - titleList, - [cat, dog, catdog].map(x => x.getAttributeValue("AXTitle")), - "Title list matches" - ); - - let linkedElems = cat.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Cat has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(cat), - titleList, - "cat has correctly ordered linked elements" - ); - - linkedElems = dog.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Dog has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(dog), - titleList, - "dog has correctly ordered linked elements" - ); - - linkedElems = catdog.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 3, "Catdog has three linked UI elems"); - Assert.deepEqual( - getLinkedTitles(catdog), - titleList, - "catdog has correctly ordered linked elements" - ); - } -); - -/** - * Test dynamic add of input[type=radio] in a single group - */ -addAccessibleTask( - `<div id="container"><input type="radio" id="cat" name="animal"></div>`, - async (browser, accDoc) => { - let cat = getNativeInterface(accDoc, "cat"); - let container = getNativeInterface(accDoc, "container"); - - let containerChildren = container.getAttributeValue("AXChildren"); - is(containerChildren.length, 1, "container has one button"); - is( - containerChildren[0].getAttributeValue("AXRole"), - "AXRadioButton", - "Container child is radio button" - ); - - let linkedElems = cat.getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 1, "Cat has 1 linked UI elem"); - is( - linkedElems[0].getAttributeValue("AXTitle"), - cat.getAttributeValue("AXTitle"), - "Cat is first element" - ); - let reorder = waitForEvent(EVENT_REORDER, "container"); - await SpecialPowers.spawn(browser, [], () => { - let input = content.document.createElement("input"); - input.setAttribute("type", "radio"); - input.setAttribute("name", "animal"); - content.document.getElementById("container").appendChild(input); - }); - await reorder; - - container = getNativeInterface(accDoc, "container"); - containerChildren = container.getAttributeValue("AXChildren"); - - is(containerChildren.length, 2, "container has two children"); - - Assert.deepEqual( - getChildRoles(container), - ["AXRadioButton", "AXRadioButton"], - "Both children are radio buttons" - ); - - linkedElems = containerChildren[0].getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 2, "Cat has 2 linked elements"); - - linkedElems = containerChildren[1].getAttributeValue("AXLinkedUIElements"); - is(linkedElems.length, 2, "New button has 2 linked elements"); - } -);