aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDeniz Akşimşek <deniz@denizaksimsek.com>2023-01-06 03:11:37 +0300
committerDeniz Akşimşek <deniz@denizaksimsek.com>2023-01-06 03:11:37 +0300
commite35c3c5b8ba47f26ecfff2ea5005038abe9d6554 (patch)
treedc5b2a624324d1232dbb842156c626d049f31187
parente8565c86cf8d304af7a88b657a65813c28c15735 (diff)
downloadmissing-e35c3c5b8ba47f26ecfff2ea5005038abe9d6554.tar.gz
missing-e35c3c5b8ba47f26ecfff2ea5005038abe9d6554.zip
refactor and comment 19 traverse
-rw-r--r--missing-js/19.ts50
1 files changed, 37 insertions, 13 deletions
diff --git a/missing-js/19.ts b/missing-js/19.ts
index 07d4fc9..99313ff 100644
--- a/missing-js/19.ts
+++ b/missing-js/19.ts
@@ -68,22 +68,46 @@ export function traverse(
const { wrap = true } = options;
const advance = direction + "ElementSibling";
- const wrapIt = direction === "next"
- ? (root: ParentNode, selector: string) => $(root, selector)
- : (root: ParentNode, selector: string) => $$(root, selector).at(-1);
- if (!current)
- return wrap ? wrapIt(root, selector) : null;
+
+ const wrapIt = () => {
+ // If wrapping is disabled.
+ if (!wrap) return null;
+ // Wrap in the correct direction.
+ return direction === "next"
+ ? $(root, selector)
+ : $$(root, selector).at(-1);
+ }
+
+ if (!current) return wrapIt();
+
+ // Traverse left to right, bottom to top.
+ //
+ // (begin ascii art diagram)
+ // (R)
+ // / \
+ // (r) (4) <- return value
+ // / | \ / \
+ // current -> (1) (2) (3) (*) (*)
+ // (end diagram)
+ //
+ // In the diagram above, 1, 2, 3 are tested by the selector (assuming we
+ // start at 1). Then, having run out of siblings, we move up (as many times
+ // as needed) before advancing, ending up at 4.
+ //
+ // To "test" an element, ee call Element#matches, then if that returns false,
+ // querySelector. The querySelector call is how the items marked with
+ // asterisks can be checked.
let cursor = current;
while (true) {
- while (cursor[advance] === null) {
- cursor = cursor.parentElement as Element;
- if (cursor === root)
- return wrap ? wrapIt(root, selector) : null;
+ while (cursor[advance] === null) { // 3
+ cursor = cursor.parentElement as Element; // 1 to r
+ if (cursor === root) return wrapIt();
}
- cursor = cursor[advance];
- const found = cursor.matches(selector) ? cursor : $(cursor, selector);
- if (found)
- return found;
+ cursor = cursor[advance]; // 1 to 2 to 3, r to 4
+ const found = cursor.matches(selector)
+ ? cursor // 4
+ : $(cursor, selector); // asterisks
+ if (found) return found;
}
}