☠☠ backed out by 42f436b26f0a ☠ ☠ | |
author | Eitan Isaacson <eitan@monotonous.org> |
Wed, 16 Sep 2020 20:20:00 +0000 | |
changeset 549006 | 2ee894a67a931b9a594691081f33156897c89b04 |
parent 549005 | cbfdd5245340bc240bab5ccb3a81878ca5143c2d |
child 549007 | ea2f00c4049e3bb28bf0a57edba3eeed15a5445e |
push id | 126522 |
push user | eisaacson@mozilla.com |
push date | Wed, 16 Sep 2020 20:24:07 +0000 |
treeherder | autoland@ea2f00c4049e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | morgan |
bugs | 1620324 |
milestone | 82.0a1 |
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/mac/MOXAccessibleProtocol.h +++ b/accessible/mac/MOXAccessibleProtocol.h @@ -200,16 +200,19 @@ - (NSValue* _Nullable)moxColumnIndexRange; // AXRowHeaderUIElements - (NSArray* _Nullable)moxRowHeaderUIElements; // AXColumnHeaderUIElements - (NSArray* _Nullable)moxColumnHeaderUIElements; +// AXIdentifier +- (NSString* _Nullable)moxIdentifier; + // Math Attributes // AXMathRootRadicand - (id _Nullable)moxMathRootRadicand; // AXMathRootIndex - (id _Nullable)moxMathRootIndex;
--- a/accessible/mac/MOXWebAreaAccessible.h +++ b/accessible/mac/MOXWebAreaAccessible.h @@ -5,35 +5,49 @@ * 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/. */ #import "mozAccessible.h" #include "Pivot.h" using namespace mozilla::a11y; -@interface MOXWebAreaAccessible : mozAccessible +@class MOXRootGroup; + +@interface MOXWebAreaAccessible : mozAccessible { + MOXRootGroup* mRootGroup; +} // overrides - (NSURL*)moxURL; // overrides - (NSNumber*)moxLoaded; // overrides - (NSNumber*)moxLoadingProgress; // override - (NSArray*)moxUIElementsForSearchPredicate:(NSDictionary*)searchPredicate; // override - (NSNumber*)moxUIElementCountForSearchPredicate:(NSDictionary*)searchPredicate; -// overrides +// override +- (NSArray*)moxUnignoredChildren; + +// override - (void)handleAccessibleEvent:(uint32_t)eventType; +// override +- (void)dealloc; + +- (NSArray*)rootGroupChildren; + +- (id)rootGroup; + @end @interface MOXSearchInfo : NSObject { // The gecko accessible of the web area, we need a reference // to set the pivot's root. This is a weak ref. AccessibleOrProxy mWebArea; // The gecko accessible we should start searching from.
--- a/accessible/mac/MOXWebAreaAccessible.mm +++ b/accessible/mac/MOXWebAreaAccessible.mm @@ -8,16 +8,118 @@ #import "MOXWebAreaAccessible.h" #import "RotorRules.h" #include "nsCocoaUtils.h" #include "DocAccessibleParent.h" using namespace mozilla::a11y; +@interface MOXRootGroup : MOXAccessibleBase { + MOXWebAreaAccessible* mParent; +} + +// override +- (id)initWithParent:(MOXWebAreaAccessible*)parent; + +// override +- (NSString*)moxRole; + +// override +- (NSString*)moxRoleDescription; + +// override +- (id<mozAccessible>)moxParent; + +// override +- (NSArray*)moxChildren; + +// override +- (NSString*)moxIdentifier; + +// override +- (id)moxHitTest:(NSPoint)point; + +// override +- (NSValue*)moxPosition; + +// override +- (NSValue*)moxSize; + +// override +- (BOOL)disableChild:(id)child; + +// override +- (void)expire; + +// override +- (BOOL)isExpired; + +@end + +@implementation MOXRootGroup + +- (id)initWithParent:(MOXWebAreaAccessible*)parent { + // The parent is always a MOXWebAreaAccessible + mParent = parent; + return [super init]; +} + +- (NSString*)moxRole { + return NSAccessibilityGroupRole; +} + +- (NSString*)moxRoleDescription { + return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, nil); +} + +- (id<mozAccessible>)moxParent { + return mParent; +} + +- (NSArray*)moxChildren { + // Reparent the children of the web area here. + return [mParent rootGroupChildren]; +} + +- (NSString*)moxIdentifier { + // This is mostly for testing purposes to assert that this is the generated + // root group. + return @"root-group"; +} + +- (id)moxHitTest:(NSPoint)point { + return [mParent moxHitTest:point]; +} + +- (NSValue*)moxPosition { + return [mParent moxPosition]; +} + +- (NSValue*)moxSize { + return [mParent moxSize]; +} + +- (BOOL)disableChild:(id)child { + return NO; +} + +- (void)expire { + mParent = nil; + [super expire]; +} + +- (BOOL)isExpired { + MOZ_ASSERT((mParent == nil) == mIsExpired); + + return [super isExpired]; +} + +@end + @implementation MOXWebAreaAccessible - (NSURL*)moxURL { if ([self isExpired]) { return nil; } nsAutoString url; @@ -107,16 +209,60 @@ using namespace mozilla::a11y; [self moxPostNotification:@"AXLayoutComplete"]; } break; } [super handleAccessibleEvent:eventType]; } +- (NSArray*)rootGroupChildren { + // This method is meant to expose the doc's children to the root group. + return [super moxChildren]; +} + +- (NSArray*)moxUnignoredChildren { + if (id rootGroup = [self rootGroup]) { + return @[ [self rootGroup] ]; + } + + // There is no root group, expose the children here directly. + return [super moxUnignoredChildren]; +} + +- (id)rootGroup { + NSArray* children = [super moxUnignoredChildren]; + if ([children count] == 1 && + [[[children firstObject] moxUnignoredChildren] count] != 0) { + // We only need a root group if our document has multiple children or one + // child that is a leaf. + return nil; + } + + if (!mRootGroup) { + mRootGroup = [[MOXRootGroup alloc] initWithParent:self]; + } + + return mRootGroup; +} + +- (void)expire { + [mRootGroup expire]; + [super expire]; +} + +- (void)dealloc { + // This object can only be dealoced after the gecko accessible wrapper + // reference is released, and that happens after expire is called. + MOZ_ASSERT([self isExpired]); + [mRootGroup release]; + + [super dealloc]; +} + @end @implementation MOXSearchInfo - (id)initWithParameters:(NSDictionary*)params andRoot:(AccessibleOrProxy)root { if (id searchKeyParam = [params objectForKey:@"AXSearchKey"]) { mSearchKeys = [searchKeyParam isKindOfClass:[NSString class]] ? @[ searchKeyParam ]
--- a/accessible/mac/mozAccessible.mm +++ b/accessible/mac/mozAccessible.mm @@ -290,16 +290,25 @@ static const uint64_t kCacheInitialized AccessibleOrProxy parent = mGeckoAccessible.Parent(); if (parent.IsNull()) { return nil; } id nativeParent = GetNativeFromGeckoAccessible(parent); + if (parent.Role() == roles::DOCUMENT && + [nativeParent respondsToSelector:@selector(rootGroup)]) { + // Before returning a WebArea as parent, check to see if + // there is a generated root group that is an intermediate container. + if (id<mozAccessible> rootGroup = [nativeParent rootGroup]) { + nativeParent = rootGroup; + } + } + if (!nativeParent && mGeckoAccessible.IsAccessible()) { // Return native of root accessible if we have no direct parent. // XXX: need to return a sensible fallback in proxy case as well nativeParent = GetNativeFromGeckoAccessible( mGeckoAccessible.AsAccessible()->RootAccessible()); } return GetObjectOrRepresentedView(nativeParent);
--- a/accessible/tests/browser/mac/browser.ini +++ b/accessible/tests/browser/mac/browser.ini @@ -28,8 +28,9 @@ support-files = [browser_focus.js] [browser_whitespace.js] [browser_webarea.js] skip-if = os == 'mac' && !debug #1648813 [browser_text_basics.js] [browser_text_input.js] skip-if = os == 'mac' && debug # Bug 1664577 [browser_rotor.js] +[browser_rootgroup.js]
new file mode 100644 --- /dev/null +++ b/accessible/tests/browser/mac/browser_rootgroup.js @@ -0,0 +1,101 @@ +/* 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"; + +/** + * Test document with no single group child + */ +addAccessibleTask( + `<p id="p1">hello</p><p>world</p>`, + async (browser, accDoc) => { + let doc = accDoc.nativeInterface.QueryInterface( + Ci.nsIAccessibleMacInterface + ); + let docChildren = doc.getAttributeValue("AXChildren"); + is(docChildren.length, 1, "The document contains a root group"); + + let rootGroup = docChildren[0]; + is( + rootGroup.getAttributeValue("AXIdentifier"), + "root-group", + "Is generated root group" + ); + + is( + rootGroup.getAttributeValue("AXChildren").length, + 2, + "Root group has two children" + ); + + // From bottom-up + let p1 = getNativeInterface(accDoc, "p1"); + rootGroup = p1.getAttributeValue("AXParent"); + is( + rootGroup.getAttributeValue("AXIdentifier"), + "root-group", + "Is generated root group" + ); + } +); + +/** + * Test document with a top-level group + */ +addAccessibleTask( + `<div role="grouping" id="group"><p>hello</p><p>world</p></div>`, + async (browser, accDoc) => { + let doc = accDoc.nativeInterface.QueryInterface( + Ci.nsIAccessibleMacInterface + ); + let docChildren = doc.getAttributeValue("AXChildren"); + is(docChildren.length, 1, "The document contains a root group"); + + let rootGroup = docChildren[0]; + is( + rootGroup.getAttributeValue("AXDOMIdentifier"), + "group", + "Root group is a document element" + ); + } +); + +/** + * Test document with a single button + */ +addAccessibleTask( + `<button id="button">I am a button</button>`, + async (browser, accDoc) => { + let doc = accDoc.nativeInterface.QueryInterface( + Ci.nsIAccessibleMacInterface + ); + let docChildren = doc.getAttributeValue("AXChildren"); + is(docChildren.length, 1, "The document contains a root group"); + + let rootGroup = docChildren[0]; + is( + rootGroup.getAttributeValue("AXIdentifier"), + "root-group", + "Is generated root group" + ); + + let rootGroupChildren = rootGroup.getAttributeValue("AXChildren"); + is(rootGroupChildren.length, 1, "Root group has one children"); + + is( + rootGroupChildren[0].getAttributeValue("AXRole"), + "AXButton", + "Button is child of root group" + ); + + // From bottom-up + let button = getNativeInterface(accDoc, "button"); + rootGroup = button.getAttributeValue("AXParent"); + is( + rootGroup.getAttributeValue("AXIdentifier"), + "root-group", + "Is generated root group" + ); + } +);
--- a/accessible/tests/browser/mac/browser_whitespace.js +++ b/accessible/tests/browser/mac/browser_whitespace.js @@ -8,36 +8,40 @@ loadScripts({ name: "role.js", dir: MOCHITESTS_DIR }); /** * Test accessibles aren't created for linebreaks. */ addAccessibleTask(`hello<br>world`, async (browser, accDoc) => { let doc = accDoc.nativeInterface.QueryInterface(Ci.nsIAccessibleMacInterface); let docChildren = doc.getAttributeValue("AXChildren"); - is(docChildren.length, 2, "The document contains two children"); + is(docChildren.length, 1, "The document contains a root group"); + + let rootGroup = docChildren[0]; + let children = rootGroup.getAttributeValue("AXChildren"); + is(docChildren.length, 1, "The root group contains 2 children"); // verify first child is correct is( - docChildren[0].getAttributeValue("AXRole"), + children[0].getAttributeValue("AXRole"), "AXStaticText", "First child is a text node" ); is( - docChildren[0].getAttributeValue("AXValue"), + children[0].getAttributeValue("AXValue"), "hello", "First child is hello text" ); // verify second child is correct is( - docChildren[1].getAttributeValue("AXRole"), + children[1].getAttributeValue("AXRole"), "AXStaticText", "Second child is a text node" ); is( - docChildren[1].getAttributeValue("AXValue"), + children[1].getAttributeValue("AXValue"), "world ", "Second child is world text" ); // we have a trailing space here due to bug 1577028 });