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:
committed by
Facebook Github Bot
parent
1fb2c4ee76
commit
c07d8c14a4
@@ -283,6 +283,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
|||||||
public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder)
|
public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
final String nodeId = params.getString("id");
|
final String nodeId = params.getString("id");
|
||||||
|
final boolean ax = params.getBoolean("ax");
|
||||||
final SonarArray keyPath = params.getArray("path");
|
final SonarArray keyPath = params.getArray("path");
|
||||||
final SonarDynamic value = params.getDynamic("value");
|
final SonarDynamic value = params.getDynamic("value");
|
||||||
|
|
||||||
@@ -303,6 +304,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
descriptor.setValue(obj, path, value);
|
descriptor.setValue(obj, path, value);
|
||||||
|
responder.success(ax ? getAXNode(nodeId): null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -620,6 +622,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
|||||||
.put("data", data)
|
.put("data", data)
|
||||||
.put("children", children)
|
.put("children", children)
|
||||||
.put("attributes", attributes)
|
.put("attributes", attributes)
|
||||||
|
.put("decoration", descriptor.getAXDecoration(obj))
|
||||||
.put("extraInfo", descriptor.getExtraInfo(obj))
|
.put("extraInfo", descriptor.getExtraInfo(obj))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,6 +183,14 @@ public abstract class NodeDescriptor<T> {
|
|||||||
*/
|
*/
|
||||||
public abstract String getDecoration(T node) throws Exception;
|
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
|
* @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
|
* other tree or if it is not represented in the other tree bu has children that should show
|
||||||
|
|||||||
@@ -155,6 +155,12 @@ public class TextViewDescriptor extends NodeDescriptor<TextView> {
|
|||||||
return descriptor.getDecoration(node);
|
return descriptor.getDecoration(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getAXDecoration(TextView node) throws Exception {
|
||||||
|
final NodeDescriptor descriptor = descriptorForClass(View.class);
|
||||||
|
return descriptor.getAXDecoration(node);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String query, TextView node) throws Exception {
|
public boolean matches(String query, TextView node) throws Exception {
|
||||||
final NodeDescriptor descriptor = descriptorForClass(Object.class);
|
final NodeDescriptor descriptor = descriptorForClass(Object.class);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import com.facebook.sonar.plugins.inspector.InspectorValue;
|
|||||||
import com.facebook.sonar.plugins.inspector.Named;
|
import com.facebook.sonar.plugins.inspector.Named;
|
||||||
import com.facebook.sonar.plugins.inspector.NodeDescriptor;
|
import com.facebook.sonar.plugins.inspector.NodeDescriptor;
|
||||||
import com.facebook.sonar.plugins.inspector.Touch;
|
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.AccessibilityRoleUtil;
|
||||||
import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityUtil;
|
import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityUtil;
|
||||||
import com.facebook.sonar.plugins.inspector.descriptors.utils.EnumMapping;
|
import com.facebook.sonar.plugins.inspector.descriptors.utils.EnumMapping;
|
||||||
@@ -538,6 +539,11 @@ public class ViewDescriptor extends NodeDescriptor<View> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAXDecoration(View obj) {
|
||||||
|
return AccessibilityEvaluationUtil.isTalkbackFocusable(obj) ? "accessibility" : "";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String query, View node) throws Exception {
|
public boolean matches(String query, View node) throws Exception {
|
||||||
final String resourceId = getResourceId(node);
|
final String resourceId = getResourceId(node);
|
||||||
|
|||||||
@@ -291,6 +291,12 @@ public class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getAXDecoration(ViewGroup obj) throws Exception {
|
||||||
|
final NodeDescriptor descriptor = descriptorForClass(View.class);
|
||||||
|
return descriptor.getAXDecoration(obj);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String query, ViewGroup node) throws Exception {
|
public boolean matches(String query, ViewGroup node) throws Exception {
|
||||||
final NodeDescriptor descriptor = descriptorForClass(Object.class);
|
final NodeDescriptor descriptor = descriptorForClass(Object.class);
|
||||||
|
|||||||
@@ -141,6 +141,12 @@ public class LithoViewDescriptor extends NodeDescriptor<LithoView> {
|
|||||||
return descriptor.getDecoration(node);
|
return descriptor.getDecoration(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAXDecoration(LithoView node) throws Exception {
|
||||||
|
final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class);
|
||||||
|
return descriptor.getAXDecoration(node);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(String query, LithoView node) throws Exception {
|
public boolean matches(String query, LithoView node) throws Exception {
|
||||||
NodeDescriptor descriptor = descriptorForClass(Object.class);
|
NodeDescriptor descriptor = descriptorForClass(Object.class);
|
||||||
|
|||||||
@@ -803,15 +803,20 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onDataValueChanged = (path: Array<string>, value: any) => {
|
onDataValueChanged = (path: Array<string>, value: any) => {
|
||||||
const selected = this.state.inAXMode
|
const ax = this.state.inAXMode;
|
||||||
? this.state.AXselected
|
const id = ax ? this.state.AXselected : this.state.selected;
|
||||||
: this.state.selected;
|
this.client
|
||||||
this.client.send('setData', {id: selected, path, value});
|
.call('setData', {id, path, value, ax})
|
||||||
this.props.logger.track('usage', 'layout:value-changed', {
|
.then((element: Element) => {
|
||||||
id: selected,
|
if (ax) {
|
||||||
value: value,
|
this.dispatchAction({
|
||||||
path: path,
|
elements: [element],
|
||||||
|
type: 'UpdateAXElements',
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.props.logger.track('usage', 'layout:value-changed', {id, value, path});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderSidebar = () => {
|
renderSidebar = () => {
|
||||||
|
|||||||
@@ -331,6 +331,8 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
|
|||||||
return <DecorationImage src="icons/componentkit-logo.png" />;
|
return <DecorationImage src="icons/componentkit-logo.png" />;
|
||||||
case 'componentscript':
|
case 'componentscript':
|
||||||
return <DecorationImage src="icons/componentscript-logo.png" />;
|
return <DecorationImage src="icons/componentscript-logo.png" />;
|
||||||
|
case 'accessibility':
|
||||||
|
return <DecorationImage src="icons/accessibility.png" />;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
static/icons/accessibility.png
Normal file
BIN
static/icons/accessibility.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
Reference in New Issue
Block a user