mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
Bug 1654679 - Add selected text marker range to text selection changed events. r=morgan
Differential Revision: https://phabricator.services.mozilla.com/D84616
This commit is contained in:
parent
0bd1d12978
commit
70a126786a
@ -166,7 +166,8 @@ nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
|
||||
// If the selection is collapsed, invalidate our text selection cache.
|
||||
MOXTextMarkerDelegate* delegate =
|
||||
[MOXTextMarkerDelegate getOrCreateForDoc:aEvent->Document()];
|
||||
[delegate invalidateSelection];
|
||||
int32_t caretOffset = event->GetCaretOffset();
|
||||
[delegate setSelectionFrom:eventTarget at:caretOffset to:eventTarget at:caretOffset];
|
||||
}
|
||||
|
||||
[nativeAcc handleAccessibleEvent:eventType];
|
||||
|
@ -100,7 +100,7 @@ void ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset, bool aIsSele
|
||||
if (aIsSelectionCollapsed) {
|
||||
// If selection is collapsed, invalidate selection.
|
||||
MOXTextMarkerDelegate* delegate = [MOXTextMarkerDelegate getOrCreateForDoc:aTarget->Document()];
|
||||
[delegate invalidateSelection];
|
||||
[delegate setSelectionFrom:aTarget at:aOffset to:aTarget at:aOffset];
|
||||
}
|
||||
|
||||
if (wrapper) {
|
||||
|
@ -840,10 +840,21 @@ enum AXTextStateChangeType {
|
||||
case nsIAccessibleEvent::EVENT_SELECTION_WITHIN:
|
||||
[self moxPostNotification:NSAccessibilitySelectedChildrenChangedNotification];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
||||
[self moxPostNotification:NSAccessibilitySelectedTextChangedNotification];
|
||||
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: {
|
||||
// We consider any caret move event to be a selected text change event.
|
||||
// So dispatching an event for EVENT_TEXT_SELECTION_CHANGED would be reduntant.
|
||||
id<MOXTextMarkerSupport> delegate = [self moxTextMarkerDelegate];
|
||||
id selectedRange = [delegate moxSelectedTextMarkerRange];
|
||||
NSDictionary* userInfo = @{
|
||||
@"AXTextChangeElement": self,
|
||||
@"AXSelectedTextMarkerRange": (selectedRange ? selectedRange : [NSNull null])
|
||||
};
|
||||
|
||||
mozAccessible* webArea = GetNativeFromGeckoAccessible([self geckoDocument]);
|
||||
[webArea moxPostNotification:NSAccessibilitySelectedTextChangedNotification withUserInfo:userInfo];
|
||||
[self moxPostNotification:NSAccessibilitySelectedTextChangedNotification withUserInfo:userInfo];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,53 @@ function testValueChangedEventData(
|
||||
is(str, expectedWordAtLeft);
|
||||
}
|
||||
|
||||
async function synthKeyAndTestEvent(
|
||||
function matchWebArea(expectedId) {
|
||||
return (iface, data) => {
|
||||
return (
|
||||
iface.getAttributeValue("AXRole") == "AXWebArea" &&
|
||||
!!data &&
|
||||
data.AXTextChangeElement.getAttributeValue("AXDOMIdentifier") ==
|
||||
expectedId
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function matchInput(expectedId) {
|
||||
return (iface, data) =>
|
||||
iface.getAttributeValue("AXDOMIdentifier") == expectedId && !!data;
|
||||
}
|
||||
|
||||
async function synthKeyAndTestSelectionChanged(
|
||||
synthKey,
|
||||
synthEvent,
|
||||
expectedId,
|
||||
expectedSelectionString
|
||||
) {
|
||||
let selectionChangedEvents = Promise.all([
|
||||
waitForMacEventWithInfo("AXSelectedTextChanged", matchWebArea(expectedId)),
|
||||
waitForMacEventWithInfo("AXSelectedTextChanged", matchInput(expectedId)),
|
||||
]);
|
||||
|
||||
EventUtils.synthesizeKey(synthKey, synthEvent);
|
||||
let [, inputEvent] = await selectionChangedEvents;
|
||||
is(
|
||||
inputEvent.data.AXTextChangeElement.getAttributeValue("AXDOMIdentifier"),
|
||||
expectedId,
|
||||
"Correct AXTextChangeElement"
|
||||
);
|
||||
|
||||
let rangeString = inputEvent.macIface.getParameterizedAttributeValue(
|
||||
"AXStringForTextMarkerRange",
|
||||
inputEvent.data.AXSelectedTextMarkerRange
|
||||
);
|
||||
is(
|
||||
rangeString,
|
||||
expectedSelectionString,
|
||||
`selection has correct value (${expectedSelectionString})`
|
||||
);
|
||||
}
|
||||
|
||||
async function synthKeyAndTestValueChanged(
|
||||
synthKey,
|
||||
synthEvent,
|
||||
expectedId,
|
||||
@ -73,22 +119,14 @@ async function synthKeyAndTestEvent(
|
||||
expectedWordAtLeft
|
||||
) {
|
||||
let valueChangedEvents = Promise.all([
|
||||
waitForMacEventWithInfo("AXValueChanged", (iface, data) => {
|
||||
return (
|
||||
iface.getAttributeValue("AXRole") == "AXWebArea" &&
|
||||
!!data &&
|
||||
data.AXTextChangeElement.getAttributeValue("AXDOMIdentifier") == "input"
|
||||
);
|
||||
}),
|
||||
waitForMacEventWithInfo(
|
||||
"AXValueChanged",
|
||||
(iface, data) =>
|
||||
iface.getAttributeValue("AXDOMIdentifier") == "input" && !!data
|
||||
),
|
||||
waitForMacEventWithInfo("AXSelectedTextChanged", matchWebArea(expectedId)),
|
||||
waitForMacEventWithInfo("AXSelectedTextChanged", matchInput(expectedId)),
|
||||
waitForMacEventWithInfo("AXValueChanged", matchWebArea(expectedId)),
|
||||
waitForMacEventWithInfo("AXValueChanged", matchInput(expectedId)),
|
||||
]);
|
||||
|
||||
EventUtils.synthesizeKey(synthKey, synthEvent);
|
||||
let [webareaEvent, inputEvent] = await valueChangedEvents;
|
||||
let [, , webareaEvent, inputEvent] = await valueChangedEvents;
|
||||
|
||||
testValueChangedEventData(
|
||||
webareaEvent.macIface,
|
||||
@ -115,19 +153,23 @@ addAccessibleTask(
|
||||
let input = getNativeInterface(accDoc, "input");
|
||||
ok(!input.getAttributeValue("AXFocused"), "input is not focused");
|
||||
ok(input.isAttributeSettable("AXFocused"), "input is focusable");
|
||||
let focusChanged = waitForMacEvent(
|
||||
"AXFocusedUIElementChanged",
|
||||
iface => iface.getAttributeValue("AXDOMIdentifier") == "input"
|
||||
);
|
||||
let events = Promise.all([
|
||||
waitForMacEvent(
|
||||
"AXFocusedUIElementChanged",
|
||||
iface => iface.getAttributeValue("AXDOMIdentifier") == "input"
|
||||
),
|
||||
waitForMacEventWithInfo("AXSelectedTextChanged", matchWebArea("input")),
|
||||
waitForMacEventWithInfo("AXSelectedTextChanged", matchInput("input")),
|
||||
]);
|
||||
input.setAttributeValue("AXFocused", true);
|
||||
await focusChanged;
|
||||
await events;
|
||||
|
||||
async function testTextInput(
|
||||
synthKey,
|
||||
expectedChangeValue,
|
||||
expectedWordAtLeft
|
||||
) {
|
||||
await synthKeyAndTestEvent(
|
||||
await synthKeyAndTestValueChanged(
|
||||
synthKey,
|
||||
null,
|
||||
"input",
|
||||
@ -153,7 +195,7 @@ addAccessibleTask(
|
||||
await testTextInput("d", "d", "world");
|
||||
|
||||
async function testTextDelete(expectedChangeValue, expectedWordAtLeft) {
|
||||
await synthKeyAndTestEvent(
|
||||
await synthKeyAndTestValueChanged(
|
||||
"KEY_Backspace",
|
||||
null,
|
||||
"input",
|
||||
@ -165,5 +207,33 @@ addAccessibleTask(
|
||||
|
||||
await testTextDelete("d", "worl");
|
||||
await testTextDelete("l", "wor");
|
||||
|
||||
await synthKeyAndTestSelectionChanged("KEY_ArrowLeft", null, "input", "");
|
||||
await synthKeyAndTestSelectionChanged(
|
||||
"KEY_ArrowLeft",
|
||||
{ shiftKey: true },
|
||||
"input",
|
||||
"o"
|
||||
);
|
||||
await synthKeyAndTestSelectionChanged(
|
||||
"KEY_ArrowLeft",
|
||||
{ shiftKey: true },
|
||||
"input",
|
||||
"wo"
|
||||
);
|
||||
await synthKeyAndTestSelectionChanged("KEY_ArrowLeft", null, "input", "");
|
||||
await synthKeyAndTestSelectionChanged(
|
||||
"KEY_Home",
|
||||
{ shiftKey: true },
|
||||
"input",
|
||||
"hello "
|
||||
);
|
||||
await synthKeyAndTestSelectionChanged("KEY_ArrowLeft", null, "input", "");
|
||||
await synthKeyAndTestSelectionChanged(
|
||||
"KEY_ArrowRight",
|
||||
{ shiftKey: true, altKey: true },
|
||||
"input",
|
||||
"hello"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user