Skip to content

Commit 2d0eec6

Browse files
authored
fix: handle all CSS newline types in CSSSourceCode (#275)
1 parent 8047f1e commit 2d0eec6

File tree

2 files changed

+116
-4
lines changed

2 files changed

+116
-4
lines changed

src/languages/css-source-code.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export class CSSSourceCode extends TextSourceCodeBase {
113113
* @param {Lexer} options.lexer The lexer used to parse the source code.
114114
*/
115115
constructor({ text, ast, comments, lexer }) {
116-
super({ text, ast });
116+
super({ text, ast, lineEndingPattern: /\r\n|[\r\n\f]/u });
117117
this.ast = ast;
118118
this.comments = comments;
119119
this.lexer = lexer;

tests/languages/css-source-code.test.js

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ describe("CSSSourceCode", () => {
107107
describe("getLocFromIndex()", () => {
108108
it("should convert index to location correctly", () => {
109109
const file = {
110-
body: "a {\n /*test*/\r\n}",
110+
body: "a {\n /*test*/\r\n/*test*/\r/*test*/\f/*test*/}",
111111
path: "test.css",
112112
};
113113
const language = new CSSLanguage();
@@ -189,13 +189,33 @@ describe("CSSSourceCode", () => {
189189
line: 3,
190190
column: 2,
191191
});
192+
assert.deepStrictEqual(sourceCode.getLocFromIndex(25), {
193+
line: 4,
194+
column: 1,
195+
});
196+
assert.deepStrictEqual(sourceCode.getLocFromIndex(26), {
197+
line: 4,
198+
column: 2,
199+
});
200+
assert.deepStrictEqual(sourceCode.getLocFromIndex(34), {
201+
line: 5,
202+
column: 1,
203+
});
204+
assert.deepStrictEqual(sourceCode.getLocFromIndex(35), {
205+
line: 5,
206+
column: 2,
207+
});
208+
assert.deepStrictEqual(sourceCode.getLocFromIndex(43), {
209+
line: 5,
210+
column: 10,
211+
});
192212
});
193213
});
194214

195215
describe("getIndexFromLoc()", () => {
196216
it("should convert location to index correctly", () => {
197217
const file = {
198-
body: "a {\n /*test*/\r\n}",
218+
body: "a {\n /*test*/\r\n/*test*/\r/*test*/\f/*test*/}",
199219
path: "test.css",
200220
};
201221
const language = new CSSLanguage();
@@ -331,6 +351,41 @@ describe("CSSSourceCode", () => {
331351
}),
332352
17,
333353
);
354+
assert.strictEqual(
355+
sourceCode.getIndexFromLoc({
356+
line: 4,
357+
column: 1,
358+
}),
359+
25,
360+
);
361+
assert.strictEqual(
362+
sourceCode.getIndexFromLoc({
363+
line: 4,
364+
column: 2,
365+
}),
366+
26,
367+
);
368+
assert.strictEqual(
369+
sourceCode.getIndexFromLoc({
370+
line: 5,
371+
column: 1,
372+
}),
373+
34,
374+
);
375+
assert.strictEqual(
376+
sourceCode.getIndexFromLoc({
377+
line: 5,
378+
column: 2,
379+
}),
380+
35,
381+
);
382+
assert.strictEqual(
383+
sourceCode.getIndexFromLoc({
384+
line: 5,
385+
column: 10,
386+
}),
387+
43,
388+
);
334389
});
335390
});
336391

@@ -402,7 +457,7 @@ describe("CSSSourceCode", () => {
402457
});
403458

404459
describe("lines", () => {
405-
it("should return an array of lines", () => {
460+
it("should split lines on LF line endings", () => {
406461
const file = { body: "a {\n/*test*/\n}", path: "test.css" };
407462
const language = new CSSLanguage();
408463
const parseResult = language.parse(file);
@@ -413,6 +468,63 @@ describe("CSSSourceCode", () => {
413468

414469
assert.deepStrictEqual(sourceCode.lines, ["a {", "/*test*/", "}"]);
415470
});
471+
472+
it("should split lines on CR line endings", () => {
473+
const file = { body: "a {\r/*test*/\r}", path: "test.css" };
474+
const language = new CSSLanguage();
475+
const parseResult = language.parse(file);
476+
const sourceCode = new CSSSourceCode({
477+
text: file.body,
478+
ast: parseResult.ast,
479+
});
480+
481+
assert.deepStrictEqual(sourceCode.lines, ["a {", "/*test*/", "}"]);
482+
});
483+
484+
it("should split lines on FF line endings", () => {
485+
const file = { body: "a {\f/*test*/\f}", path: "test.css" };
486+
const language = new CSSLanguage();
487+
const parseResult = language.parse(file);
488+
const sourceCode = new CSSSourceCode({
489+
text: file.body,
490+
ast: parseResult.ast,
491+
});
492+
493+
assert.deepStrictEqual(sourceCode.lines, ["a {", "/*test*/", "}"]);
494+
});
495+
496+
it("should split lines on CRLF line endings", () => {
497+
const file = { body: "a {\r\n/*test*/\r\n}", path: "test.css" };
498+
const language = new CSSLanguage();
499+
const parseResult = language.parse(file);
500+
const sourceCode = new CSSSourceCode({
501+
text: file.body,
502+
ast: parseResult.ast,
503+
});
504+
505+
assert.deepStrictEqual(sourceCode.lines, ["a {", "/*test*/", "}"]);
506+
});
507+
508+
it("should split lines with mixed line endings (LF, CRLF, CR, FF)", () => {
509+
const file = {
510+
body: "a {\n/*one*/\r\n/*two*/\r/*three*/\f}",
511+
path: "test.css",
512+
};
513+
const language = new CSSLanguage();
514+
const parseResult = language.parse(file);
515+
const sourceCode = new CSSSourceCode({
516+
text: file.body,
517+
ast: parseResult.ast,
518+
});
519+
520+
assert.deepStrictEqual(sourceCode.lines, [
521+
"a {",
522+
"/*one*/",
523+
"/*two*/",
524+
"/*three*/",
525+
"}",
526+
]);
527+
});
416528
});
417529

418530
describe("getParent()", () => {

0 commit comments

Comments
 (0)