Skip to content

Commit 6d1496a

Browse files
committed
Handle sibling combinators
1 parent 8823a52 commit 6d1496a

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,27 @@ And Svelte will generate the following HTML and CSS(should be external styleshee
9898

9999
This preprocess will transform rules with the following selectors:
100100

101-
[X] Type Selector `h1`
101+
- [X] Type Selector `h1`
102102

103-
[X] Id Selector `#foo`
103+
- [X] Id Selector `#foo`
104104

105-
[X] Class Selector `.foo`
105+
- [X] Class Selector `.foo`
106106

107-
[X] Attribute Selector `li[title]`
107+
- [X] Attribute Selector `li[title]`
108108

109-
[X] Descendant combinator `.foo .bar`
109+
- [X] Descendant combinator `.foo .bar`
110110

111-
[X] Child combinator `.foo>.bar`
111+
- [X] Child combinator `.foo>.bar`
112112

113-
[ ] Adjacent sibling combinator `.foo+.bar`
113+
- [X] Adjacent sibling combinator `.foo+.bar`
114114

115-
[ ] General sibling combinator `.foo~.bar`
115+
- [X] General sibling combinator `.foo~.bar`
116116

117-
[X] Pseudo class `.foo:hover`
117+
- [X] Pseudo class `.foo:hover`
118118

119-
[X] Pseudo selector `.foo::before`
119+
- [X] Pseudo selector `.foo::before`
120+
121+
- [X] `:not()` selector `a:not(.hello)`
120122

121123
## Known limitations
122124

src/transformer.js

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,60 @@ const isTargetElement = (selectorNode, node, linker) => {
3232
}
3333
const combinator = isCombinator(selector);
3434
if (combinator) {
35-
curNode = linker.getParent(curNode);
3635
selector = r.prev();
3736
matchCount++;
38-
if (combinator === ">") {
39-
// prevent linker from providing more than one node for finding direct parent
40-
linker.hide(curNode);
37+
switch (combinator) {
38+
case ">":
39+
// prevent linker from providing more than one node for finding direct parent
40+
curNode = linker.getParent(curNode);
41+
linker.hide(curNode);
42+
break;
43+
44+
case "~": {
45+
// should check its siblings before it
46+
const parent = linker.getParent(curNode);
47+
const curNodeIndex = parent.children.findIndex((s) => s === curNode);
48+
const sliced = parent.children.slice(0, curNodeIndex + 1);
49+
50+
for (const sibling of sliced) {
51+
const matched = matchWithSelector(sibling, selector);
52+
if (matched) {
53+
matchCount++;
54+
}
55+
}
56+
break;
57+
}
58+
59+
case "+": {
60+
const parent = linker.getParent(curNode);
61+
const curNodeIndex = parent.children.findIndex((s) => s === curNode);
62+
if (curNodeIndex > 0) {
63+
curNode = parent.children[curNodeIndex - 1];
64+
} else {
65+
return false;
66+
}
67+
break;
68+
}
69+
70+
case " ": {
71+
curNode = linker.getParent(curNode);
72+
break;
73+
}
4174
}
4275
} else {
4376
const isMatch = matchWithSelector(curNode, selector);
4477
if (isMatch) {
4578
selector = r.prev();
4679
matchCount++;
47-
if (r.length() === matchCount) {
48-
found = true;
49-
return found;
50-
}
5180
} else {
5281
return false;
5382
}
5483
}
84+
85+
if (r.length() === matchCount) {
86+
found = true;
87+
return found;
88+
}
5589
}
5690

5791
return found;

0 commit comments

Comments
 (0)