Skip to content

Commit 6485caf

Browse files
authored
feat: add sourceIndex to Selector nodes (#290)
1 parent b4c848e commit 6485caf

File tree

3 files changed

+82
-4
lines changed

3 files changed

+82
-4
lines changed

src/__tests__/node.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ test('Node#isAtPosition', (t) => {
9999
let notSelector = pseudoNot.first;
100100
t.deepEqual(notSelector.isAtPosition(1, 1), false);
101101
t.deepEqual(notSelector.isAtPosition(1, 4), false);
102-
t.deepEqual(notSelector.isAtPosition(1, 5), true);
103102
t.deepEqual(notSelector.isAtPosition(1, 6), true);
103+
t.deepEqual(notSelector.isAtPosition(1, 7), true);
104104
t.deepEqual(notSelector.isAtPosition(1, 9), true);
105105
t.deepEqual(notSelector.isAtPosition(1, 10), true);
106106
t.deepEqual(notSelector.isAtPosition(1, 11), false);

src/__tests__/sourceIndex.mjs

+67
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import {test} from './util/helpers.mjs';
22

33
test('universal selector', '*', (t, tree) => {
4+
t.deepEqual(tree.nodes[0].source.start.column, 1);
5+
t.deepEqual(tree.nodes[0].source.end.column, 1);
6+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
47
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
58
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 1);
69
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
710
});
811

912
test('lobotomized owl selector', ' * + * ', (t, tree) => {
13+
t.deepEqual(tree.nodes[0].source.start.column, 1);
14+
t.deepEqual(tree.nodes[0].source.end.column, 6);
15+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
1016
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 2);
1117
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 2);
1218
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 1);
@@ -19,12 +25,18 @@ test('lobotomized owl selector', ' * + * ', (t, tree) => {
1925
});
2026

2127
test('comment', '/**\n * Hello!\n */', (t, tree) => {
28+
t.deepEqual(tree.nodes[0].source.start.column, 1);
29+
t.deepEqual(tree.nodes[0].source.end.column, 3);
30+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
2231
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
2332
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 3);
2433
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
2534
});
2635

2736
test('comment & universal selectors', '*/*test*/*', (t, tree) => {
37+
t.deepEqual(tree.nodes[0].source.start.column, 1);
38+
t.deepEqual(tree.nodes[0].source.end.column, 10);
39+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
2840
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
2941
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 1);
3042
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
@@ -37,27 +49,42 @@ test('comment & universal selectors', '*/*test*/*', (t, tree) => {
3749
});
3850

3951
test('tag selector', 'h1', (t, tree) => {
52+
t.deepEqual(tree.nodes[0].source.start.column, 1);
53+
t.deepEqual(tree.nodes[0].source.end.column, 2);
54+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
4055
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
4156
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 2);
4257
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
4358
});
4459

4560
test('id selector', '#id', (t, tree) => {
61+
t.deepEqual(tree.nodes[0].source.start.column, 1);
62+
t.deepEqual(tree.nodes[0].source.end.column, 3);
63+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
4664
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
4765
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 3);
4866
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
4967
});
5068

5169
test('tag selector followed by id selector', 'h1, #id', (t, tree) => {
70+
t.deepEqual(tree.nodes[0].source.start.column, 1);
71+
t.deepEqual(tree.nodes[0].source.end.column, 2);
72+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
5273
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
5374
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 2);
5475
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
76+
t.deepEqual(tree.nodes[1].source.start.column, 4);
77+
t.deepEqual(tree.nodes[1].source.end.column, 7);
78+
t.deepEqual(tree.nodes[1].sourceIndex, 3);
5579
t.deepEqual(tree.nodes[1].nodes[0].source.start.column, 5);
5680
t.deepEqual(tree.nodes[1].nodes[0].source.end.column, 7);
5781
t.deepEqual(tree.nodes[1].nodes[0].sourceIndex, 4);
5882
});
5983

6084
test('multiple id selectors', '#one#two', (t, tree) => {
85+
t.deepEqual(tree.nodes[0].source.start.column, 1);
86+
t.deepEqual(tree.nodes[0].source.end.column, 8);
87+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
6188
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
6289
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 4);
6390
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
@@ -67,6 +94,9 @@ test('multiple id selectors', '#one#two', (t, tree) => {
6794
});
6895

6996
test('multiple id selectors (2)', '#one#two#three#four', (t, tree) => {
97+
t.deepEqual(tree.nodes[0].source.start.column, 1);
98+
t.deepEqual(tree.nodes[0].source.end.column, 19);
99+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
70100
t.deepEqual(tree.nodes[0].nodes[2].source.start.column, 9);
71101
t.deepEqual(tree.nodes[0].nodes[2].source.end.column, 14);
72102
t.deepEqual(tree.nodes[0].nodes[2].sourceIndex, 8);
@@ -76,24 +106,39 @@ test('multiple id selectors (2)', '#one#two#three#four', (t, tree) => {
76106
});
77107

78108
test('multiple id selectors (3)', '#one#two,#three#four', (t, tree) => {
109+
t.deepEqual(tree.nodes[0].source.start.column, 1);
110+
t.deepEqual(tree.nodes[0].source.end.column, 8);
111+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
79112
t.deepEqual(tree.nodes[0].nodes[1].source.start.column, 5);
80113
t.deepEqual(tree.nodes[0].nodes[1].source.end.column, 8);
81114
t.deepEqual(tree.nodes[0].nodes[1].sourceIndex, 4);
115+
t.deepEqual(tree.nodes[1].source.start.column, 10);
116+
t.deepEqual(tree.nodes[1].source.end.column, 20);
117+
t.deepEqual(tree.nodes[1].sourceIndex, 9);
82118
t.deepEqual(tree.nodes[1].nodes[1].source.start.column, 16);
83119
t.deepEqual(tree.nodes[1].nodes[1].source.end.column, 20);
84120
t.deepEqual(tree.nodes[1].nodes[1].sourceIndex, 15);
85121
});
86122

87123
test('multiple class selectors', '.one.two,.three.four', (t, tree) => {
124+
t.deepEqual(tree.nodes[0].source.start.column, 1);
125+
t.deepEqual(tree.nodes[0].source.end.column, 8);
126+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
88127
t.deepEqual(tree.nodes[0].nodes[1].source.start.column, 5);
89128
t.deepEqual(tree.nodes[0].nodes[1].source.end.column, 8);
90129
t.deepEqual(tree.nodes[0].nodes[1].sourceIndex, 4);
130+
t.deepEqual(tree.nodes[1].source.start.column, 10);
131+
t.deepEqual(tree.nodes[1].source.end.column, 20);
132+
t.deepEqual(tree.nodes[1].sourceIndex, 9);
91133
t.deepEqual(tree.nodes[1].nodes[1].source.start.column, 16);
92134
t.deepEqual(tree.nodes[1].nodes[1].source.end.column, 20);
93135
t.deepEqual(tree.nodes[1].nodes[1].sourceIndex, 15);
94136
});
95137

96138
test('attribute selector', '[name="james"]', (t, tree) => {
139+
t.deepEqual(tree.nodes[0].source.start.column, 1);
140+
t.deepEqual(tree.nodes[0].source.end.column, 14);
141+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
97142
t.deepEqual(tree.nodes[0].nodes[0].source.start.line, 1);
98143
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
99144
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 14);
@@ -130,11 +175,33 @@ test('pseudo-class', 'h1:first-child', (t, tree) => {
130175
t.deepEqual(tree.nodes[0].nodes[1].sourceIndex, 2);
131176
});
132177

178+
test('pseudo-class without argument', ':not()', (t, tree) => {
179+
t.deepEqual(tree.nodes[0].source.start.column, 1);
180+
t.deepEqual(tree.nodes[0].source.end.column, 6);
181+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
182+
t.deepEqual(tree.nodes[0].nodes[0].source.start.line, 1);
183+
t.deepEqual(tree.nodes[0].nodes[0].source.start.column, 1);
184+
t.deepEqual(tree.nodes[0].nodes[0].source.end.column, 6);
185+
t.deepEqual(tree.nodes[0].nodes[0].sourceIndex, 0);
186+
t.deepEqual(tree.nodes[0].nodes[0].nodes[0].source.start.column, 6);
187+
t.deepEqual(tree.nodes[0].nodes[0].nodes[0].source.end.column, 6);
188+
t.deepEqual(tree.nodes[0].nodes[0].nodes[0].sourceIndex, 5);
189+
});
190+
133191
test('pseudo-class with argument', 'h1:not(.strudel, .food)', (t, tree) => {
192+
t.deepEqual(tree.nodes[0].source.start.column, 1);
193+
t.deepEqual(tree.nodes[0].source.end.column, 23);
194+
t.deepEqual(tree.nodes[0].sourceIndex, 0);
134195
t.deepEqual(tree.nodes[0].nodes[1].source.start.line, 1);
135196
t.deepEqual(tree.nodes[0].nodes[1].source.start.column, 3);
136197
t.deepEqual(tree.nodes[0].nodes[1].source.end.column, 23);
137198
t.deepEqual(tree.nodes[0].nodes[1].sourceIndex, 2);
199+
t.deepEqual(tree.nodes[0].nodes[1].nodes[0].source.start.column, 8);
200+
t.deepEqual(tree.nodes[0].nodes[1].nodes[0].source.end.column, 15);
201+
t.deepEqual(tree.nodes[0].nodes[1].nodes[0].sourceIndex, 7);
202+
t.deepEqual(tree.nodes[0].nodes[1].nodes[1].source.start.column, 17);
203+
t.deepEqual(tree.nodes[0].nodes[1].nodes[1].source.end.column, 23);
204+
t.deepEqual(tree.nodes[0].nodes[1].nodes[1].sourceIndex, 16);
138205
});
139206

140207
test('pseudo-element', 'h1::before', (t, tree) => {

src/parser.js

+14-3
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@ export default class Parser {
131131
this.root.errorGenerator = this._errorGenerator();
132132

133133

134-
const selector = new Selector({source: {start: {line: 1, column: 1}}});
134+
const selector = new Selector({
135+
source: {start: {line: 1, column: 1}},
136+
sourceIndex: 0,
137+
});
135138
this.root.append(selector);
136139
this.current = selector;
137140

@@ -608,7 +611,12 @@ export default class Parser {
608611
return;
609612
}
610613
this.current._inferEndPosition();
611-
const selector = new Selector({source: {start: tokenStart(this.tokens[this.position + 1])}});
614+
const selector = new Selector({
615+
source: {
616+
start: tokenStart(this.tokens[this.position + 1]),
617+
},
618+
sourceIndex: this.tokens[this.position + 1][TOKEN.START_POS],
619+
});
612620
this.current.parent.append(selector);
613621
this.current = selector;
614622
this.position ++;
@@ -685,7 +693,10 @@ export default class Parser {
685693
let unbalanced = 1;
686694
this.position ++;
687695
if (last && last.type === types.PSEUDO) {
688-
const selector = new Selector({source: {start: tokenStart(this.tokens[this.position - 1])}});
696+
const selector = new Selector({
697+
source: {start: tokenStart(this.tokens[this.position])},
698+
sourceIndex: this.tokens[this.position][TOKEN.START_POS],
699+
});
689700
const cache = this.current;
690701
last.append(selector);
691702
this.current = selector;

0 commit comments

Comments
 (0)