Bug 1846312 - Use AXAttachment to represent non-text controls in an attributed string. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D184958
This commit is contained in:
Eitan Isaacson 2023-08-04 17:11:23 +00:00
parent 54a9eedf39
commit 0135568045
3 changed files with 63 additions and 34 deletions

View File

@ -436,27 +436,28 @@ NSAttributedString* GeckoTextMarkerRange::AttributedText() const {
: mRange;
nsAutoString text;
RefPtr<AccAttributes> currentRun = nullptr;
RefPtr<AccAttributes> currentRun = range.Start().GetTextAttributes();
Accessible* runAcc = range.Start().mAcc;
for (TextLeafRange segment : range) {
TextLeafPoint start = segment.Start();
if (start.mAcc->IsTextField() && start.mAcc->ChildCount() == 0) {
continue;
}
if (!currentRun) {
// This is the first segment that isn't an empty input.
currentRun = start.GetTextAttributes();
}
TextLeafPoint attributesNext;
do {
if (start.mAcc->IsText()) {
attributesNext = start.FindTextAttrsStart(eDirNext, false);
} else {
// If this segment isn't a text leaf, but another kind of inline element
// like a control, just consider this full segment one "attributes run".
attributesNext = segment.End();
}
if (attributesNext == start) {
// XXX: FindTextAttrsStart should not return the same point.
break;
}
RefPtr<AccAttributes> attributes = start.GetTextAttributes();
MOZ_ASSERT(attributes);
if (attributes && !attributes->Equal(currentRun)) {
if (!currentRun || !attributes || !attributes->Equal(currentRun)) {
// If currentRun is null this is a non-text control and we will
// append a run with no text or attributes, just an AXAttachment
// referencing this accessible.
AppendTextToAttributedString(str, runAcc, text, currentRun);
text.Truncate();
currentRun = attributes;

View File

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "MacUtils.h"
#include "mozAccessible.h"
#include "LocalAccessible.h"
#include "DocAccessible.h"
@ -83,6 +84,12 @@ static NSColor* ColorFromColor(const Color& aColor) {
NSDictionary* StringAttributesFromAccAttributes(AccAttributes* aAttributes,
Accessible* aContainer) {
if (!aAttributes) {
if (mozAccessible* mozAcc = GetNativeFromGeckoAccessible(aContainer)) {
// If we don't have attributes provided this is probably a control like
// a button or empty entry. Just provide the accessible as an
// AXAttachment.
return @{@"AXAttachment" : mozAcc};
}
return @{};
}

View File

@ -115,7 +115,9 @@ addAccessibleTask(
);
// Test getting a span of attributed text that includes an empty input element.
addAccessibleTask(`hello <input id="input"> world`, async (browser, accDoc) => {
addAccessibleTask(
`hello <input id="input"> world<button></button>`,
async (browser, accDoc) => {
let macDoc = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
@ -138,7 +140,26 @@ addAccessibleTask(`hello <input id="input"> world`, async (browser, accDoc) => {
range
);
is(attributedText.length, 1, "Empty input does not break up attribute run.");
is(attributedText[0].string, `hello world `, "Attributed string is correct");
is(text, `hello world `, "Unattributed string is correct");
});
is(
attributedText.length,
4,
"Should be 4 attribute runs for 2 texts, input and button"
);
is(attributedText[0].string, `hello `, "Attributed string is correct");
ok(
!attributedText[0].AXAttachment,
"Regular string attributes run doesn't have attachment"
);
is(
attributedText[1].AXAttachment.getAttributeValue("AXRole"),
"AXTextField",
"Entry text attribute run has correct attachment"
);
is(
attributedText[3].AXAttachment.getAttributeValue("AXRole"),
"AXButton",
"Button text attribute run has correct attachment"
);
is(text, `hello world${kEmbedChar}`, "Unattributed string is correct");
}
);