Skip to content

Commit fd00010

Browse files
feat: report end indices for nodes (#83)
1 parent d77a65a commit fd00010

File tree

5 files changed

+501
-126
lines changed

5 files changed

+501
-126
lines changed

lib/index.d.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
declare namespace postcssValueParser {
22
interface BaseNode {
33
/**
4-
* The offset inside the CSS value at which the node starts
4+
* The offset, inclusive, inside the CSS value at which the node starts.
55
*/
66
sourceIndex: number;
77

8+
/**
9+
* The offset, exclusive, inside the CSS value at which the node ends.
10+
*/
11+
sourceEndIndex: number;
12+
813
/**
914
* The node's characteristic value
1015
*/

lib/parse.js

+20-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ module.exports = function(input) {
5050
after = token;
5151
} else if (prev && prev.type === "div") {
5252
prev.after = token;
53+
prev.sourceEndIndex += token.length;
5354
} else if (
5455
code === comma ||
5556
code === colon ||
@@ -63,6 +64,7 @@ module.exports = function(input) {
6364
tokens.push({
6465
type: "space",
6566
sourceIndex: pos,
67+
sourceEndIndex: next,
6668
value: token
6769
});
6870
}
@@ -94,22 +96,25 @@ module.exports = function(input) {
9496
}
9597
} while (escape);
9698
token.value = value.slice(pos + 1, next);
97-
99+
token.sourceEndIndex = token.unclosed ? next : next + 1;
98100
tokens.push(token);
99101
pos = next + 1;
100102
code = value.charCodeAt(pos);
101103

102104
// Comments
103105
} else if (code === slash && value.charCodeAt(pos + 1) === star) {
106+
next = value.indexOf("*/", pos);
107+
104108
token = {
105109
type: "comment",
106-
sourceIndex: pos
110+
sourceIndex: pos,
111+
sourceEndIndex: next + 2
107112
};
108113

109-
next = value.indexOf("*/", pos);
110114
if (next === -1) {
111115
token.unclosed = true;
112116
next = value.length;
117+
token.sourceEndIndex = next;
113118
}
114119

115120
token.value = value.slice(pos + 2, next);
@@ -129,6 +134,7 @@ module.exports = function(input) {
129134
tokens.push({
130135
type: "word",
131136
sourceIndex: pos - before.length,
137+
sourceEndIndex: pos + token.length,
132138
value: token
133139
});
134140
pos += 1;
@@ -141,6 +147,7 @@ module.exports = function(input) {
141147
tokens.push({
142148
type: "div",
143149
sourceIndex: pos - before.length,
150+
sourceEndIndex: pos + token.length,
144151
value: token,
145152
before: before,
146153
after: ""
@@ -196,6 +203,7 @@ module.exports = function(input) {
196203
{
197204
type: "word",
198205
sourceIndex: pos,
206+
sourceEndIndex: whitespacePos + 1,
199207
value: value.slice(pos, whitespacePos + 1)
200208
}
201209
];
@@ -207,21 +215,25 @@ module.exports = function(input) {
207215
token.nodes.push({
208216
type: "space",
209217
sourceIndex: whitespacePos + 1,
218+
sourceEndIndex: next,
210219
value: value.slice(whitespacePos + 1, next)
211220
});
212221
} else {
213222
token.after = value.slice(whitespacePos + 1, next);
223+
token.sourceEndIndex = next;
214224
}
215225
} else {
216226
token.after = "";
217227
token.nodes = [];
218228
}
219229
pos = next + 1;
230+
token.sourceEndIndex = token.unclosed ? next : pos;
220231
code = value.charCodeAt(pos);
221232
tokens.push(token);
222233
} else {
223234
balanced += 1;
224235
token.after = "";
236+
token.sourceEndIndex = pos + 1;
225237
tokens.push(token);
226238
stack.push(token);
227239
tokens = token.nodes = [];
@@ -235,8 +247,10 @@ module.exports = function(input) {
235247
code = value.charCodeAt(pos);
236248

237249
parent.after = after;
250+
parent.sourceEndIndex += after.length;
238251
after = "";
239252
balanced -= 1;
253+
stack[stack.length - 1].sourceEndIndex = pos;
240254
stack.pop();
241255
parent = stack[balanced];
242256
tokens = parent.nodes;
@@ -282,12 +296,14 @@ module.exports = function(input) {
282296
tokens.push({
283297
type: "unicode-range",
284298
sourceIndex: pos,
299+
sourceEndIndex: next,
285300
value: token
286301
});
287302
} else {
288303
tokens.push({
289304
type: "word",
290305
sourceIndex: pos,
306+
sourceEndIndex: next,
291307
value: token
292308
});
293309
}
@@ -298,6 +314,7 @@ module.exports = function(input) {
298314

299315
for (pos = stack.length - 1; pos; pos -= 1) {
300316
stack[pos].unclosed = true;
317+
stack[pos].sourceEndIndex = value.length;
301318
}
302319

303320
return stack[0].nodes;

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"tape": "^4.10.2"
1616
},
1717
"scripts": {
18-
"lint:prettier": "prettier '**/*.js' '**/*.ts' --list-different",
18+
"lint:prettier": "prettier \"**/*.js\" \"**/*.ts\" --list-different",
1919
"lint:js": "eslint . --cache",
2020
"lint": "yarn lint:js && yarn lint:prettier",
2121
"pretest": "yarn lint",

test/index.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ test("ValueParser", function(tp) {
3838
{
3939
type: "function",
4040
sourceIndex: 0,
41+
sourceEndIndex: 5,
4142
value: "fn",
4243
before: " ",
4344
after: "",
@@ -46,13 +47,15 @@ test("ValueParser", function(tp) {
4647
{
4748
type: "function",
4849
sourceIndex: 6,
50+
sourceEndIndex: 17,
4951
value: "fn2",
5052
before: " ",
5153
after: "",
5254
nodes: [
5355
{
5456
type: "function",
5557
sourceIndex: 11,
58+
sourceEndIndex: 16,
5659
value: "fn3",
5760
before: "",
5861
after: "",
@@ -63,6 +66,7 @@ test("ValueParser", function(tp) {
6366
{
6467
type: "function",
6568
sourceIndex: 11,
69+
sourceEndIndex: 16,
6670
value: "fn3",
6771
before: "",
6872
after: "",
@@ -90,6 +94,7 @@ test("ValueParser", function(tp) {
9094
{
9195
type: "function",
9296
sourceIndex: 0,
97+
sourceEndIndex: 5,
9398
value: "fn",
9499
before: " ",
95100
after: "",
@@ -98,13 +103,15 @@ test("ValueParser", function(tp) {
98103
{
99104
type: "function",
100105
sourceIndex: 6,
106+
sourceEndIndex: 17,
101107
value: "fn2",
102108
before: " ",
103109
after: "",
104110
nodes: [
105111
{
106112
type: "function",
107113
sourceIndex: 11,
114+
sourceEndIndex: 16,
108115
value: "fn3",
109116
before: "",
110117
after: "",
@@ -131,22 +138,25 @@ test("ValueParser", function(tp) {
131138
{
132139
type: "function",
133140
sourceIndex: 0,
141+
sourceEndIndex: 5,
134142
value: "fn",
135143
before: " ",
136144
after: "",
137145
nodes: []
138146
},
139-
{ type: "space", sourceIndex: 5, value: " " },
147+
{ type: "space", sourceIndex: 5, sourceEndIndex: 6, value: " " },
140148
{
141149
type: "word",
142150
sourceIndex: 6,
151+
sourceEndIndex: 17,
143152
value: "fn2",
144153
before: " ",
145154
after: "",
146155
nodes: [
147156
{
148157
type: "function",
149158
sourceIndex: 11,
159+
sourceEndIndex: 16,
150160
value: "fn3",
151161
before: "",
152162
after: "",
@@ -172,6 +182,7 @@ test("ValueParser", function(tp) {
172182
{
173183
type: "function",
174184
sourceIndex: 5,
185+
sourceEndIndex: 10,
175186
value: "fn3",
176187
before: "",
177188
after: "",
@@ -180,13 +191,15 @@ test("ValueParser", function(tp) {
180191
{
181192
type: "function",
182193
sourceIndex: 0,
194+
sourceEndIndex: 11,
183195
value: "fn2",
184196
before: " ",
185197
after: "",
186198
nodes: [
187199
{
188200
type: "function",
189201
sourceIndex: 5,
202+
sourceEndIndex: 10,
190203
value: "fn3",
191204
before: "",
192205
after: "",

0 commit comments

Comments
 (0)