From b65404fb2cba01ff998a5dfa09a91d297938837d Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Fri, 11 Dec 2020 05:10:44 +0000 Subject: [PATCH] Bug 1680277 - 1/3: Add editable and focusable ancestor getters. r=morgan For focusable ancestor, just use editable ancestor since the IPC toll on finding closest focusable ancestor isn't worth it. Differential Revision: https://phabricator.services.mozilla.com/D99311 --- accessible/mac/MOXAccessibleProtocol.h | 6 ++++ accessible/mac/mozAccessible.h | 6 ++++ accessible/mac/mozAccessible.mm | 28 +++++++++++++++++ accessible/tests/browser/mac/browser_input.js | 31 +++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/accessible/mac/MOXAccessibleProtocol.h b/accessible/mac/MOXAccessibleProtocol.h index d25d467d8014..07ea53f27f2d 100644 --- a/accessible/mac/MOXAccessibleProtocol.h +++ b/accessible/mac/MOXAccessibleProtocol.h @@ -284,6 +284,12 @@ // AXEditableAncestor - (id _Nullable)moxEditableAncestor; +// AXHighestEditableAncestor +- (id _Nullable)moxHighestEditableAncestor; + +// AXFocusableAncestor +- (id _Nullable)moxFocusableAncestor; + // AXARIAAtomic - (NSNumber* _Nullable)moxARIAAtomic; diff --git a/accessible/mac/mozAccessible.h b/accessible/mac/mozAccessible.h index 694bf28d33d0..673bdad4714d 100644 --- a/accessible/mac/mozAccessible.h +++ b/accessible/mac/mozAccessible.h @@ -208,6 +208,12 @@ inline mozAccessible* GetNativeFromGeckoAccessible( // override - (id)moxEditableAncestor; +// override +- (id)moxHighestEditableAncestor; + +// override +- (id)moxFocusableAncestor; + #ifndef RELEASE_OR_BETA // override - (NSString*)moxMozDebugDescription; diff --git a/accessible/mac/mozAccessible.mm b/accessible/mac/mozAccessible.mm index 92057996ea6e..a1f518a38230 100644 --- a/accessible/mac/mozAccessible.mm +++ b/accessible/mac/mozAccessible.mm @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #import "mozAccessible.h" +#include "MOXAccessibleBase.h" #import "MacUtils.h" #import "mozView.h" @@ -831,6 +832,33 @@ struct RoleDescrComparator { return nil; } +- (id)moxHighestEditableAncestor { + id highestAncestor = [self moxEditableAncestor]; + while ([highestAncestor conformsToProtocol:@protocol(MOXAccessible)]) { + id ancestorParent = [highestAncestor moxUnignoredParent]; + if (![ancestorParent conformsToProtocol:@protocol(MOXAccessible)]) { + break; + } + + id higherAncestor = [ancestorParent moxEditableAncestor]; + + if (!higherAncestor) { + break; + } + + highestAncestor = higherAncestor; + } + + return highestAncestor; +} + +- (id)moxFocusableAncestor { + // XXX: Checking focusable state up the chain can be expensive. For now, + // we can just return AXEditableAncestor since the main use case for this + // is rich text editing with links. + return [self moxEditableAncestor]; +} + #ifndef RELEASE_OR_BETA - (NSString*)moxMozDebugDescription { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; diff --git a/accessible/tests/browser/mac/browser_input.js b/accessible/tests/browser/mac/browser_input.js index 35f05cfb0b2a..6b124880c7cf 100644 --- a/accessible/tests/browser/mac/browser_input.js +++ b/accessible/tests/browser/mac/browser_input.js @@ -178,3 +178,34 @@ addAccessibleTask( ); } ); + +/** + * test nested content editables and their ancestor getters. + */ +addAccessibleTask( + `
+

Bob Loblaw's

+
+ Law Blog +
+
`, + (browser, accDoc) => { + let link = getNativeInterface(accDoc, "link"); + let innerLink = getNativeInterface(accDoc, "inner_link"); + + let idmatches = (elem, id) => { + is(elem.getAttributeValue("AXDOMIdentifier"), id, "Matches ID"); + }; + + idmatches(link.getAttributeValue("AXEditableAncestor"), "outer"); + idmatches(link.getAttributeValue("AXFocusableAncestor"), "outer"); + idmatches(link.getAttributeValue("AXHighestEditableAncestor"), "outer"); + + idmatches(innerLink.getAttributeValue("AXEditableAncestor"), "inner"); + idmatches(innerLink.getAttributeValue("AXFocusableAncestor"), "inner"); + idmatches( + innerLink.getAttributeValue("AXHighestEditableAncestor"), + "outer" + ); + } +);