diff options
author | Deniz Akşimşek <deniz@denizaksimsek.com> | 2023-01-06 03:11:37 +0300 |
---|---|---|
committer | Deniz Akşimşek <deniz@denizaksimsek.com> | 2023-01-06 03:11:37 +0300 |
commit | e35c3c5b8ba47f26ecfff2ea5005038abe9d6554 (patch) | |
tree | dc5b2a624324d1232dbb842156c626d049f31187 | |
parent | e8565c86cf8d304af7a88b657a65813c28c15735 (diff) | |
download | missing-e35c3c5b8ba47f26ecfff2ea5005038abe9d6554.tar.gz missing-e35c3c5b8ba47f26ecfff2ea5005038abe9d6554.zip |
refactor and comment 19 traverse
-rw-r--r-- | missing-js/19.ts | 50 |
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; } } |