@herb-tools/formatter 0.8.7 → 0.8.8
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.esm.js
CHANGED
|
@@ -253,7 +253,7 @@ class Token {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
256
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
256
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/errors.ts.erb
|
|
257
257
|
class HerbError {
|
|
258
258
|
type;
|
|
259
259
|
message;
|
|
@@ -818,7 +818,7 @@ function convertToUTF8(string) {
|
|
|
818
818
|
}
|
|
819
819
|
|
|
820
820
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
821
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
821
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/nodes.ts.erb
|
|
822
822
|
class Node {
|
|
823
823
|
type;
|
|
824
824
|
location;
|
|
@@ -1892,6 +1892,7 @@ class ERBIfNode extends Node {
|
|
|
1892
1892
|
tag_opening;
|
|
1893
1893
|
content;
|
|
1894
1894
|
tag_closing;
|
|
1895
|
+
then_keyword;
|
|
1895
1896
|
statements;
|
|
1896
1897
|
subsequent;
|
|
1897
1898
|
end_node;
|
|
@@ -1906,6 +1907,7 @@ class ERBIfNode extends Node {
|
|
|
1906
1907
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
1907
1908
|
content: data.content ? Token.from(data.content) : null,
|
|
1908
1909
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
1910
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
1909
1911
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
1910
1912
|
subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
|
|
1911
1913
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -1916,6 +1918,7 @@ class ERBIfNode extends Node {
|
|
|
1916
1918
|
this.tag_opening = props.tag_opening;
|
|
1917
1919
|
this.content = props.content;
|
|
1918
1920
|
this.tag_closing = props.tag_closing;
|
|
1921
|
+
this.then_keyword = props.then_keyword;
|
|
1919
1922
|
this.statements = props.statements;
|
|
1920
1923
|
this.subsequent = props.subsequent;
|
|
1921
1924
|
this.end_node = props.end_node;
|
|
@@ -1948,6 +1951,7 @@ class ERBIfNode extends Node {
|
|
|
1948
1951
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
1949
1952
|
content: this.content ? this.content.toJSON() : null,
|
|
1950
1953
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
1954
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
1951
1955
|
statements: this.statements.map(node => node.toJSON()),
|
|
1952
1956
|
subsequent: this.subsequent ? this.subsequent.toJSON() : null,
|
|
1953
1957
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -1960,6 +1964,7 @@ class ERBIfNode extends Node {
|
|
|
1960
1964
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
1961
1965
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
1962
1966
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
1967
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
1963
1968
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
1964
1969
|
output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
|
|
1965
1970
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2041,6 +2046,7 @@ class ERBWhenNode extends Node {
|
|
|
2041
2046
|
tag_opening;
|
|
2042
2047
|
content;
|
|
2043
2048
|
tag_closing;
|
|
2049
|
+
then_keyword;
|
|
2044
2050
|
statements;
|
|
2045
2051
|
static get type() {
|
|
2046
2052
|
return "AST_ERB_WHEN_NODE";
|
|
@@ -2053,6 +2059,7 @@ class ERBWhenNode extends Node {
|
|
|
2053
2059
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2054
2060
|
content: data.content ? Token.from(data.content) : null,
|
|
2055
2061
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2062
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2056
2063
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2057
2064
|
});
|
|
2058
2065
|
}
|
|
@@ -2061,6 +2068,7 @@ class ERBWhenNode extends Node {
|
|
|
2061
2068
|
this.tag_opening = props.tag_opening;
|
|
2062
2069
|
this.content = props.content;
|
|
2063
2070
|
this.tag_closing = props.tag_closing;
|
|
2071
|
+
this.then_keyword = props.then_keyword;
|
|
2064
2072
|
this.statements = props.statements;
|
|
2065
2073
|
}
|
|
2066
2074
|
accept(visitor) {
|
|
@@ -2087,6 +2095,7 @@ class ERBWhenNode extends Node {
|
|
|
2087
2095
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2088
2096
|
content: this.content ? this.content.toJSON() : null,
|
|
2089
2097
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2098
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2090
2099
|
statements: this.statements.map(node => node.toJSON()),
|
|
2091
2100
|
};
|
|
2092
2101
|
}
|
|
@@ -2097,6 +2106,7 @@ class ERBWhenNode extends Node {
|
|
|
2097
2106
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2098
2107
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2099
2108
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2109
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2100
2110
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2101
2111
|
return output;
|
|
2102
2112
|
}
|
|
@@ -2715,6 +2725,7 @@ class ERBUnlessNode extends Node {
|
|
|
2715
2725
|
tag_opening;
|
|
2716
2726
|
content;
|
|
2717
2727
|
tag_closing;
|
|
2728
|
+
then_keyword;
|
|
2718
2729
|
statements;
|
|
2719
2730
|
else_clause;
|
|
2720
2731
|
end_node;
|
|
@@ -2729,6 +2740,7 @@ class ERBUnlessNode extends Node {
|
|
|
2729
2740
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2730
2741
|
content: data.content ? Token.from(data.content) : null,
|
|
2731
2742
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2743
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2732
2744
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2733
2745
|
else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
|
|
2734
2746
|
end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
|
|
@@ -2739,6 +2751,7 @@ class ERBUnlessNode extends Node {
|
|
|
2739
2751
|
this.tag_opening = props.tag_opening;
|
|
2740
2752
|
this.content = props.content;
|
|
2741
2753
|
this.tag_closing = props.tag_closing;
|
|
2754
|
+
this.then_keyword = props.then_keyword;
|
|
2742
2755
|
this.statements = props.statements;
|
|
2743
2756
|
this.else_clause = props.else_clause;
|
|
2744
2757
|
this.end_node = props.end_node;
|
|
@@ -2771,6 +2784,7 @@ class ERBUnlessNode extends Node {
|
|
|
2771
2784
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2772
2785
|
content: this.content ? this.content.toJSON() : null,
|
|
2773
2786
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2787
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2774
2788
|
statements: this.statements.map(node => node.toJSON()),
|
|
2775
2789
|
else_clause: this.else_clause ? this.else_clause.toJSON() : null,
|
|
2776
2790
|
end_node: this.end_node ? this.end_node.toJSON() : null,
|
|
@@ -2783,6 +2797,7 @@ class ERBUnlessNode extends Node {
|
|
|
2783
2797
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2784
2798
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2785
2799
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2800
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2786
2801
|
output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
|
|
2787
2802
|
output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
|
|
2788
2803
|
output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
|
|
@@ -2849,6 +2864,7 @@ class ERBInNode extends Node {
|
|
|
2849
2864
|
tag_opening;
|
|
2850
2865
|
content;
|
|
2851
2866
|
tag_closing;
|
|
2867
|
+
then_keyword;
|
|
2852
2868
|
statements;
|
|
2853
2869
|
static get type() {
|
|
2854
2870
|
return "AST_ERB_IN_NODE";
|
|
@@ -2861,6 +2877,7 @@ class ERBInNode extends Node {
|
|
|
2861
2877
|
tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
|
|
2862
2878
|
content: data.content ? Token.from(data.content) : null,
|
|
2863
2879
|
tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
|
|
2880
|
+
then_keyword: data.then_keyword ? Location.from(data.then_keyword) : null,
|
|
2864
2881
|
statements: (data.statements || []).map(node => fromSerializedNode(node)),
|
|
2865
2882
|
});
|
|
2866
2883
|
}
|
|
@@ -2869,6 +2886,7 @@ class ERBInNode extends Node {
|
|
|
2869
2886
|
this.tag_opening = props.tag_opening;
|
|
2870
2887
|
this.content = props.content;
|
|
2871
2888
|
this.tag_closing = props.tag_closing;
|
|
2889
|
+
this.then_keyword = props.then_keyword;
|
|
2872
2890
|
this.statements = props.statements;
|
|
2873
2891
|
}
|
|
2874
2892
|
accept(visitor) {
|
|
@@ -2895,6 +2913,7 @@ class ERBInNode extends Node {
|
|
|
2895
2913
|
tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
|
|
2896
2914
|
content: this.content ? this.content.toJSON() : null,
|
|
2897
2915
|
tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
|
|
2916
|
+
then_keyword: this.then_keyword ? this.then_keyword.toJSON() : null,
|
|
2898
2917
|
statements: this.statements.map(node => node.toJSON()),
|
|
2899
2918
|
};
|
|
2900
2919
|
}
|
|
@@ -2905,6 +2924,7 @@ class ERBInNode extends Node {
|
|
|
2905
2924
|
output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
|
|
2906
2925
|
output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
|
|
2907
2926
|
output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
|
|
2927
|
+
output += `├── then_keyword: ${this.then_keyword ? "(location: " + this.then_keyword.treeInspect() + ")" : "∅"}\n`;
|
|
2908
2928
|
output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
|
|
2909
2929
|
return output;
|
|
2910
2930
|
}
|
|
@@ -3052,7 +3072,7 @@ class ParseResult extends Result {
|
|
|
3052
3072
|
}
|
|
3053
3073
|
|
|
3054
3074
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3055
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3075
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/node-type-guards.ts.erb
|
|
3056
3076
|
/**
|
|
3057
3077
|
* Type guard functions for AST nodes.
|
|
3058
3078
|
* These functions provide type checking by combining both instanceof
|
|
@@ -3549,7 +3569,7 @@ function getNodesAfterPosition(nodes, position, inclusive = true) {
|
|
|
3549
3569
|
}
|
|
3550
3570
|
|
|
3551
3571
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3552
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.
|
|
3572
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.8/templates/javascript/packages/core/src/visitor.ts.erb
|
|
3553
3573
|
class Visitor {
|
|
3554
3574
|
visit(node) {
|
|
3555
3575
|
if (!node)
|
|
@@ -4540,6 +4560,11 @@ function isFrontmatter(node) {
|
|
|
4540
4560
|
return content.startsWith("---") && /---\s*$/.test(content);
|
|
4541
4561
|
}
|
|
4542
4562
|
|
|
4563
|
+
/**
|
|
4564
|
+
* ASCII whitespace pattern - use instead of \s to preserve Unicode whitespace
|
|
4565
|
+
* characters like NBSP (U+00A0) and full-width space (U+3000)
|
|
4566
|
+
*/
|
|
4567
|
+
const ASCII_WHITESPACE = /[ \t\n\r]+/g;
|
|
4543
4568
|
/**
|
|
4544
4569
|
* Printer traverses the Herb AST using the Visitor pattern
|
|
4545
4570
|
* and emits a formatted string with proper indentation, line breaks, and attribute wrapping.
|
|
@@ -4911,7 +4936,7 @@ class FormatPrinter extends Printer {
|
|
|
4911
4936
|
return true;
|
|
4912
4937
|
}
|
|
4913
4938
|
wouldClassAttributeBeMultiline(content, indentLength) {
|
|
4914
|
-
const normalizedContent = content.replace(
|
|
4939
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4915
4940
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4916
4941
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4917
4942
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4949,12 +4974,12 @@ class FormatPrinter extends Printer {
|
|
|
4949
4974
|
if (/\r?\n/.test(content)) {
|
|
4950
4975
|
const name = attribute.name ? getCombinedAttributeName(attribute.name) : "";
|
|
4951
4976
|
if (name === "class") {
|
|
4952
|
-
const normalizedContent = content.replace(
|
|
4977
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4953
4978
|
return normalizedContent.length > 80;
|
|
4954
4979
|
}
|
|
4955
4980
|
const lines = content.split(/\r?\n/);
|
|
4956
4981
|
if (lines.length > 1) {
|
|
4957
|
-
return lines.slice(1).some(line =>
|
|
4982
|
+
return lines.slice(1).some(line => /^[ \t\n\r]+/.test(line));
|
|
4958
4983
|
}
|
|
4959
4984
|
}
|
|
4960
4985
|
}
|
|
@@ -4962,7 +4987,7 @@ class FormatPrinter extends Printer {
|
|
|
4962
4987
|
});
|
|
4963
4988
|
}
|
|
4964
4989
|
formatClassAttribute(content, name, equals, open_quote, close_quote) {
|
|
4965
|
-
const normalizedContent = content.replace(
|
|
4990
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4966
4991
|
const hasActualNewlines = /\r?\n/.test(content);
|
|
4967
4992
|
if (hasActualNewlines && normalizedContent.length > 80) {
|
|
4968
4993
|
const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line);
|
|
@@ -4991,7 +5016,7 @@ class FormatPrinter extends Printer {
|
|
|
4991
5016
|
}
|
|
4992
5017
|
formatMultilineAttribute(content, name, open_quote, close_quote) {
|
|
4993
5018
|
if (name === 'srcset' || name === 'sizes') {
|
|
4994
|
-
const normalizedContent = content.replace(
|
|
5019
|
+
const normalizedContent = content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
4995
5020
|
return open_quote + normalizedContent + close_quote;
|
|
4996
5021
|
}
|
|
4997
5022
|
const lines = content.split('\n');
|
|
@@ -5181,7 +5206,7 @@ class FormatPrinter extends Printer {
|
|
|
5181
5206
|
nodesToRender.forEach(child => {
|
|
5182
5207
|
if (isNode(child, HTMLTextNode)) {
|
|
5183
5208
|
if (hasTextFlow) {
|
|
5184
|
-
const normalizedContent = child.content.replace(
|
|
5209
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5185
5210
|
if (normalizedContent && normalizedContent !== ' ') {
|
|
5186
5211
|
this.push(normalizedContent);
|
|
5187
5212
|
}
|
|
@@ -5190,7 +5215,7 @@ class FormatPrinter extends Printer {
|
|
|
5190
5215
|
}
|
|
5191
5216
|
}
|
|
5192
5217
|
else {
|
|
5193
|
-
const normalizedContent = child.content.replace(
|
|
5218
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
5194
5219
|
if (shouldPreserveSpaces && normalizedContent) {
|
|
5195
5220
|
this.push(normalizedContent);
|
|
5196
5221
|
}
|
|
@@ -5215,8 +5240,8 @@ class FormatPrinter extends Printer {
|
|
|
5215
5240
|
});
|
|
5216
5241
|
const content = lines.join('');
|
|
5217
5242
|
const inlineContent = shouldPreserveSpaces
|
|
5218
|
-
? (hasTextFlow ? content.replace(
|
|
5219
|
-
: (hasTextFlow ? content.replace(
|
|
5243
|
+
? (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ') : content)
|
|
5244
|
+
: (hasTextFlow ? content.replace(ASCII_WHITESPACE, ' ').trim() : content.trim());
|
|
5220
5245
|
if (inlineContent) {
|
|
5221
5246
|
this.pushToLastLine(inlineContent);
|
|
5222
5247
|
}
|
|
@@ -5405,7 +5430,7 @@ class FormatPrinter extends Printer {
|
|
|
5405
5430
|
}
|
|
5406
5431
|
visitHTMLTextNode(node) {
|
|
5407
5432
|
if (this.inlineMode) {
|
|
5408
|
-
const normalizedContent = node.content.replace(
|
|
5433
|
+
const normalizedContent = node.content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
5409
5434
|
if (normalizedContent) {
|
|
5410
5435
|
this.push(normalizedContent);
|
|
5411
5436
|
}
|
|
@@ -5415,7 +5440,7 @@ class FormatPrinter extends Printer {
|
|
|
5415
5440
|
if (!text)
|
|
5416
5441
|
return;
|
|
5417
5442
|
const wrapWidth = this.maxLineLength - this.indent.length;
|
|
5418
|
-
const words = text.split(
|
|
5443
|
+
const words = text.split(/[ \t\n\r]+/);
|
|
5419
5444
|
const lines = [];
|
|
5420
5445
|
let line = "";
|
|
5421
5446
|
for (const word of words) {
|
|
@@ -5924,7 +5949,7 @@ class FormatPrinter extends Printer {
|
|
|
5924
5949
|
wrappedLines: []
|
|
5925
5950
|
};
|
|
5926
5951
|
}
|
|
5927
|
-
const words = restText.split(
|
|
5952
|
+
const words = restText.split(/[ \t\n\r]+/);
|
|
5928
5953
|
let toMerge = punctuation;
|
|
5929
5954
|
let mergedWordCount = 0;
|
|
5930
5955
|
for (const word of words) {
|
|
@@ -6074,7 +6099,7 @@ class FormatPrinter extends Printer {
|
|
|
6074
6099
|
words.push({ word: unit.content, isHerbDisable: unit.isHerbDisable || false });
|
|
6075
6100
|
}
|
|
6076
6101
|
else {
|
|
6077
|
-
const text = unit.content.replace(
|
|
6102
|
+
const text = unit.content.replace(ASCII_WHITESPACE, ' ');
|
|
6078
6103
|
const hasLeadingSpace = text.startsWith(' ');
|
|
6079
6104
|
const hasTrailingSpace = text.endsWith(' ');
|
|
6080
6105
|
const trimmedText = text.trim();
|
|
@@ -6120,7 +6145,7 @@ class FormatPrinter extends Printer {
|
|
|
6120
6145
|
return false;
|
|
6121
6146
|
const firstWord = words[0];
|
|
6122
6147
|
const firstChar = firstWord[0];
|
|
6123
|
-
if (
|
|
6148
|
+
if (' \t\n\r'.includes(firstChar)) {
|
|
6124
6149
|
return false;
|
|
6125
6150
|
}
|
|
6126
6151
|
lastUnit.unit.content += firstWord;
|
|
@@ -6177,7 +6202,7 @@ class FormatPrinter extends Printer {
|
|
|
6177
6202
|
if (hasWhitespaceBetween(children, lastProcessedIndex, currentIndex)) {
|
|
6178
6203
|
return true;
|
|
6179
6204
|
}
|
|
6180
|
-
if (isNode(currentNode, HTMLTextNode) &&
|
|
6205
|
+
if (isNode(currentNode, HTMLTextNode) && /^[ \t\n\r]/.test(currentNode.content)) {
|
|
6181
6206
|
return true;
|
|
6182
6207
|
}
|
|
6183
6208
|
return false;
|
|
@@ -6516,9 +6541,9 @@ class FormatPrinter extends Printer {
|
|
|
6516
6541
|
const shouldPreserveSpaces = hasOnlyTextContent && tagName && isInlineElement(tagName);
|
|
6517
6542
|
for (const child of children) {
|
|
6518
6543
|
if (isNode(child, HTMLTextNode)) {
|
|
6519
|
-
const normalizedContent = child.content.replace(
|
|
6520
|
-
const hasLeadingSpace =
|
|
6521
|
-
const hasTrailingSpace =
|
|
6544
|
+
const normalizedContent = child.content.replace(ASCII_WHITESPACE, ' ');
|
|
6545
|
+
const hasLeadingSpace = /^[ \t\n\r]/.test(child.content);
|
|
6546
|
+
const hasTrailingSpace = /[ \t\n\r]$/.test(child.content);
|
|
6522
6547
|
const trimmedContent = normalizedContent.trim();
|
|
6523
6548
|
if (trimmedContent) {
|
|
6524
6549
|
if (hasLeadingSpace && (result || shouldPreserveSpaces) && !result.endsWith(' ')) {
|
|
@@ -6625,7 +6650,7 @@ class FormatPrinter extends Printer {
|
|
|
6625
6650
|
content += this.reconstructERBNode(child, true);
|
|
6626
6651
|
}
|
|
6627
6652
|
}
|
|
6628
|
-
return content.replace(
|
|
6653
|
+
return content.replace(ASCII_WHITESPACE, ' ').trim();
|
|
6629
6654
|
}
|
|
6630
6655
|
}
|
|
6631
6656
|
|