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
This commit is contained in:
Eitan Isaacson 2020-12-11 05:10:44 +00:00
parent 6820632f46
commit b65404fb2c
4 changed files with 71 additions and 0 deletions

View File

@ -284,6 +284,12 @@
// AXEditableAncestor
- (id _Nullable)moxEditableAncestor;
// AXHighestEditableAncestor
- (id _Nullable)moxHighestEditableAncestor;
// AXFocusableAncestor
- (id _Nullable)moxFocusableAncestor;
// AXARIAAtomic
- (NSNumber* _Nullable)moxARIAAtomic;

View File

@ -208,6 +208,12 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
// override
- (id)moxEditableAncestor;
// override
- (id)moxHighestEditableAncestor;
// override
- (id)moxFocusableAncestor;
#ifndef RELEASE_OR_BETA
// override
- (NSString*)moxMozDebugDescription;

View File

@ -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;

View File

@ -178,3 +178,34 @@ addAccessibleTask(
);
}
);
/**
* test nested content editables and their ancestor getters.
*/
addAccessibleTask(
`<div id="outer" role="textbox" contenteditable="true">
<p id="p">Bob <a href="#" id="link">Loblaw's</a></p>
<div id="inner" role="textbox" contenteditable="true">
Law <a href="#" id="inner_link">Blog</a>
</div>
</div>`,
(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"
);
}
);