Add icon to show which elements in ax tree are talkback-focusable

Summary: Puts an accessibility icon next to any elements in the ax tree that may be focused on when talkback is running to show that they are "accessibility-focusable". When any sidebar values are changed, the icon will show up/disappear accordingly.

Reviewed By: danielbuechele

Differential Revision: D9171781

fbshipit-source-id: f3b42624988aaef22040ac3325d745a12f0622db
This commit is contained in:
Sara Valderrama
2018-08-07 09:35:14 -07:00
committed by Facebook Github Bot
parent 1fb2c4ee76
commit c07d8c14a4
9 changed files with 51 additions and 9 deletions

View File

@@ -283,6 +283,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder)
throws Exception {
final String nodeId = params.getString("id");
final boolean ax = params.getBoolean("ax");
final SonarArray keyPath = params.getArray("path");
final SonarDynamic value = params.getDynamic("value");
@@ -303,6 +304,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
}
descriptor.setValue(obj, path, value);
responder.success(ax ? getAXNode(nodeId): null);
}
};
@@ -620,6 +622,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
.put("data", data)
.put("children", children)
.put("attributes", attributes)
.put("decoration", descriptor.getAXDecoration(obj))
.put("extraInfo", descriptor.getExtraInfo(obj))
.build();
}

View File

@@ -183,6 +183,14 @@ public abstract class NodeDescriptor<T> {
*/
public abstract String getDecoration(T node) throws Exception;
/**
* @return A string indicating how this element should be decorated in the AX tree. Check with the Sonar desktop
* app to see what values are supported.
*/
public String getAXDecoration(T node) throws Exception {
return null;
}
/**
* @return Extra data about the node indicating whether the node corresponds to a node in the
* other tree or if it is not represented in the other tree bu has children that should show

View File

@@ -155,6 +155,12 @@ public class TextViewDescriptor extends NodeDescriptor<TextView> {
return descriptor.getDecoration(node);
}
@Override
public @Nullable String getAXDecoration(TextView node) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class);
return descriptor.getAXDecoration(node);
}
@Override
public boolean matches(String query, TextView node) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Object.class);

View File

@@ -37,6 +37,7 @@ import com.facebook.sonar.plugins.inspector.InspectorValue;
import com.facebook.sonar.plugins.inspector.Named;
import com.facebook.sonar.plugins.inspector.NodeDescriptor;
import com.facebook.sonar.plugins.inspector.Touch;
import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityEvaluationUtil;
import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityRoleUtil;
import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityUtil;
import com.facebook.sonar.plugins.inspector.descriptors.utils.EnumMapping;
@@ -538,6 +539,11 @@ public class ViewDescriptor extends NodeDescriptor<View> {
return null;
}
@Override
public String getAXDecoration(View obj) {
return AccessibilityEvaluationUtil.isTalkbackFocusable(obj) ? "accessibility" : "";
}
@Override
public boolean matches(String query, View node) throws Exception {
final String resourceId = getResourceId(node);

View File

@@ -291,6 +291,12 @@ public class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
return null;
}
@Override
public @Nullable String getAXDecoration(ViewGroup obj) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class);
return descriptor.getAXDecoration(obj);
}
@Override
public boolean matches(String query, ViewGroup node) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Object.class);

View File

@@ -141,6 +141,12 @@ public class LithoViewDescriptor extends NodeDescriptor<LithoView> {
return descriptor.getDecoration(node);
}
@Override
public String getAXDecoration(LithoView node) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class);
return descriptor.getAXDecoration(node);
}
@Override
public boolean matches(String query, LithoView node) throws Exception {
NodeDescriptor descriptor = descriptorForClass(Object.class);

View File

@@ -803,15 +803,20 @@ export default class Layout extends SonarPlugin<InspectorState> {
}
onDataValueChanged = (path: Array<string>, value: any) => {
const selected = this.state.inAXMode
? this.state.AXselected
: this.state.selected;
this.client.send('setData', {id: selected, path, value});
this.props.logger.track('usage', 'layout:value-changed', {
id: selected,
value: value,
path: path,
const ax = this.state.inAXMode;
const id = ax ? this.state.AXselected : this.state.selected;
this.client
.call('setData', {id, path, value, ax})
.then((element: Element) => {
if (ax) {
this.dispatchAction({
elements: [element],
type: 'UpdateAXElements',
});
}
});
this.props.logger.track('usage', 'layout:value-changed', {id, value, path});
};
renderSidebar = () => {

View File

@@ -331,6 +331,8 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
return <DecorationImage src="icons/componentkit-logo.png" />;
case 'componentscript':
return <DecorationImage src="icons/componentscript-logo.png" />;
case 'accessibility':
return <DecorationImage src="icons/accessibility.png" />;
default:
return null;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB