Skip to content

Commit 4b6ba1b

Browse files
authoredApr 21, 2022
Merge branch 'main' into in-class-method
2 parents a5995d0 + 508e803 commit 4b6ba1b

18 files changed

+1269
-336
lines changed
 

‎CHANGELOG.md

+459
Large diffs are not rendered by default.

‎README.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,17 @@ JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries
5858

5959
To pull the latest version from one of these services include one set of the script tags below in your document:
6060
```html
61-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.2/beautify.js"></script>
62-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.2/beautify-css.js"></script>
63-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.2/beautify-html.js"></script>
61+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify.js"></script>
62+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-css.js"></script>
63+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-html.js"></script>
6464

65-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.2/beautify.min.js"></script>
66-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.2/beautify-css.min.js"></script>
67-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.2/beautify-html.min.js"></script>
65+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify.min.js"></script>
66+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-css.min.js"></script>
67+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-html.min.js"></script>
6868

69-
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.2/js/lib/beautify.js"></script>
70-
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.2/js/lib/beautify-css.js"></script>
71-
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.2/js/lib/beautify-html.js"></script>
69+
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.3/js/lib/beautify.js"></script>
70+
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.3/js/lib/beautify-css.js"></script>
71+
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.3/js/lib/beautify-html.js"></script>
7272
```
7373

7474
Older versions are available by changing the version number.
@@ -401,4 +401,4 @@ Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, D
401401
Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
402402
Mathias Bynens, Vittorio Gambaletta and others.
403403
404-
(README.md: js-beautify@1.14.2)
404+
(README.md: js-beautify@1.14.3)

‎index.html

+200-209
Large diffs are not rendered by default.

‎js/src/css/beautifier.js

+44-7
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ function Beautifier(source_text, options) {
6767
"@supports": true,
6868
"@document": true
6969
};
70+
this.NON_SEMICOLON_NEWLINE_PROPERTY = [
71+
"grid-template-areas",
72+
"grid-template"
73+
];
7074

7175
}
7276

@@ -191,7 +195,9 @@ Beautifier.prototype.beautify = function() {
191195
var enteringConditionalGroup = false;
192196
var insideAtExtend = false;
193197
var insideAtImport = false;
198+
var insideScssMap = false;
194199
var topCharacter = this._ch;
200+
var insideNonSemiColonValues = false;
195201
var whitespace;
196202
var isAfterSpace;
197203
var previous_ch;
@@ -243,7 +249,7 @@ Beautifier.prototype.beautify = function() {
243249

244250
// Ensures any new lines following the comment are preserved
245251
this.eatWhitespace(true);
246-
} else if (this._ch === '@') {
252+
} else if (this._ch === '@' || this._ch === '$') {
247253
this.preserveSingleSpace(isAfterSpace);
248254

249255
// deal with less propery mixins @{...}
@@ -358,6 +364,14 @@ Beautifier.prototype.beautify = function() {
358364
}
359365
}
360366
} else if (this._ch === ":") {
367+
368+
for (var i = 0; i < this.NON_SEMICOLON_NEWLINE_PROPERTY.length; i++) {
369+
if (this._input.lookBack(this.NON_SEMICOLON_NEWLINE_PROPERTY[i])) {
370+
insideNonSemiColonValues = true;
371+
break;
372+
}
373+
}
374+
361375
if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) {
362376
// 'property: value' delimiter
363377
// which could be in a conditional group query
@@ -390,6 +404,7 @@ Beautifier.prototype.beautify = function() {
390404
this.print_string(this._ch + this.eatString(this._ch));
391405
this.eatWhitespace(true);
392406
} else if (this._ch === ';') {
407+
insideNonSemiColonValues = false;
393408
if (parenLevel === 0) {
394409
if (insidePropertyValue) {
395410
this.outdent();
@@ -429,22 +444,39 @@ Beautifier.prototype.beautify = function() {
429444
}
430445
}
431446
} else {
432-
this.preserveSingleSpace(isAfterSpace);
447+
var space_needed = false;
448+
if (this._input.lookBack("with")) {
449+
// look back is not an accurate solution, we need tokens to confirm without whitespaces
450+
space_needed = true;
451+
}
452+
this.preserveSingleSpace(isAfterSpace || space_needed);
433453
this.print_string(this._ch);
434-
this.eatWhitespace();
435-
parenLevel++;
436-
this.indent();
454+
455+
// handle scss/sass map
456+
if (insidePropertyValue && previous_ch === "$" && this._options.selector_separator_newline) {
457+
this._output.add_new_line();
458+
insideScssMap = true;
459+
} else {
460+
this.eatWhitespace();
461+
parenLevel++;
462+
this.indent();
463+
}
437464
}
438465
} else if (this._ch === ')') {
439466
if (parenLevel) {
440467
parenLevel--;
441468
this.outdent();
442469
}
470+
if (insideScssMap && this._input.peek() === ";" && this._options.selector_separator_newline) {
471+
insideScssMap = false;
472+
this.outdent();
473+
this._output.add_new_line();
474+
}
443475
this.print_string(this._ch);
444476
} else if (this._ch === ',') {
445477
this.print_string(this._ch);
446478
this.eatWhitespace(true);
447-
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
479+
if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
448480
this._output.add_new_line();
449481
} else {
450482
this._output.space_before_token = true;
@@ -478,8 +510,13 @@ Beautifier.prototype.beautify = function() {
478510
this.print_string(' ');
479511
this.print_string(this._ch);
480512
} else {
481-
this.preserveSingleSpace(isAfterSpace);
513+
var preserveAfterSpace = previous_ch === '"' || previous_ch === '\'';
514+
this.preserveSingleSpace(preserveAfterSpace || isAfterSpace);
482515
this.print_string(this._ch);
516+
517+
if (!this._output.just_added_newline() && this._input.peek() === '\n' && insideNonSemiColonValues) {
518+
this._output.add_new_line();
519+
}
483520
}
484521
}
485522

‎js/src/html/beautifier.js

+18-5
Original file line numberDiff line numberDiff line change
@@ -607,14 +607,19 @@ var TagOpenParserToken = function(parent, raw_token) {
607607
tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
608608
this.tag_check = tag_check_match ? tag_check_match[1] : '';
609609
} else {
610-
tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
610+
tag_check_match = raw_token.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/);
611611
this.tag_check = tag_check_match ? tag_check_match[1] : '';
612612

613-
// handle "{{#> myPartial}}
614-
if (raw_token.text === '{{#>' && this.tag_check === '>' && raw_token.next !== null) {
615-
this.tag_check = raw_token.next.text.split(' ')[0];
613+
// handle "{{#> myPartial}}" or "{{~#> myPartial}}"
614+
if ((raw_token.text.startsWith('{{#>') || raw_token.text.startsWith('{{~#>')) && this.tag_check[0] === '>') {
615+
if (this.tag_check === '>' && raw_token.next !== null) {
616+
this.tag_check = raw_token.next.text.split(' ')[0];
617+
} else {
618+
this.tag_check = raw_token.text.split('>')[1];
619+
}
616620
}
617621
}
622+
618623
this.tag_check = this.tag_check.toLowerCase();
619624

620625
if (raw_token.type === TOKEN.COMMENT) {
@@ -626,9 +631,17 @@ var TagOpenParserToken = function(parent, raw_token) {
626631
this.is_end_tag = !this.is_start_tag ||
627632
(raw_token.closed && raw_token.closed.text === '/>');
628633

634+
// if whitespace handler ~ included (i.e. {{~#if true}}), handlebars tags start at pos 3 not pos 2
635+
var handlebar_starts = 2;
636+
if (this.tag_start_char === '{' && this.text.length >= 3) {
637+
if (this.text.charAt(2) === '~') {
638+
handlebar_starts = 3;
639+
}
640+
}
641+
629642
// handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
630643
this.is_end_tag = this.is_end_tag ||
631-
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(2)))));
644+
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
632645
}
633646
};
634647

‎js/src/javascript/beautifier.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -1151,13 +1151,6 @@ Beautifier.prototype.handle_operator = function(current_token) {
11511151
this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
11521152
}
11531153

1154-
if (reserved_array(this._flags.last_token, special_words)) {
1155-
// "return" had a special handling in TK_WORD. Now we need to return the favor
1156-
this._output.space_before_token = true;
1157-
this.print_token(current_token);
1158-
return;
1159-
}
1160-
11611154
// hack for actionscript's import .*;
11621155
if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) {
11631156
this.print_token(current_token);
@@ -1285,7 +1278,11 @@ Beautifier.prototype.handle_operator = function(current_token) {
12851278
// http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
12861279
// if there is a newline between -- or ++ and anything else we should preserve it.
12871280
if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) {
1288-
this.print_newline(false, true);
1281+
var new_line_needed = reserved_array(this._flags.last_token, special_words) && current_token.newlines;
1282+
if (new_line_needed && (this._previous_flags.if_block || this._previous_flags.else_block)) {
1283+
this.restore_mode();
1284+
}
1285+
this.print_newline(new_line_needed, true);
12891286
}
12901287

12911288
if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
@@ -1425,6 +1422,10 @@ Beautifier.prototype.handle_dot = function(current_token) {
14251422
this.handle_whitespace_and_comments(current_token, true);
14261423
}
14271424

1425+
if (this._flags.last_token.text.match('^[0-9]+$')) {
1426+
this._output.space_before_token = true;
1427+
}
1428+
14281429
if (reserved_array(this._flags.last_token, special_words)) {
14291430
this._output.space_before_token = false;
14301431
} else {

‎package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "js-beautify",
3-
"version": "1.14.2",
3+
"version": "1.14.3",
44
"description": "beautifier.io for node",
55
"main": "js/index.js",
66
"bin": {

‎python/cssbeautifier/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.14.2"
1+
__version__ = "1.14.3"

‎python/cssbeautifier/css/beautifier.py

+48-7
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ def __init__(self, source_text, opts=default_options()):
119119
"@document",
120120
}
121121
self.CONDITIONAL_GROUP_RULE = {"@media", "@supports", "@document"}
122+
self.NON_SEMICOLON_NEWLINE_PROPERTY = ["grid-template-areas", "grid-template"]
122123

123124
def eatString(self, endChars):
124125
result = ""
@@ -222,7 +223,9 @@ def beautify(self):
222223
enteringConditionalGroup = False
223224
insideAtExtend = False
224225
insideAtImport = False
226+
insideScssMap = False
225227
topCharacter = self._ch
228+
insideNonSemiColonValues = False
226229

227230
while True:
228231
whitespace = self._input.read(whitespacePattern)
@@ -268,7 +271,7 @@ def beautify(self):
268271

269272
# Ensures any new lines following the comment are preserved
270273
self.eatWhitespace(True)
271-
elif self._ch == "@":
274+
elif self._ch == "@" or self._ch == "$":
272275
self.preserveSingleSpace(isAfterSpace)
273276

274277
# deal with less propery mixins @{...}
@@ -381,6 +384,12 @@ def beautify(self):
381384
if self._options.brace_style == "expand":
382385
self._output.add_new_line(True)
383386
elif self._ch == ":":
387+
388+
for i in range(0, len(self.NON_SEMICOLON_NEWLINE_PROPERTY)):
389+
if self._input.lookBack(self.NON_SEMICOLON_NEWLINE_PROPERTY[i]):
390+
insideNonSemiColonValues = True
391+
break
392+
384393
if (
385394
(insideRule or enteringConditionalGroup)
386395
and not (self._input.lookBack("&") or self.foundNestedPseudoClass())
@@ -417,6 +426,7 @@ def beautify(self):
417426
self.print_string(self._ch + self.eatString(self._ch))
418427
self.eatWhitespace(True)
419428
elif self._ch == ";":
429+
insideNonSemiColonValues = False
420430
if parenLevel == 0:
421431
if insidePropertyValue:
422432
self.outdent()
@@ -452,22 +462,45 @@ def beautify(self):
452462
parenLevel -= 1
453463
self.outdent()
454464
else:
455-
self.preserveSingleSpace(isAfterSpace)
465+
space_needed = False
466+
if self._input.lookBack("with"):
467+
# look back is not an accurate solution, we need tokens to confirm without whitespaces
468+
space_needed = True
469+
self.preserveSingleSpace(isAfterSpace or space_needed)
456470
self.print_string(self._ch)
457-
self.eatWhitespace()
458-
parenLevel += 1
459-
self.indent()
471+
472+
# handle scss/sass map
473+
if (
474+
insidePropertyValue
475+
and previous_ch == "$"
476+
and self._options.selector_separator_newline
477+
):
478+
self._output.add_new_line()
479+
insideScssMap = True
480+
else:
481+
self.eatWhitespace()
482+
parenLevel += 1
483+
self.indent()
460484
elif self._ch == ")":
461485
if parenLevel:
462486
parenLevel -= 1
463487
self.outdent()
488+
489+
if (
490+
insideScssMap
491+
and self._input.peek() == ";"
492+
and self._options.selector_separator_newline
493+
):
494+
insideScssMap = False
495+
self.outdent()
496+
self._output.add_new_line()
464497
self.print_string(self._ch)
465498
elif self._ch == ",":
466499
self.print_string(self._ch)
467500
self.eatWhitespace(True)
468501
if (
469502
self._options.selector_separator_newline
470-
and not insidePropertyValue
503+
and (not insidePropertyValue or insideScssMap)
471504
and parenLevel == 0
472505
and not insideAtImport
473506
and not insideAtExtend
@@ -507,9 +540,17 @@ def beautify(self):
507540
self.print_string(" ")
508541
self.print_string(self._ch)
509542
else:
510-
self.preserveSingleSpace(isAfterSpace)
543+
preserveAfterSpace = previous_ch == '"' or previous_ch == "'"
544+
self.preserveSingleSpace(preserveAfterSpace or isAfterSpace)
511545
self.print_string(self._ch)
512546

547+
if (
548+
not self._output.just_added_newline()
549+
and self._input.peek() == "\n"
550+
and insideNonSemiColonValues
551+
):
552+
self._output.add_new_line()
553+
513554
sweet_code = self._output.get_code(self._options.eol)
514555

515556
return sweet_code

‎python/jsbeautifier/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.14.2"
1+
__version__ = "1.14.3"

‎python/jsbeautifier/javascript/beautifier.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -1307,12 +1307,6 @@ def handle_operator(self, current_token):
13071307
preserve_statement_flags = not isGeneratorAsterisk
13081308
self.handle_whitespace_and_comments(current_token, preserve_statement_flags)
13091309

1310-
if reserved_array(self._flags.last_token, _special_word_set):
1311-
# return had a special handling in TK_WORD
1312-
self._output.space_before_token = True
1313-
self.print_token(current_token)
1314-
return
1315-
13161310
# hack for actionscript's import .*;
13171311
if current_token.text == "*" and self._flags.last_token.type == TOKEN.DOT:
13181312
self.print_token(current_token)
@@ -1449,7 +1443,15 @@ def handle_operator(self, current_token):
14491443
or current_token.text == "++"
14501444
or current_token.text == "~"
14511445
):
1452-
self.print_newline(preserve_statement_flags=True)
1446+
new_line_needed = (
1447+
reserved_array(self._flags.last_token, _special_word_set)
1448+
and current_token.newlines
1449+
)
1450+
if new_line_needed and (
1451+
self._previous_flags.if_block or self._previous_flags.else_block
1452+
):
1453+
self.restore_mode()
1454+
self.print_newline(new_line_needed, True)
14531455

14541456
if self._flags.last_token.text == ";" and self.is_expression(
14551457
self._flags.mode
@@ -1593,6 +1595,9 @@ def handle_dot(self, current_token):
15931595
else:
15941596
self.handle_whitespace_and_comments(current_token, True)
15951597

1598+
if re.search("^([0-9])+$", self._flags.last_token.text):
1599+
self._flags.whitespace_before = True
1600+
15961601
if reserved_array(self._flags.last_token, _special_word_set):
15971602
self._output.space_before_token = False
15981603
else:

‎test/data/css/tests.js

+105
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,40 @@ exports.test_data = {
13861386
comment: "Multiple filed issues in LESS due to not(:blah)",
13871387
unchanged: '&:first-of-type:not(:last-child) {}'
13881388
},
1389+
{
1390+
comment: "#1236 - maps standard",
1391+
unchanged: [
1392+
'$theme-colors: (',
1393+
' primary: $blue,',
1394+
' secondary: "gray-600"',
1395+
');'
1396+
]
1397+
},
1398+
{
1399+
comment: "#1236 - maps single line",
1400+
input: '$theme-colors:(primary: $blue, secondary: "$gray-600");',
1401+
output: [
1402+
'$theme-colors: (',
1403+
' primary: $blue,',
1404+
' secondary: "$gray-600"',
1405+
');'
1406+
]
1407+
},
1408+
{
1409+
comment: "#1236 - maps with functions",
1410+
input: [
1411+
'$maps:(x: 80px, y: "something", ',
1412+
'z: calc(10 + 10)',
1413+
');'
1414+
],
1415+
output: [
1416+
'$maps: (',
1417+
' x: 80px,',
1418+
' y: "something",',
1419+
' z: calc(10 + 10)',
1420+
');'
1421+
]
1422+
},
13891423
{
13901424
unchanged: [
13911425
'div {',
@@ -1459,13 +1493,84 @@ exports.test_data = {
14591493
' }',
14601494
'}'
14611495
]
1496+
}, {
1497+
comment: "#1236 - SCSS/SASS Maps with selector_separator_newline = false",
1498+
unchanged: '$font-weights: ("regular": 400, "medium": 500, "bold": 700);'
14621499
}, {
14631500
unchanged: [
14641501
'.fa-rotate-270 {',
14651502
' filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);',
14661503
'}'
14671504
]
14681505
}]
1506+
}, {
1507+
name: "Regression tests - with default options",
1508+
description: "",
1509+
tests: [{
1510+
comment: "Issue #1798 - space after strings in preserved",
1511+
unchanged: '@use "variables" as *;'
1512+
}, {
1513+
comment: "Issue #1976 - support the new @forwards syntax",
1514+
input: [
1515+
'@forwards "a" with (',
1516+
' $a: 2',
1517+
');'
1518+
],
1519+
output: '@forwards "a" with ($a: 2);'
1520+
}]
1521+
}, {
1522+
name: "Issue #1817",
1523+
description: "",
1524+
tests: [{
1525+
comment: "ensure that properties that are expected to have multiline values persist new lines",
1526+
unchanged: [
1527+
'.grid {',
1528+
' grid-template:',
1529+
' "top-bar top-bar" 100px',
1530+
' "left-bar center" 100px;',
1531+
'}'
1532+
]
1533+
}, {
1534+
comment: "property values that have string followed by other identifiers should persist spacing",
1535+
input: [
1536+
'.grid {grid-template: "top-bar" 100px;}'
1537+
],
1538+
output: [
1539+
'.grid {',
1540+
' grid-template: "top-bar" 100px;',
1541+
'}'
1542+
]
1543+
}, {
1544+
input: [
1545+
'div {',
1546+
'grid-template-areas: "a"',
1547+
' "b" ',
1548+
' "c";',
1549+
'}'
1550+
],
1551+
output: [
1552+
'div {',
1553+
' grid-template-areas: "a"',
1554+
' "b"',
1555+
' "c";',
1556+
'}'
1557+
]
1558+
}, {
1559+
input: [
1560+
'div {',
1561+
'grid-template: "a a a" 20%',
1562+
' [main-top] "b b b" 1fr',
1563+
' "b b b" auto;',
1564+
'}'
1565+
],
1566+
output: [
1567+
'div {',
1568+
' grid-template: "a a a" 20%',
1569+
' [main-top] "b b b" 1fr',
1570+
' "b b b" auto;',
1571+
'}'
1572+
]
1573+
}]
14691574
}, {
14701575
name: "Issue #645, #1233",
14711576
description: "",

‎test/data/html/tests.js

+114
Original file line numberDiff line numberDiff line change
@@ -3528,6 +3528,120 @@ exports.test_data = {
35283528
'</script>'
35293529
]
35303530
}]
3531+
}, {
3532+
name: "Recognize handlebars with whitespace control",
3533+
description: "Maintains handlebar properties even when whitespace control ~ is at the start of handlebar statements",
3534+
template: "^^^ $$$",
3535+
options: [
3536+
{ name: "indent_handlebars", value: "true" }
3537+
],
3538+
tests: [{
3539+
input: [
3540+
'{{#if true}}<div><div>',
3541+
'{{~#if true ~}}<p>true</p>{{/if}}',
3542+
'</div></div>{{/if}}'
3543+
],
3544+
output: [
3545+
'{{#if true}}',
3546+
' <div>',
3547+
' <div>',
3548+
' {{~#if true ~}}',
3549+
' <p>true</p>',
3550+
' {{/if}}',
3551+
' </div>',
3552+
' </div>',
3553+
'{{/if}}'
3554+
]
3555+
}, {
3556+
input: [
3557+
'{{~#*inline "MyInlinePartial"}}',
3558+
'{{MyIdentifier}}',
3559+
'{{/inline}}'
3560+
],
3561+
output: [
3562+
'{{~#*inline "MyInlinePartial"}}',
3563+
' {{MyIdentifier}}',
3564+
'{{/inline}}'
3565+
]
3566+
}, {
3567+
input: [
3568+
'{{~#> myPartial }}',
3569+
'<span>format correctly</span>',
3570+
'{{/myPartial}}'
3571+
],
3572+
output: [
3573+
'{{~#> myPartial }}',
3574+
' <span>format correctly</span>',
3575+
'{{/myPartial}}'
3576+
]
3577+
}, {
3578+
unchanged: [
3579+
'{{#if callOn}}',
3580+
' {{translate "onText"}}',
3581+
'{{~else if (eq callOn false)}}',
3582+
' {{translate "offText"}}',
3583+
'{{/if}}'
3584+
]
3585+
}, {
3586+
unchanged: [
3587+
'{{~#if callOn}}',
3588+
' {{translate "onText"}}',
3589+
'{{~else if (eq callOn false)}}',
3590+
' {{translate "offText"}}',
3591+
'{{/if}}'
3592+
]
3593+
}]
3594+
}, {
3595+
name: "Corrects Partial Behavior Involving Whitespace",
3596+
description: "Handles partials that do not have a space before the tag",
3597+
template: "^^^ $$$",
3598+
tests: [{
3599+
input: [
3600+
'{{#>row}}',
3601+
' {{#>column}}',
3602+
' <span>content</span>',
3603+
' {{/column}}',
3604+
' {{/row}}'
3605+
],
3606+
output: [
3607+
'{{#>row}}',
3608+
' {{#>column}}',
3609+
' <span>content</span>',
3610+
' {{/column}}',
3611+
'{{/row}}'
3612+
]
3613+
}, {
3614+
input: [
3615+
'{{~#>row}}',
3616+
'{{#>column}}',
3617+
'<p>content</p>',
3618+
'{{/column}}',
3619+
'{{/row}}'
3620+
],
3621+
output: [
3622+
'{{~#>row}}',
3623+
' {{#>column}}',
3624+
' <p>content</p>',
3625+
' {{/column}}',
3626+
'{{/row}}'
3627+
]
3628+
}, {
3629+
unchanged: [
3630+
'{{#>row}}',
3631+
' {{#>column}}',
3632+
' <span>content</span>',
3633+
' {{/column}}',
3634+
'{{/row}}'
3635+
]
3636+
}, {
3637+
unchanged: [
3638+
'{{#> row}}',
3639+
' {{#> column}}',
3640+
' <span>content</span>',
3641+
' {{/column}}',
3642+
'{{/row}}'
3643+
]
3644+
}]
35313645
}, {
35323646
name: "New Test Suite"
35333647
}]

‎test/data/javascript/tests.js

+122
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,25 @@ exports.test_data = {
754754
input: 'a= f[b];',
755755
output: 'a = f[{{s}}b{{s}}];'
756756
},
757+
{
758+
comment: 'Issue #1151 - inside class methods',
759+
input: [
760+
'export default class Test extends Component {',
761+
' render() {',
762+
' someOther();',
763+
' return null;',
764+
' }',
765+
'}'
766+
],
767+
output: [
768+
'export default class Test extends Component {',
769+
' render({{e}}) {',
770+
' someOther({{e}});',
771+
' return null;',
772+
' }',
773+
'}'
774+
]
775+
},
757776
{
758777
input: [
759778
'{',
@@ -3283,6 +3302,24 @@ exports.test_data = {
32833302
' });',
32843303
'var test = 1;'
32853304
]
3305+
}, {
3306+
comment: "Issue #772",
3307+
input: [
3308+
'this.initAttributes([',
3309+
'"name",',
3310+
'["parent", null, "parentName"],',
3311+
'"length",',
3312+
'["id", this.name],',
3313+
']);'
3314+
],
3315+
output: [
3316+
'this.initAttributes([',
3317+
' "name",',
3318+
' ["parent", null, "parentName"],',
3319+
' "length",',
3320+
' ["id", this.name],',
3321+
']);'
3322+
]
32863323
}, {
32873324
comment: "Issue #1663",
32883325
unchanged: [
@@ -3293,6 +3330,81 @@ exports.test_data = {
32933330
'}'
32943331
]
32953332
},
3333+
{
3334+
comment: "#1095 - Return without semicolon followed by prefix on a new line",
3335+
input: [
3336+
'function x(){',
3337+
'return',
3338+
'++a',
3339+
'}',
3340+
'',
3341+
'while(true) {',
3342+
'return',
3343+
'--b',
3344+
'}'
3345+
],
3346+
output: [
3347+
'function x() {',
3348+
' return',
3349+
' ++a',
3350+
'}',
3351+
'',
3352+
'while (true) {',
3353+
' return',
3354+
' --b',
3355+
'}'
3356+
]
3357+
},
3358+
{
3359+
comment: "#1095",
3360+
input: [
3361+
'function test(){',
3362+
'if(x) return',
3363+
'++x',
3364+
'var y= 1;',
3365+
'}',
3366+
'function t1(){',
3367+
'if(cc) return;',
3368+
'else return',
3369+
'--cc',
3370+
'}'
3371+
],
3372+
output: [
3373+
'function test() {',
3374+
' if (x) return',
3375+
' ++x',
3376+
' var y = 1;',
3377+
'}',
3378+
'',
3379+
'function t1() {',
3380+
' if (cc) return;',
3381+
' else return',
3382+
' --cc',
3383+
'}'
3384+
]
3385+
},
3386+
{
3387+
comment: "#1095 - Return with semicolon followed by a prefix on a new line",
3388+
input: [
3389+
'function x(){',
3390+
'return; ++a',
3391+
'}',
3392+
'',
3393+
'while(true){return; --b',
3394+
'}'
3395+
],
3396+
output: [
3397+
'function x() {',
3398+
' return;',
3399+
' ++a',
3400+
'}',
3401+
'',
3402+
'while (true) {',
3403+
' return;',
3404+
' --b',
3405+
'}'
3406+
]
3407+
},
32963408
{
32973409
comment: "#1838 - handle class and interface word as an object property",
32983410
unchanged: [
@@ -4691,6 +4803,16 @@ exports.test_data = {
46914803
' }',
46924804
'}'
46934805
]
4806+
},
4807+
{
4808+
comment: 'Issue #1950: Do not remove whitespace after number - test scenario: number before a dot',
4809+
input: '1000000000000001000 .toFixed(0)!==1000000000000001024',
4810+
output: '1000000000000001000 .toFixed(0) !== 1000000000000001024'
4811+
},
4812+
{
4813+
comment: 'Issue #1950: Do not remove whitespace after number - test scenario: variable ends with a number before a dot',
4814+
input: 'a.b21 . performAction()',
4815+
output: 'a.b21.performAction()'
46944816
}
46954817
]
46964818
}, {

‎tools/generate-changelog.sh

+18-17
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ main()
1111
cd $SCRIPT_DIR/..
1212

1313
if [ "$#" -ne 2 ]; then
14-
echo "Usage: ./generate-changelog.sh user/repo api_key"
14+
echo "Usage: ./generate-changelog.sh user/repo <github token>"
1515
exit 1
1616
fi
1717

@@ -31,22 +31,23 @@ main()
3131
IFS=$'\n'
3232
echo "# Changelog" > CHANGELOG.md
3333

34-
for m in $(curl -s "https://api.github.com/repos/$1/milestones?access_token=$2&per_page=100&state=closed" | "$JQ" -c '.[] | [.title, .number, .description]' | "$GSORT" -r -V); do
35-
mid=$(echo $m | sed 's/\[".*",\(.*\),".*"\]/\1/')
36-
title=$(echo $m | sed 's/\["\(.*\)",.*,".*"\]/\1/')
37-
38-
echo "Processing milestone: $title..."
39-
echo $m | sed 's/\["\(.*\)",.*\]/## \1/' >> CHANGELOG.md
40-
echo "" >> CHANGELOG.md
41-
echo '### Description' >> CHANGELOG.md
42-
echo $m | sed 's/\[".*",.*,"\(.*\)"\]/\1/' | sed -e 's/\\"/"/g' | sed -e 's/\\r\\n/\\n/g' | sed -e 's/\\n/\'$'\n/g' >> CHANGELOG.md
43-
echo "" >> CHANGELOG.md
44-
echo '### Closed Issues' >> CHANGELOG.md
45-
for i in $(curl -s "https://api.github.com/repos/$1/issues?access_token=$2&per_page=100&milestone=$mid&state=closed" | "$JQ" -c '.[] | [.html_url, .number, .title]'); do
46-
echo $i | sed 's/\["\(.*\)",\(.*\),\"\(.*\)\"\]/* \3 ([#\2](\1))/' | sed 's/\\"/"/g' >> CHANGELOG.md
47-
done
48-
echo "" >> CHANGELOG.md
49-
echo "" >> CHANGELOG.md
34+
for m in $(
35+
curl -s -H "Authorization: token $2" "https://api.github.com/repos/$1/milestones?state=closed&per_page=100" \
36+
| jq -c '.[] | [.title, .number]' \
37+
| sed 's/-/\!/' | sort -rV | sed 's/\!/-/' # sed trick to put -alpha, -beta, etc earlier than GA release
38+
); do
39+
40+
echo "Processing milestone: $title..."
41+
echo $m | sed 's/\["\(.*\)",.*\]/\n## \1/' >> CHANGELOG.md
42+
mid=$(echo $m | sed 's/.*,\(.*\)]/\1/')
43+
44+
for i in $(curl -s -H "Authorization: token $2" "https://api.github.com/repos/$1/issues?milestone=$mid&state=closed" | jq -r '.[] | [.html_url, .number, .title, (.labels[] | select(.name == "breaking") | .name)] | @tsv'); do
45+
if [ "$(echo "$i" | cut -f 4)" = "breaking" ]; then
46+
echo "* **$(echo "$i" | cut -f 3 | sed 's/_/\\_/g') ([#$(echo "$i" | cut -f 2)]($(echo "$i" | cut -f 1)))**" >> CHANGELOG.md
47+
else
48+
echo "* $(echo "$i" | cut -f 3 | sed 's/_/\\_/g') ([#$(echo "$i" | cut -f 2)]($(echo "$i" | cut -f 1)))" >> CHANGELOG.md
49+
fi
50+
done
5051
done
5152

5253
git commit -am "Update Changelog"

‎tools/release-all.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ update_versions()
8282
git clean -xfd || exit 1
8383

8484
# Disabled due to build break
85-
# $SCRIPT_DIR/generate-changelog.sh beautify-web/js-beautify $GITHUB_TOKEN || exit 1
85+
$SCRIPT_DIR/generate-changelog.sh beautify-web/js-beautify $GITHUB_TOKEN || exit 1
8686

8787
$SCRIPT_DIR/npm version --no-git-tag-version $NEW_VERSION || exit 1
8888

‎web/common-style.css

+104-60
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
body {
22
background: #eee;
33
color: #333;
4-
}
5-
6-
img {
7-
border: 0;
4+
height: 95vh;
5+
font: 13px/1.231 arial, sans-serif;
86
}
97

108
a.self {
@@ -14,110 +12,156 @@ a.self {
1412
border-bottom: 1px solid #aaa
1513
}
1614

17-
h1 {
15+
h1.logo {
1816
display: flex;
19-
margin-bottom: 0;
2017
line-height: 1em;
18+
margin: 0;
2119
}
2220

2321
h1 img {
2422
font-family: montserrat, nexa, gotham, sans-serif;
2523
font-weight: 600;
26-
margin-left: 40px;
2724
}
2825

2926
p, select, label, .blurb, a.turn-off-codemirror {
30-
font: 13px/1.231 arial, sans-serif;
3127
font-size: small;
3228
}
3329

34-
a.turn-off-codemirror {
35-
margin-left: 25px;
30+
.sub-title {
31+
margin-bottom: 30px;
3632
}
3733

38-
button.submit {
39-
cursor: pointer;
40-
margin: 0;
34+
.title {
35+
margin-left: 40px;
4136
}
4237

43-
button.submit em {
44-
font-size: 11px;
45-
font-style: normal;
46-
color: #999;
38+
textarea#source {
39+
width: 100%;
40+
height: 100%;
4741
}
4842

49-
button.control {
50-
cursor: pointer;
51-
margin: 0;
43+
a.turn-off-codemirror {
44+
margin-left: 25px;
5245
}
5346

54-
label {
47+
input[type="checkbox"], select, button {
5548
cursor: pointer;
5649
}
5750

58-
select {
59-
width: 220px;
60-
}
61-
62-
table#options td {
63-
vertical-align: top;
64-
padding-left: 10px;
65-
}
66-
67-
.col-6 {
68-
width: 50%;
69-
float: left;
70-
}
71-
7251
#version-number {
7352
align-self: flex-end;
7453
font-family: arial, sans-serif;
7554
font-size: .5em;
7655
margin-left: 10px;
7756
}
7857

79-
.uses li {
80-
padding-top: 3px;
81-
line-height: 150%;
82-
}
83-
84-
.uses li.sep {
85-
margin-top: 8px;
86-
}
87-
8858
#testresults {
8959
display: none;
9060
font-family: monaco, consolas, "lucida console", "courier new", monospace;
9161
}
9262

9363
.CodeMirror {
9464
border: 1px solid #ccc;
95-
height: 450px;
65+
height: 100%;
9666
font-size: 90%;
9767
margin-bottom: 6px;
9868
background: white;
9969
}
10070

101-
p {
102-
margin-left: 40px;
103-
margin-right: 40px;
71+
.hide {
72+
display: none;
10473
}
10574

106-
a {
107-
white-space: nowrap;
108-
color: #36d;
75+
.container {
76+
display: grid;
77+
grid-template-columns: 1.6fr 0.9fr;
78+
grid-template-rows: 0.2fr 1.8fr;
79+
gap: 0 14px;
80+
grid-auto-flow: row;
81+
grid-template-areas:
82+
"title options"
83+
"editor options";
10984
}
11085

111-
.contributor-sep {
112-
clear: left;
113-
border-top: 1px solid #ccc;
114-
padding-top: 8px;
86+
.title {
87+
grid-area: title;
11588
}
11689

117-
h2 {
118-
margin-top: 32px;
119-
margin-left: 40px;
120-
margin-bottom: 0;
90+
.editor {
91+
grid-area: editor;
92+
}
93+
94+
.options {
95+
grid-area: options;
96+
}
97+
98+
select, .buttons-box button {
99+
background-color: white;
100+
border: 1px solid #ccc;
101+
border-radius: 4px;
102+
line-height: 1.5em;
103+
padding: 0.5em;
104+
margin: 0 0 5px;
105+
-webkit-box-sizing: border-box;
106+
-moz-box-sizing: border-box;
107+
box-sizing: border-box;
108+
}
109+
110+
select {
111+
display: block;
112+
}
113+
114+
.options-checkboxes, .options-select {
115+
display: inline-table;
116+
}
117+
118+
#language {
121119
font-size: 20px;
122-
font-weight: normal;
120+
width: 100%;
121+
padding-left: 16px;
122+
font-weight: 800;
123+
margin-bottom: 10px;
124+
}
125+
126+
.buttons-box {
127+
margin-top: 20px;
128+
}
129+
130+
.buttons-box .submit {
131+
margin-top: 10px;
132+
margin-bottom: 10px;
133+
display: block;
134+
font-size: 1.5em;
135+
width: 100%;
136+
background-color: #7cffcb;
137+
background-image: linear-gradient(315deg, #7cffcb 0%, #74f2ce 74%);
138+
}
139+
140+
.buttons-box .control {
141+
background-color: #2e3138;
142+
color: white;
143+
display: inline-flex;
144+
}
145+
146+
@media only screen and (max-width: 600px) {
147+
.container {
148+
grid-template-areas:
149+
"title"
150+
"editor"
151+
"options";
152+
grid-template-rows: 0.1fr 1.8fr 0.1fr;
153+
width: 100vw;
154+
}
155+
156+
.title {
157+
margin-left: 10px;
158+
}
159+
160+
.editor, .title, .options {
161+
width: 95vw;
162+
}
163+
164+
.CodeMirror {
165+
height: 50vh;
166+
}
123167
}

0 commit comments

Comments
 (0)
Please sign in to comment.