Live update sidebar with click and focus accessibility events
Summary: Lets AX inspector live update the sidebar when a view is clicked (state may change) or accessibility focus changes (previously only updated the sidebar live if it became the focused element). Differential Revision: D9489376 fbshipit-source-id: 8959f722370ce1d3a622b24c7b049b03f0d662e6
This commit is contained in:
committed by
Facebook Github Bot
parent
61258d4b64
commit
364883f661
@@ -221,7 +221,8 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
||||
final SonarArray.Builder result = new SonarArray.Builder();
|
||||
|
||||
// getNodes called to refresh accessibility focus
|
||||
final boolean forFocusEvent = params.getBoolean("forFocusEvent");
|
||||
final boolean forAccessibilityEvent = params.getBoolean("forAccessibilityEvent");
|
||||
final String selected = params.getString("selected");
|
||||
|
||||
for (int i = 0, count = ids.length(); i < count; i++) {
|
||||
final String id = ids.getString(i);
|
||||
@@ -231,7 +232,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
||||
if (node == null) {
|
||||
|
||||
// some nodes may be null since we are searching through all current and previous known nodes
|
||||
if (forFocusEvent) {
|
||||
if (forAccessibilityEvent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -243,11 +244,11 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
||||
return;
|
||||
} else {
|
||||
|
||||
// only need to get the focused node in this case
|
||||
if (forFocusEvent) {
|
||||
if (node.getObject("extraInfo").getBoolean("focused")) {
|
||||
// always add currently selected node for live updates to the sidebar
|
||||
// also add focused node for updates
|
||||
if (forAccessibilityEvent) {
|
||||
if (id.equals(selected) || node.getObject("extraInfo").getBoolean("focused")) {
|
||||
result.put(node);
|
||||
break;
|
||||
}
|
||||
|
||||
// normal getNodes call, put any nodes in result
|
||||
|
||||
@@ -101,6 +101,12 @@ public class ApplicationDescriptor extends NodeDescriptor<ApplicationWrapper> {
|
||||
new SonarObject.Builder()
|
||||
.put("isFocus", false)
|
||||
.build());
|
||||
} else if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) {
|
||||
mConnection.send("axFocusEvent",
|
||||
new SonarObject.Builder()
|
||||
.put("isFocus", false)
|
||||
.put("isClick", true)
|
||||
.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ type UpdateAXElementsArgs = {|
|
||||
|
||||
type AXFocusEventResult = {|
|
||||
isFocus: boolean,
|
||||
isClick?: boolean,
|
||||
|};
|
||||
|
||||
type SetRootArgs = {|
|
||||
@@ -89,7 +90,7 @@ type GetNodesResult = {|
|
||||
type GetNodesOptions = {|
|
||||
force: boolean,
|
||||
ax: boolean,
|
||||
forFocusEvent?: boolean,
|
||||
forAccessibilityEvent?: boolean,
|
||||
|};
|
||||
|
||||
type TrackArgs = {|
|
||||
@@ -519,36 +520,51 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
});
|
||||
});
|
||||
|
||||
this.client.subscribe('axFocusEvent', ({isFocus}: AXFocusEventResult) => {
|
||||
this.props.logger.track('usage', 'accessibility:focusEvent', {
|
||||
isFocus,
|
||||
inAXMode: this.state.inAXMode,
|
||||
});
|
||||
this.client.subscribe(
|
||||
'axFocusEvent',
|
||||
({isFocus, isClick}: AXFocusEventResult) => {
|
||||
this.props.logger.track('usage', 'accessibility:focusEvent', {
|
||||
isFocus,
|
||||
isClick,
|
||||
inAXMode: this.state.inAXMode,
|
||||
});
|
||||
|
||||
// if focusing, need to update all elements in the tree because
|
||||
// we don't know which one now has focus
|
||||
const keys = isFocus ? Object.keys(this.state.AXelements) : [];
|
||||
// if focusing, need to update all elements in the tree because
|
||||
// we don't know which one now has focus
|
||||
const keys = isFocus ? Object.keys(this.state.AXelements) : [];
|
||||
|
||||
// if unfocusing and currently focused element exists, update only the
|
||||
// focused element (and only if it is/was loaded in tree)
|
||||
if (
|
||||
!isFocus &&
|
||||
this.state.AXfocused &&
|
||||
this.state.AXelements[this.state.AXfocused]
|
||||
) {
|
||||
keys.push(this.state.AXfocused);
|
||||
}
|
||||
// if unfocusing, update only the focused and selected elements and
|
||||
// only if they have been loaded into tree
|
||||
if (!isFocus) {
|
||||
if (
|
||||
this.state.AXfocused &&
|
||||
this.state.AXelements[this.state.AXfocused]
|
||||
) {
|
||||
keys.push(this.state.AXfocused);
|
||||
}
|
||||
|
||||
this.getNodes(keys, {force: true, ax: true, forFocusEvent: true}).then(
|
||||
(elements: Array<Element>) => {
|
||||
// also update current selected element live, so data shown is not invalid
|
||||
if (
|
||||
this.state.AXselected &&
|
||||
this.state.AXelements[this.state.AXselected]
|
||||
) {
|
||||
keys.push(this.state.AXselected);
|
||||
}
|
||||
}
|
||||
|
||||
this.getNodes(keys, {
|
||||
force: true,
|
||||
ax: true,
|
||||
forAccessibilityEvent: true,
|
||||
}).then((elements: Array<Element>) => {
|
||||
this.dispatchAction({
|
||||
elements,
|
||||
forFocusEvent: true,
|
||||
forFocusEvent: !isClick,
|
||||
type: 'UpdateAXElements',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
this.client.subscribe(
|
||||
'invalidateAX',
|
||||
@@ -668,7 +684,7 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
ids: Array<ElementID> = [],
|
||||
options: GetNodesOptions,
|
||||
): Promise<Array<Element>> {
|
||||
const {force, ax, forFocusEvent} = options;
|
||||
const {force, ax, forAccessibilityEvent} = options;
|
||||
if (!force) {
|
||||
const elems = ax ? this.state.AXelements : this.state.elements;
|
||||
// always force undefined elements and elements that need to be expanded
|
||||
@@ -692,7 +708,8 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
return this.client
|
||||
.call(ax ? 'getAXNodes' : 'getNodes', {
|
||||
ids,
|
||||
forFocusEvent,
|
||||
forAccessibilityEvent,
|
||||
selected: this.state.AXselected,
|
||||
})
|
||||
.then(({elements}: GetNodesResult) => {
|
||||
this.props.logger.trackTimeSince(mark, eventName);
|
||||
|
||||
Reference in New Issue
Block a user