From 905268dac2c2ae3f9822019afcb18d72065036ec Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Thu, 29 Aug 2019 08:46:55 -0700 Subject: [PATCH] Add more tree search utilities --- modern/src/MakiSelectors.ts | 19 +++++++++++++++++++ modern/src/utils.ts | 22 +++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/modern/src/MakiSelectors.ts b/modern/src/MakiSelectors.ts index ae5eed4c..a808e0c5 100644 --- a/modern/src/MakiSelectors.ts +++ b/modern/src/MakiSelectors.ts @@ -16,3 +16,22 @@ export function getTop(uid) { return Number(node.attributes.y) || 0; }; } + +export function getPathToUid(uid: number) { + return state => { + return Utils.findPathToNode(state.xmlTree, node => node.uid === uid); + }; +} + +export function getNodeAtPath(path: number[]) { + return state => { + let node = state.xmlTree; + path.forEach(offset => { + if (node == null) { + return null; + } + node = node.children[offset]; + }); + return node; + }; +} diff --git a/modern/src/utils.ts b/modern/src/utils.ts index 363681bb..a12e9718 100644 --- a/modern/src/utils.ts +++ b/modern/src/utils.ts @@ -138,8 +138,28 @@ export function unimplementedWarning(name: string): void { console.warn(`Executing unimplemented MAKI function: ${name}`); } +// Bredth-first search in a tree that returns the path to the node +export function findPathToNode( + node: T, + predicate: (candidate: T) => boolean +): number[] { + if (predicate(node)) { + return []; + } + const children = node.children || []; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + + const found = findPathToNode(child, predicate); + if (found != null) { + return [i, ...found]; + } + } + return null; +} + // Bredth-first search in a tree -export function findInTree(node, predicate) { +export function findInTree(node: T, predicate): T { if (predicate(node)) { return node; }