@herb-tools/formatter 0.8.7 → 0.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/herb-format.js +81 -2775
- package/dist/herb-format.js.map +1 -1
- package/dist/index.cjs +48 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +48 -23
- package/dist/index.esm.js.map +1 -1
- package/package.json +5 -5
- package/src/format-printer.ts +25 -19
package/dist/index.cjs
CHANGED
|
@@ -255,7 +255,7 @@ class Token {
|
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
258
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
258
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/core/src/errors.ts.erb
|
|
259
259
|
class HerbError {
|
|
260
260
|
type;
|
|
261
261
|
message;
|
|
@@ -820,7 +820,7 @@ function convertToUTF8(string) {
|
|
|
820
820
|
}
|
|
821
821
|
|
|
822
822
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
823
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
823
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/core/src/nodes.ts.erb
|
|
824
824
|
class Node {
|
|
825
825
|
type;
|
|
826
826
|
location;
|
|
@@ -1894,6 +1894,7 @@ class ERBIfNode extends Node {
|
|
|
1894
1894
|
tag_opening;
|
|
1895
1895
|
content;
|
|
1896
1896
|
tag_closing;
|
|
1897
|
+
then_keyword;
|
|
1897
1898
|
statements;
|
|
1898
1899
|
subsequent;
|
|
1899
1900
|
end_node;
|
|
@@ -1908,6 +1909,7 @@ class ERBIfNode extends Node {
|
|
|
1908
1909
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
1909
1910
|
content: data.content ? Token.from(data.content) : null,
|
|
1910
1911
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
1912
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
1911
1913
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
1912
1914
|
subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
|
|
1913
1915
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -1918,6 +1920,7 @@ class ERBIfNode extends Node {
|
|
|
1918
1920
|
this.tag_opening = props.tag_opening;
|
|
1919
1921
|
this.content = props.content;
|
|
1920
1922
|
this.tag_closing = props.tag_closing;
|
|
1923
|
+
this.then_keyword = props.then_keyword;
|
|
1921
1924
|
this.statements = props.statements;
|
|
1922
1925
|
this.subsequent = props.subsequent;
|
|
1923
1926
|
this.end_node = props.end_node;
|
|
@@ -1950,6 +1953,7 @@ class ERBIfNode extends Node {
|
|
|
1950
1953
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
1951
1954
|
content: this.content ? this.content.toJSON() : null,
|
|
1952
1955
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
1956
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
1953
1957
|
statements: this.statements.map(node => node.toJSON()),
|
|
1954
1958
|
subsequent: this.subsequent ? this.subsequent.toJSON() : null,
|
|
1955
1959
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -1962,6 +1966,7 @@ class ERBIfNode extends Node {
|
|
|
1962
1966
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
1963
1967
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
1964
1968
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
1969
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
1965
1970
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
1966
1971
|
output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
|
|
1967
1972
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2043,6 +2048,7 @@ class ERBWhenNode extends Node {
|
|
|
2043
2048
|
tag_opening;
|
|
2044
2049
|
content;
|
|
2045
2050
|
tag_closing;
|
|
2051
|
+
then_keyword;
|
|
2046
2052
|
statements;
|
|
2047
2053
|
static get type() {
|
|
2048
2054
|
return "AST_ERB_WHEN_NODE";
|
|
@@ -2055,6 +2061,7 @@ class ERBWhenNode extends Node {
|
|
|
2055
2061
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2056
2062
|
content: data.content ? Token.from(data.content) : null,
|
|
2057
2063
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2064
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2058
2065
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2059
2066
|
});
|
|
2060
2067
|
}
|
|
@@ -2063,6 +2070,7 @@ class ERBWhenNode extends Node {
|
|
|
2063
2070
|
this.tag_opening = props.tag_opening;
|
|
2064
2071
|
this.content = props.content;
|
|
2065
2072
|
this.tag_closing = props.tag_closing;
|
|
2073
|
+
this.then_keyword = props.then_keyword;
|
|
2066
2074
|
this.statements = props.statements;
|
|
2067
2075
|
}
|
|
2068
2076
|
accept(visitor) {
|
|
@@ -2089,6 +2097,7 @@ class ERBWhenNode extends Node {
|
|
|
2089
2097
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2090
2098
|
content: this.content ? this.content.toJSON() : null,
|
|
2091
2099
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2100
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2092
2101
|
statements: this.statements.map(node => node.toJSON()),
|
|
2093
2102
|
};
|
|
2094
2103
|
}
|
|
@@ -2099,6 +2108,7 @@ class ERBWhenNode extends Node {
|
|
|
2099
2108
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2100
2109
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2101
2110
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2111
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2102
2112
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2103
2113
|
return output;
|
|
2104
2114
|
}
|
|
@@ -2717,6 +2727,7 @@ class ERBUnlessNode extends Node {
|
|
|
2717
2727
|
tag_opening;
|
|
2718
2728
|
content;
|
|
2719
2729
|
tag_closing;
|
|
2730
|
+
then_keyword;
|
|
2720
2731
|
statements;
|
|
2721
2732
|
else_clause;
|
|
2722
2733
|
end_node;
|
|
@@ -2731,6 +2742,7 @@ class ERBUnlessNode extends Node {
|
|
|
2731
2742
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2732
2743
|
content: data.content ? Token.from(data.content) : null,
|
|
2733
2744
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2745
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2734
2746
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2735
2747
|
else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
|
|
2736
2748
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -2741,6 +2753,7 @@ class ERBUnlessNode extends Node {
|
|
|
2741
2753
|
this.tag_opening = props.tag_opening;
|
|
2742
2754
|
this.content = props.content;
|
|
2743
2755
|
this.tag_closing = props.tag_closing;
|
|
2756
|
+
this.then_keyword = props.then_keyword;
|
|
2744
2757
|
this.statements = props.statements;
|
|
2745
2758
|
this.else_clause = props.else_clause;
|
|
2746
2759
|
this.end_node = props.end_node;
|
|
@@ -2773,6 +2786,7 @@ class ERBUnlessNode extends Node {
|
|
|
2773
2786
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2774
2787
|
content: this.content ? this.content.toJSON() : null,
|
|
2775
2788
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2789
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2776
2790
|
statements: this.statements.map(node => node.toJSON()),
|
|
2777
2791
|
else_clause: this.else_clause ? this.else_clause.toJSON() : null,
|
|
2778
2792
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -2785,6 +2799,7 @@ class ERBUnlessNode extends Node {
|
|
|
2785
2799
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2786
2800
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2787
2801
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2802
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2788
2803
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
2789
2804
|
output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
|
|
2790
2805
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2851,6 +2866,7 @@ class ERBInNode extends Node {
|
|
|
2851
2866
|
tag_opening;
|
|
2852
2867
|
content;
|
|
2853
2868
|
tag_closing;
|
|
2869
|
+
then_keyword;
|
|
2854
2870
|
statements;
|
|
2855
2871
|
static get type() {
|
|
2856
2872
|
return "AST_ERB_IN_NODE";
|
|
@@ -2863,6 +2879,7 @@ class ERBInNode extends Node {
|
|
|
2863
2879
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2864
2880
|
content: data.content ? Token.from(data.content) : null,
|
|
2865
2881
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2882
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2866
2883
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2867
2884
|
});
|
|
2868
2885
|
}
|
|
@@ -2871,6 +2888,7 @@ class ERBInNode extends Node {
|
|
|
2871
2888
|
this.tag_opening = props.tag_opening;
|
|
2872
2889
|
this.content = props.content;
|
|
2873
2890
|
this.tag_closing = props.tag_closing;
|
|
2891
|
+
this.then_keyword = props.then_keyword;
|
|
2874
2892
|
this.statements = props.statements;
|
|
2875
2893
|
}
|
|
2876
2894
|
accept(visitor) {
|
|
@@ -2897,6 +2915,7 @@ class ERBInNode extends Node {
|
|
|
2897
2915
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2898
2916
|
content: this.content ? this.content.toJSON() : null,
|
|
2899
2917
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2918
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2900
2919
|
statements: this.statements.map(node => node.toJSON()),
|
|
2901
2920
|
};
|
|
2902
2921
|
}
|
|
@@ -2907,6 +2926,7 @@ class ERBInNode extends Node {
|
|
|
2907
2926
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2908
2927
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2909
2928
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2929
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2910
2930
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2911
2931
|
return output;
|
|
2912
2932
|
}
|
|
@@ -3054,7 +3074,7 @@ class ParseResult extends Result {
|
|
|
3054
3074
|
}
|
|
3055
3075
|
|
|
3056
3076
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3057
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3077
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/core/src/node-type-guards.ts.erb
|
|
3058
3078
|
/**
|
|
3059
3079
|
* Type guard functions for AST nodes.
|
|
3060
3080
|
* These functions provide type checking by combining both instanceof
|
|
@@ -3551,7 +3571,7 @@ function getNodesAfterPosition(nodes, position, inclusive = true) {
|
|
|
3551
3571
|
}
|
|
3552
3572
|
|
|
3553
3573
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3554
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3574
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.9/templates/javascript/packages/core/src/visitor.ts.erb
|
|
3555
3575
|
class Visitor {
|
|
3556
3576
|
visit(node) {
|
|
3557
3577
|
if (!node)
|
|
@@ -4542,6 +4562,11 @@ function isFrontmatter(node) {
|
|
|
4542
4562
|
return content.startsWith("---") && /---\s*$/.test(content);
|
|
4543
4563
|
}
|
|
4544
4564
|
|
|
4565
|
+
/**
|
|
4566
|
+
* ASCII whitespace pattern - use instead of \s to preserve Unicode whitespace
|
|
4567
|
+
* characters like NBSP (U+00A0) and full-width space (U+3000)
|
|
4568
|
+
*/
|
|
4569
|
+
const ASCII_WHITESPACE = /[ \t\n\r]+/g;
|
|
4545
4570
|
/**
|
|
4546
4571
|
* Printer traverses the Herb AST using the Visitor pattern
|
|
4547
4572
|
* and emits a formatted string with proper indentation, line breaks, and attribute wrapping.
|
|
@@ -4913,7 +4938,7 @@ class FormatPrinter extends Printer {
|
|
|
4913
4938
|
return true;
|
|
4914
4939
|
}
|
|
4915
4940
|
wouldClassAttributeBeMultiline(content, indentLength) {
|
|
4916
|
-
const normalizedContent = content.replace(
|
|
4941
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4917
4942
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4918
4943
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4919
4944
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4951,12 +4976,12 @@ class FormatPrinter extends Printer {
|
|
|
4951
4976
|
if (/\r?\n/.test(content)) {
|
|
4952
4977
|
const name = attribute.name ? getCombinedAttributeName(attribute.name) : "";
|
|
4953
4978
|
if (name === "class") {
|
|
4954
|
-
const normalizedContent = content.replace(
|
|
4979
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4955
4980
|
return normalizedContent.length > 80;
|
|
4956
4981
|
}
|
|
4957
4982
|
const lines = content.split(/\r?\n/);
|
|
4958
4983
|
if (lines.length > 1) {
|
|
4959
|
-
return lines.slice(1).some(line =>
|
|
4984
|
+
return lines.slice(1).some(line => /^[ \t\n\r]+/.test(line));
|
|
4960
4985
|
}
|
|
4961
4986
|
}
|
|
4962
4987
|
}
|
|
@@ -4964,7 +4989,7 @@ class FormatPrinter extends Printer {
|
|
|
4964
4989
|
});
|
|
4965
4990
|
}
|
|
4966
4991
|
formatClassAttribute(content, name, equals, open_quote, close_quote) {
|
|
4967
|
-
const normalizedContent = content.replace(
|
|
4992
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4968
4993
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4969
4994
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4970
4995
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4993,7 +5018,7 @@ class FormatPrinter extends Printer {
|
|
|
4993
5018
|
}
|
|
4994
5019
|
formatMultilineAttribute(content, name, open_quote, close_quote) {
|
|
4995
5020
|
if (name === 'srcset' || name === 'sizes') {
|
|
4996
|
-
const normalizedContent = content.replace(
|
|
5021
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4997
5022
|
return open_quote + normalizedContent + close_quote;
|
|
4998
5023
|
}
|
|
4999
5024
|
const lines = content.split('\n');
|
|
@@ -5183,7 +5208,7 @@ class FormatPrinter extends Printer {
|
|
|
5183
5208
|
nodesToRender.forEach(child => {
|
|
5184
5209
|
if (isNode(child, HTMLTextNode)) {
|
|
5185
5210
|
if (hasTextFlow) {
|
|
5186
|
-
const normalizedContent = child.content.replace(
|
|
5211
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5187
5212
|
if (normalizedContent && normalizedContent !== ' ') {
|
|
5188
5213
|
this.push(normalizedContent);
|
|
5189
5214
|
}
|
|
@@ -5192,7 +5217,7 @@ class FormatPrinter extends Printer {
|
|
|
5192
5217
|
}
|
|
5193
5218
|
}
|
|
5194
5219
|
else {
|
|
5195
|
-
const normalizedContent = child.content.replace(
|
|
5220
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5196
5221
|
if (shouldPreserveSpaces && normalizedContent) {
|
|
5197
5222
|
this.push(normalizedContent);
|
|
5198
5223
|
}
|
|
@@ -5217,8 +5242,8 @@ class FormatPrinter extends Printer {
|
|
|
5217
5242
|
});
|
|
5218
5243
|
const content = lines.join('');
|
|
5219
5244
|
const inlineContent = shouldPreserveSpaces
|
|
5220
|
-
? (hasTextFlow ? content.replace(
|
|
5221
|
-
: (hasTextFlow ? content.replace(
|
|
5245
|
+
? (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ') : content)
|
|
5246
|
+
: (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ').trim() : content.trim());
|
|
5222
5247
|
if (inlineContent) {
|
|
5223
5248
|
this.pushToLastLine(inlineContent);
|
|
5224
5249
|
}
|
|
@@ -5407,7 +5432,7 @@ class FormatPrinter extends Printer {
|
|
|
5407
5432
|
}
|
|
5408
5433
|
visitHTMLTextNode(node) {
|
|
5409
5434
|
if (this.inlineMode) {
|
|
5410
|
-
const normalizedContent = node.content.replace(
|
|
5435
|
+
const normalizedContent = node.content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
5411
5436
|
if (normalizedContent) {
|
|
5412
5437
|
this.push(normalizedContent);
|
|
5413
5438
|
}
|
|
@@ -5417,7 +5442,7 @@ class FormatPrinter extends Printer {
|
|
|
5417
5442
|
if (!text)
|
|
5418
5443
|
return;
|
|
5419
5444
|
const wrapWidth = this.maxLineLength - this.indent.length;
|
|
5420
|
-
const words = text.split(
|
|
5445
|
+
const words = text.split(/[ \t\n\r]+/);
|
|
5421
5446
|
const lines = [];
|
|
5422
5447
|
let line = "";
|
|
5423
5448
|
for (const word of words) {
|
|
@@ -5926,7 +5951,7 @@ class FormatPrinter extends Printer {
|
|
|
5926
5951
|
wrappedLines: []
|
|
5927
5952
|
};
|
|
5928
5953
|
}
|
|
5929
|
-
const words = restText.split(
|
|
5954
|
+
const words = restText.split(/[ \t\n\r]+/);
|
|
5930
5955
|
let toMerge = punctuation;
|
|
5931
5956
|
let mergedWordCount = 0;
|
|
5932
5957
|
for (const word of words) {
|
|
@@ -6076,7 +6101,7 @@ class FormatPrinter extends Printer {
|
|
|
6076
6101
|
words.push({ word: unit.content, isHerbDisable: unit.isHerbDisable || false });
|
|
6077
6102
|
}
|
|
6078
6103
|
else {
|
|
6079
|
-
const text = unit.content.replace(
|
|
6104
|
+
const text = unit.content.replace(ASCII_WHITESPACE, ' ');
|
|
6080
6105
|
const hasLeadingSpace = text.startsWith(' ');
|
|
6081
6106
|
const hasTrailingSpace = text.endsWith(' ');
|
|
6082
6107
|
const trimmedText = text.trim();
|
|
@@ -6122,7 +6147,7 @@ class FormatPrinter extends Printer {
|
|
|
6122
6147
|
return false;
|
|
6123
6148
|
const firstWord = words[0];
|
|
6124
6149
|
const firstChar = firstWord[0];
|
|
6125
|
-
if (
|
|
6150
|
+
if (' \t\n\r'.includes(firstChar)) {
|
|
6126
6151
|
return false;
|
|
6127
6152
|
}
|
|
6128
6153
|
lastUnit.unit.content += firstWord;
|
|
@@ -6179,7 +6204,7 @@ class FormatPrinter extends Printer {
|
|
|
6179
6204
|
if (hasWhitespaceBetween(children, lastProcessedIndex, currentIndex)) {
|
|
6180
6205
|
return true;
|
|
6181
6206
|
}
|
|
6182
|
-
if (isNode(currentNode, HTMLTextNode) &&
|
|
6207
|
+
if (isNode(currentNode, HTMLTextNode) && /^[ \t\n\r]/.test(currentNode.content)) {
|
|
6183
6208
|
return true;
|
|
6184
6209
|
}
|
|
6185
6210
|
return false;
|
|
@@ -6518,9 +6543,9 @@ class FormatPrinter extends Printer {
|
|
|
6518
6543
|
const shouldPreserveSpaces = hasOnlyTextContent && tagName && isInlineElement(tagName);
|
|
6519
6544
|
for (const child of children) {
|
|
6520
6545
|
if (isNode(child, HTMLTextNode)) {
|
|
6521
|
-
const normalizedContent = child.content.replace(
|
|
6522
|
-
const hasLeadingSpace =
|
|
6523
|
-
const hasTrailingSpace =
|
|
6546
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
6547
|
+
const hasLeadingSpace = /^[ \t\n\r]/.test(child.content);
|
|
6548
|
+
const hasTrailingSpace = /[ \t\n\r]$/.test(child.content);
|
|
6524
6549
|
const trimmedContent = normalizedContent.trim();
|
|
6525
6550
|
if (trimmedContent) {
|
|
6526
6551
|
if (hasLeadingSpace && (result || shouldPreserveSpaces) && !result.endsWith(' ')) {
|
|
@@ -6627,7 +6652,7 @@ class FormatPrinter extends Printer {
|
|
|
6627
6652
|
content += this.reconstructERBNode(child, true);
|
|
6628
6653
|
}
|
|
6629
6654
|
}
|
|
6630
|
-
return content.replace(
|
|
6655
|
+
return content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
6631
6656
|
}
|
|
6632
6657
|
}
|
|
6633
6658
|
|