diff options
author | bptato <nincsnevem662@gmail.com> | 2021-11-23 13:01:23 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2021-11-23 13:01:23 +0100 |
commit | 30f3b5deb3be13683e73175f241600c028910eaa (patch) | |
tree | 8524e4451cbf7ef4f8850f9b74f9df8bfd839ac0 /src/css/selector.nim | |
parent | ff1b68086d699510dcdbea6051460926556bd401 (diff) | |
download | chawan-30f3b5deb3be13683e73175f241600c028910eaa.tar.gz |
Support CSS child combinators
Diffstat (limited to 'src/css/selector.nim')
-rw-r--r-- | src/css/selector.nim | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/src/css/selector.nim b/src/css/selector.nim index 97c7d695..8489f240 100644 --- a/src/css/selector.nim +++ b/src/css/selector.nim @@ -12,13 +12,13 @@ type QueryMode* = enum QUERY_TYPE, QUERY_CLASS, QUERY_ATTR, QUERY_DELIM, QUERY_VALUE, - QUERY_PSEUDO, QUERY_PSELEM, QUERY_COMBINATOR + QUERY_PSEUDO, QUERY_PSELEM, QUERY_DESC_COMBINATOR, QUERY_CHILD_COMBINATOR PseudoElem* = enum PSEUDO_NONE, PSEUDO_BEFORE, PSEUDO_AFTER CombinatorType* = enum - DESCENDANT_COMBINATOR + DESCENDANT_COMBINATOR, CHILD_COMBINATOR SelectorParser = object selectors: seq[SelectorList] @@ -86,10 +86,8 @@ func getSpecificity(sel: Selector): int = of UNIVERSAL_SELECTOR: discard of COMBINATOR_SELECTOR: - case sel.ct - of DESCENDANT_COMBINATOR: - for child in sel.csels: - result += getSpecificity(child) + for child in sel.csels: + result += getSpecificity(child) func getSpecificity*(sels: SelectorList): int = for sel in sels.sels: @@ -135,17 +133,31 @@ proc addSelectorList(state: var SelectorParser) = state.combinator = nil state.selectors.add(SelectorList()) +proc parseSelectorCombinator(state: var SelectorParser, ct: CombinatorType, csstoken: CSSToken) = + if csstoken.tokenType in {CSS_IDENT_TOKEN, CSS_HASH_TOKEN, + CSS_COLON_TOKEN}: + if state.combinator != nil and state.combinator.ct != ct: + let nc = Selector(t: COMBINATOR_SELECTOR, ct: ct) + nc.csels.add(SelectorList()) + nc.csels[^1].add(state.combinator) + state.combinator = nc + + if state.combinator == nil: + state.combinator = Selector(t: COMBINATOR_SELECTOR, ct: ct) + + state.combinator.csels.add(state.selectors[^1]) + if state.combinator.csels[^1].len > 0: + state.combinator.csels.add(SelectorList()) + state.selectors[^1] = SelectorList() + state.query = QUERY_TYPE + proc parseSelectorToken(state: var SelectorParser, csstoken: CSSToken) = - if state.query == QUERY_COMBINATOR: - if csstoken.tokenType in {CSS_IDENT_TOKEN, CSS_HASH_TOKEN, - CSS_COLON_TOKEN}: - if state.combinator == nil: - state.combinator = Selector(t: COMBINATOR_SELECTOR, ct: DESCENDANT_COMBINATOR) - state.combinator.csels.add(state.selectors[^1]) - if state.combinator.csels[^1].len > 0: - state.combinator.csels.add(SelectorList()) - state.selectors[^1] = SelectorList() - state.query = QUERY_TYPE + if state.query == QUERY_DESC_COMBINATOR: + state.parseSelectorCombinator(DESCENDANT_COMBINATOR, csstoken) + elif state.query == QUERY_CHILD_COMBINATOR: + if csstoken.tokenType == CSS_WHITESPACE_TOKEN: + return + state.parseSelectorCombinator(CHILD_COMBINATOR, csstoken) case csstoken.tokenType of CSS_IDENT_TOKEN: @@ -163,6 +175,9 @@ proc parseSelectorToken(state: var SelectorParser, csstoken: CSSToken) = of CSS_DELIM_TOKEN: if csstoken.rvalue == Rune('.'): state.query = QUERY_CLASS + elif csstoken.rvalue == Rune('>'): + if state.selectors[^1].len > 0 or state.combinator != nil: + state.query = QUERY_CHILD_COMBINATOR of CSS_HASH_TOKEN: state.addSelector(Selector(t: ID_SELECTOR, id: $csstoken.value)) of CSS_COMMA_TOKEN: @@ -170,7 +185,7 @@ proc parseSelectorToken(state: var SelectorParser, csstoken: CSSToken) = state.addSelectorList() of CSS_WHITESPACE_TOKEN: if state.selectors[^1].len > 0 or state.combinator != nil: - state.query = QUERY_COMBINATOR + state.query = QUERY_DESC_COMBINATOR of CSS_COLON_TOKEN: if state.query == QUERY_PSEUDO: state.query = QUERY_PSELEM |