mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-22 05:41:14 +01:00
Clean up _writeWithIndent() (#216)
This improves formatting and fixes a case where it crashed on trailing whitespace.
This commit is contained in:
parent
da2ff6a06d
commit
67494e2b2a
@ -132,6 +132,7 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
|
|||||||
|
|
||||||
void visitComment(CssComment node) {
|
void visitComment(CssComment node) {
|
||||||
var minimumIndentation = _minimumIndentation(node.text);
|
var minimumIndentation = _minimumIndentation(node.text);
|
||||||
|
assert(minimumIndentation != -1);
|
||||||
if (minimumIndentation == null) {
|
if (minimumIndentation == null) {
|
||||||
_writeIndentation();
|
_writeIndentation();
|
||||||
_buffer.write(node.text);
|
_buffer.write(node.text);
|
||||||
@ -261,6 +262,10 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
|
|||||||
if (minimumIndentation == null) {
|
if (minimumIndentation == null) {
|
||||||
_buffer.write(value);
|
_buffer.write(value);
|
||||||
return;
|
return;
|
||||||
|
} else if (minimumIndentation == -1) {
|
||||||
|
_buffer.write(value.trimRight());
|
||||||
|
_buffer.writeCharCode($space);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.value.span != null) {
|
if (node.value.span != null) {
|
||||||
@ -271,8 +276,11 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
|
|||||||
_writeWithIndent(value, minimumIndentation);
|
_writeWithIndent(value, minimumIndentation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the indentation level of the least-indented, non-empty line in
|
/// Returns the indentation level of the least-indented non-empty line in
|
||||||
/// [text].
|
/// [text] after the first.
|
||||||
|
///
|
||||||
|
/// Returns `null` if [text] contains no newlines, and -1 if it contains
|
||||||
|
/// newlines but no lines are indented.
|
||||||
int _minimumIndentation(String text) {
|
int _minimumIndentation(String text) {
|
||||||
var scanner = new LineScanner(text);
|
var scanner = new LineScanner(text);
|
||||||
while (!scanner.isDone && scanner.readChar() != $lf) {}
|
while (!scanner.isDone && scanner.readChar() != $lf) {}
|
||||||
@ -290,23 +298,54 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
|
|||||||
while (!scanner.isDone && scanner.readChar() != $lf) {}
|
while (!scanner.isDone && scanner.readChar() != $lf) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return min;
|
return min ?? -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes [text] to [_buffer], adding [minimumIndentation] to each non-empty
|
/// Writes [text] to [_buffer], replacing [minimumIndentation] with
|
||||||
/// line.
|
/// [_indentation] for each non-empty line after the first.
|
||||||
|
///
|
||||||
|
/// Compresses trailing empty lines of [text] into a single trailing space.
|
||||||
void _writeWithIndent(String text, int minimumIndentation) {
|
void _writeWithIndent(String text, int minimumIndentation) {
|
||||||
var scanner = new LineScanner(text);
|
var scanner = new LineScanner(text);
|
||||||
while (!scanner.isDone && scanner.peekChar() != $lf) {
|
|
||||||
_buffer.writeCharCode(scanner.readChar());
|
// Write the first line as-is.
|
||||||
|
while (!scanner.isDone) {
|
||||||
|
var next = scanner.readChar();
|
||||||
|
if (next == $lf) break;
|
||||||
|
_buffer.writeCharCode(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!scanner.isDone) {
|
while (true) {
|
||||||
_buffer.writeCharCode(scanner.readChar());
|
assert(isWhitespace(scanner.peekChar(-1)));
|
||||||
for (var i = 0; i < minimumIndentation; i++) scanner.readChar();
|
|
||||||
|
// Scan forward until we hit non-whitespace or the end of [text].
|
||||||
|
var lineStart = scanner.position;
|
||||||
|
var newlines = 1;
|
||||||
|
while (true) {
|
||||||
|
// If we hit the end of [text], we still need to preserve the fact that
|
||||||
|
// whitespace exists because it could matter for custom properties.
|
||||||
|
if (scanner.isDone) {
|
||||||
|
_buffer.writeCharCode($space);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = scanner.readChar();
|
||||||
|
if (next == $space || next == $tab) continue;
|
||||||
|
if (next != $lf) break;
|
||||||
|
lineStart = scanner.position;
|
||||||
|
newlines++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeTimes($lf, newlines);
|
||||||
_writeIndentation();
|
_writeIndentation();
|
||||||
while (!scanner.isDone && scanner.peekChar() != $lf) {
|
_buffer.write(scanner.substring(lineStart + minimumIndentation));
|
||||||
_buffer.writeCharCode(scanner.readChar());
|
|
||||||
|
// Scan and write until we hit a newline or the end of [text].
|
||||||
|
while (true) {
|
||||||
|
if (scanner.isDone) return;
|
||||||
|
var next = scanner.readChar();
|
||||||
|
if (next == $lf) break;
|
||||||
|
_buffer.writeCharCode(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -848,9 +887,13 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Writes indentation based on [_indentation].
|
/// Writes indentation based on [_indentation].
|
||||||
void _writeIndentation() {
|
void _writeIndentation() =>
|
||||||
for (var i = 0; i < _indentation * _indentWidth; i++) {
|
_writeTimes(_indentCharacter, _indentation * _indentWidth);
|
||||||
_buffer.writeCharCode(_indentCharacter);
|
|
||||||
|
/// Writes [char] to [_buffer] with [times] repetitions.
|
||||||
|
void _writeTimes(int char, int times) {
|
||||||
|
for (var i = 0; i < times; i++) {
|
||||||
|
_buffer.writeCharCode(char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user