From f5c37dc25151a3ce8db68112430e19aeb14a4e72 Mon Sep 17 00:00:00 2001 From: bendtherules Date: Wed, 18 Sep 2019 11:36:09 +0530 Subject: [PATCH] temp commit --- package-lock.json | 17 ++++++++--- package.json | 1 + src/match.ts | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 src/match.ts diff --git a/package-lock.json b/package-lock.json index b40358e..46c8e0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3767,7 +3767,7 @@ }, "css-select": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "dev": true, "requires": { @@ -3775,13 +3775,20 @@ "css-what": "2.1", "domutils": "1.5.1", "nth-check": "~1.0.1" + }, + "dependencies": { + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + } } }, "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "dev": true + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.0.tgz", + "integrity": "sha512-lukqnlbswsPmDZ5+ViDBCcrk+1fyPBA+ZoHSAQhRuEeXBKUb3Lj2kcTwMqoiFrJAnEeO9u3Oc8X617SUm3apYQ==" }, "cssom": { "version": "0.3.8", diff --git a/package.json b/package.json index 81edaee..c852f0c 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ }, "dependencies": { "@babel/runtime": "^7.5.4", + "css-what": "^3.2.0", "prop-types": "^15.7.2" }, "devDependencies": { diff --git a/src/match.ts b/src/match.ts new file mode 100644 index 0000000..6b4d576 --- /dev/null +++ b/src/match.ts @@ -0,0 +1,78 @@ +import CSSwhat from "css-what"; +import { traverseGenerator } from "./traverse"; +import { FiberNode } from "./mocked-types"; +import { isNodeNotHtmlLike } from "./utils"; + +function* matchGenerator( + node: FiberNode, + match: string | CSSwhat.Selector[][] +): IterableIterator { + // Either parse match string or allow parsed match object as it is + let matchParsed: CSSwhat.Selector[][]; + if (typeof match === "string") { + matchParsed = CSSwhat.parse(match); + } else { + matchParsed = match; + } + + // If selector is a combination of multiple basic selectors (a, b), + // pass them separately to matchGenerator and combine their results one after another + const selectorsCount = matchParsed.length; + if (selectorsCount > 1) { + for (const selectorParsed of matchParsed) { + yield* matchGenerator(node, [selectorParsed]); + } + + return; + } + + // For simple selector (matchParsed.length == 0), actual logic starts here + { + const parsedSelector = matchParsed[0]; + if (parsedSelector.length === 0) { + return; + } + + let currentMatchingNodes: FiberNode[] = [node]; + let currentMatchingSelectorPartIndex = 0; + let currentMatchingSelectorPart: CSSwhat.Selector = + parsedSelector[currentMatchingSelectorPartIndex]; + let lastRelationshipSelectorPart: CSSwhat.Selector | undefined = undefined; + + while (currentMatchingSelectorPartIndex < parsedSelector.length) { + const nextMatchingNodes: FiberNode[] = []; + + for (const currentNode of currentMatchingNodes) { + if (["tag"].includes(currentMatchingSelectorPart.type)) { + const traverseIterator = traverseGenerator(currentNode); + + // Handle supported non-traversal parts here + if (currentMatchingSelectorPart.type == "tag") { + for (const tmpNode of traverseIterator) { + if ( + isNodeNotHtmlLike(tmpNode) && + tmpNode.type.name === currentMatchingSelectorPart.name + ) { + nextMatchingNodes.push(tmpNode); + } + } + } + traverseIterator.throw && + traverseIterator.throw(new Error("cleanup")); + } else if (["descendant"].includes(currentMatchingSelectorPart.type)) { + // Handle traversal parts here + lastRelationshipSelectorPart = currentMatchingSelectorPart; + } else { + // For unhandled parts + lastRelationshipSelectorPart = undefined; + } + } + + currentMatchingNodes = nextMatchingNodes; + } + + return; + } +} + +export { matchGenerator };