(server) Add New Parameter And Functions for Select Subscriber

Summary:
- add type to represent the returned component tree
```
expected data:
{
  [nodeID1]: [subtree1],
  [nodeID2]: [subtree2],
  ...
}
example:
{
   id1: {
    id2: {
      id3: {
        id4: {},
        id5: {
          id6: {}
        }
      }
    }
  }
}
```
- add functions to deal with a tree
  - `_getElementLeaves` for finding ids that don't have any child given the tree structure
  - `_getPathForNode` for finding path (similar to previous path parameter) for given id
- This diff still retain functionality in case of selector appear to touch only one element.

Reviewed By: mweststrate

Differential Revision: D21040427

fbshipit-source-id: e6704535a437ad47d9664cc16896b9f24c9d6736
This commit is contained in:
Chaiwat Ekkaewnumchai
2020-05-07 03:37:49 -07:00
committed by Facebook GitHub Bot
parent 770c8b4d00
commit a7163bf06d

View File

@@ -25,6 +25,8 @@ type GetNodesOptions = {
forAccessibilityEvent?: boolean;
};
type ElementSelectorNode = {[id: string]: ElementSelectorNode};
type Props = {
ax?: boolean;
client: PluginClient;
@@ -131,8 +133,12 @@ export default class Inspector extends Component<Props> {
this.props.client.subscribe(
this.call().SELECT,
({path}: {path: Array<ElementID>}) => {
this.getAndExpandPath(path);
({path, tree}: {path?: Array<ElementID>; tree?: ElementSelectorNode}) => {
if (tree) {
this._getAndExpandPathFromTree(tree);
} else if (path) {
this.getAndExpandPath(path);
}
},
);
@@ -291,6 +297,48 @@ export default class Inspector extends Component<Props> {
this.onElementSelected(path[path.length - 1]);
}
getElementLeaves(tree: ElementSelectorNode): Array<ElementID> {
return tree
? Object.entries(tree).reduce(
(
currLeafNode: Array<ElementID>,
[id, children]: [ElementID, ElementSelectorNode],
): Array<ElementID> =>
currLeafNode.concat(
Object.keys(children).length > 0
? this.getElementLeaves(children)
: [id],
),
[],
)
: [];
}
/// Return path from given tree structure and id if id is not null; otherwise return any path
getPathForNode(
tree: ElementSelectorNode,
nodeID: ElementID | null,
): Array<ElementID> | null {
for (const node in tree) {
if (
node === nodeID ||
(nodeID === null && Object.keys(tree[node]).length == 0)
) {
return [node];
}
const path = this.getPathForNode(tree[node], nodeID);
if (path !== null) {
return [node].concat(path);
}
}
return null;
}
// NOTE: this will be used in the future when we remove path and use tree instead
async _getAndExpandPathFromTree(tree: ElementSelectorNode) {
this.getAndExpandPath(this.getPathForNode(tree, null) ?? []);
}
onElementSelected = debounce((selectedKey: ElementID) => {
this.onElementHovered(selectedKey);
this.props.onSelect(selectedKey);