Expand trees together - including fragments, not including litho components
Summary: When expanding one tree, the other tree also expands. This expanding jumps over fragments (which are not in the accessibility tree) so that the trees can stay in sync even when there are extra wrappers in the main tree. Need to figure out functionality for litho components (these simply don't expand together right now since the relationship between the trees at these nodes are less obvious). Differential Revision: D8943229 fbshipit-source-id: 289c3511a6495508b45a62da13ae4c50209e6118
This commit is contained in:
committed by
Facebook Github Bot
parent
2155c7799f
commit
c57e6e4396
@@ -490,6 +490,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
|
||||
.put("children", children)
|
||||
.put("attributes", attributes)
|
||||
.put("decoration", descriptor.getDecoration(obj))
|
||||
.put("extraInfo", descriptor.getExtraInfo(obj))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,15 @@ public abstract class NodeDescriptor<T> {
|
||||
*/
|
||||
public abstract String getDecoration(T node) throws Exception;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* up, etc.
|
||||
*/
|
||||
public SonarObject getExtraInfo(T node) {
|
||||
return new SonarObject.Builder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test this node against a given query to see if it matches. This is used for finding search
|
||||
* results.
|
||||
|
||||
@@ -64,6 +64,12 @@ public class DialogFragmentDescriptor extends NodeDescriptor<DialogFragment> {
|
||||
return descriptor.getAttributes(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SonarObject getExtraInfo(DialogFragment node) {
|
||||
final NodeDescriptor descriptor = descriptorForClass(Fragment.class);
|
||||
return descriptor.getExtraInfo(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlighted(DialogFragment node, boolean selected) throws Exception {
|
||||
final NodeDescriptor descriptor = descriptorForClass(Dialog.class);
|
||||
|
||||
@@ -77,6 +77,11 @@ public class FragmentDescriptor extends NodeDescriptor<Fragment> {
|
||||
return Arrays.asList(new Named<>("id", resourceId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SonarObject getExtraInfo(Fragment node) {
|
||||
return new SonarObject.Builder().put("nonAXWithAXChild", true).build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getResourceId(Fragment node) {
|
||||
final int id = node.getId();
|
||||
|
||||
@@ -64,6 +64,12 @@ public class SupportDialogFragmentDescriptor extends NodeDescriptor<DialogFragme
|
||||
return descriptor.getAttributes(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SonarObject getExtraInfo(DialogFragment node) {
|
||||
final NodeDescriptor descriptor = descriptorForClass(Fragment.class);
|
||||
return descriptor.getExtraInfo(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlighted(DialogFragment node, boolean selected) throws Exception {
|
||||
final NodeDescriptor descriptor = descriptorForClass(Dialog.class);
|
||||
|
||||
@@ -78,6 +78,11 @@ public class SupportFragmentDescriptor extends NodeDescriptor<Fragment> {
|
||||
"id", ResourcesUtil.getIdStringQuietly(node.getContext(), node.getResources(), id)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SonarObject getExtraInfo(Fragment node) {
|
||||
return new SonarObject.Builder().put("nonAXWithAXChild", true).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlighted(Fragment node, boolean selected) throws Exception {
|
||||
if (node.getView() == null) {
|
||||
|
||||
@@ -103,6 +103,7 @@ public class InspectorSonarPluginTest {
|
||||
.put("children", new SonarArray.Builder().put("test"))
|
||||
.put("attributes", new SonarArray.Builder())
|
||||
.put("decoration", (String) null)
|
||||
.put("extraInfo", new SonarObject.Builder())
|
||||
.build()));
|
||||
}
|
||||
|
||||
@@ -138,7 +139,8 @@ public class InspectorSonarPluginTest {
|
||||
.put("data", new SonarObject.Builder())
|
||||
.put("children", new SonarArray.Builder())
|
||||
.put("attributes", new SonarArray.Builder())
|
||||
.put("decoration", (String) null)))
|
||||
.put("decoration", (String) null)
|
||||
.put("extraInfo", new SonarObject.Builder())))
|
||||
.build()));
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,13 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
expanded: expand,
|
||||
},
|
||||
},
|
||||
AXelements: {
|
||||
...state.AXelements,
|
||||
[key]: {
|
||||
...state.AXelements[key],
|
||||
expanded: expand,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@@ -322,9 +329,7 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
}
|
||||
|
||||
return this.performInitialExpand(
|
||||
ax
|
||||
? this.state.AXelements[element.children[0]]
|
||||
: this.state.elements[element.children[0]],
|
||||
(ax ? this.state.AXelements : this.state.elements)[element.children[0]],
|
||||
ax,
|
||||
);
|
||||
});
|
||||
@@ -540,11 +545,22 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
performance.mark('LayoutInspectorExpandElement');
|
||||
if (expand) {
|
||||
return this.getChildren(key, ax).then((elements: Array<Element>) => {
|
||||
this.props.logger.trackTimeSince('LayoutInspectorExpandElement');
|
||||
this.dispatchAction({
|
||||
elements,
|
||||
type: ax ? 'UpdateAXElements' : 'UpdateElements',
|
||||
});
|
||||
|
||||
// only expand extra components in the main tree when in AX mode
|
||||
if (this.state.inAXMode && !ax) {
|
||||
// expand child wrapper elements that aren't in the AX tree (e.g. fragments)
|
||||
for (const childElem of elements) {
|
||||
if (childElem.extraInfo.nonAXWithAXChild) {
|
||||
this.setElementExpanded(childElem.id, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.props.logger.trackTimeSince('LayoutInspectorExpandElement');
|
||||
return Promise.resolve(elements);
|
||||
});
|
||||
} else {
|
||||
@@ -583,19 +599,9 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
onElementExpanded = (key: ElementID, deep: boolean) => {
|
||||
if (deep) {
|
||||
this.deepExpandElement(key, false);
|
||||
} else {
|
||||
this.expandElement(key, false);
|
||||
}
|
||||
this.props.logger.track('usage', 'layout:element-expanded', {
|
||||
id: key,
|
||||
deep: deep,
|
||||
});
|
||||
};
|
||||
|
||||
onAXElementExpanded = (key: ElementID, deep: boolean) => {
|
||||
if (deep) {
|
||||
this.deepExpandElement(key, true);
|
||||
} else {
|
||||
this.expandElement(key, false);
|
||||
this.expandElement(key, true);
|
||||
}
|
||||
this.props.logger.track('usage', 'layout:element-expanded', {
|
||||
@@ -621,11 +627,6 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
this.getNodes([key], true, false).then((elements: Array<Element>) => {
|
||||
this.dispatchAction({elements, type: 'UpdateElements'});
|
||||
});
|
||||
});
|
||||
|
||||
onAXElementSelected = debounce((key: ElementID) => {
|
||||
this.dispatchAction({key, type: 'SelectElement'});
|
||||
this.client.send('setHighlighted', {id: key});
|
||||
this.getNodes([key], true, true).then((elements: Array<Element>) => {
|
||||
this.dispatchAction({elements, type: 'UpdateAXElements'});
|
||||
});
|
||||
@@ -635,10 +636,6 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
this.client.send('setHighlighted', {id: key});
|
||||
});
|
||||
|
||||
onAXElementHovered = debounce((key: ?ElementID) => {
|
||||
this.client.send('setHighlighted', {id: key});
|
||||
});
|
||||
|
||||
onDataValueChanged = (path: Array<string>, value: any) => {
|
||||
const selected = this.state.inAXMode
|
||||
? this.state.AXselected
|
||||
@@ -757,9 +754,9 @@ export default class Layout extends SonarPlugin<InspectorState> {
|
||||
{AXinitialised && inAXMode ? <VerticalRule /> : null}
|
||||
{AXinitialised && inAXMode ? (
|
||||
<AXElementsInspector
|
||||
onElementSelected={this.onAXElementSelected}
|
||||
onElementHovered={this.onAXElementHovered}
|
||||
onElementExpanded={this.onAXElementExpanded}
|
||||
onElementSelected={this.onElementSelected}
|
||||
onElementHovered={this.onElementHovered}
|
||||
onElementExpanded={this.onElementExpanded}
|
||||
onValueChanged={this.onDataValueChanged}
|
||||
selected={AXselected}
|
||||
searchResults={null}
|
||||
|
||||
@@ -34,6 +34,10 @@ export type ElementAttribute = {|
|
||||
value: string,
|
||||
|};
|
||||
|
||||
export type ElementExtraInfo = {|
|
||||
nonAXWithAXChild?: boolean,
|
||||
|};
|
||||
|
||||
export type Element = {|
|
||||
id: ElementID,
|
||||
name: string,
|
||||
@@ -42,6 +46,7 @@ export type Element = {|
|
||||
attributes: Array<ElementAttribute>,
|
||||
data: ElementData,
|
||||
decoration: string,
|
||||
extraInfo: ElementExtraInfo,
|
||||
|};
|
||||
|
||||
export default class ElementsInspector extends Component<{
|
||||
|
||||
Reference in New Issue
Block a user