Skip to content

Commit 3fb3f02

Browse files
author
GitHub Action
committedJun 20, 2022
Merge remote-tracking branch 'origin/staging/main' into staging/release
2 parents ab9d7c3 + 3256a5a commit 3fb3f02

22 files changed

+1309
-337
lines changed
 

‎.DS_Store

8 KB
Binary file not shown.

‎CHANGELOG.md

+474
Large diffs are not rendered by default.

‎Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ $(BUILD_DIR)/virtualenv: | $(BUILD_DIR)
144144
virtualenv --version || pip install virtualenv
145145
virtualenv build/python-dev
146146
virtualenv build/python-rel
147-
$(SCRIPT_DIR)/python-dev pip install pip --upgrade
148-
$(SCRIPT_DIR)/python-rel pip install pip --upgrade
147+
$(SCRIPT_DIR)/python-dev python -m pip install --upgrade pip || exit 0
148+
$(SCRIPT_DIR)/python-rel python -m pip install --upgrade pip || exit 0
149149
$(SCRIPT_DIR)/python-dev3 pip install black
150150
@touch $(BUILD_DIR)/virtualenv
151151

‎README.md

+7-11
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,13 @@ 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.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>
61+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.4/beautify.js"></script>
62+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.4/beautify-css.js"></script>
63+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.4/beautify-html.js"></script>
6464

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>
68-
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>
65+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.4/beautify.min.js"></script>
66+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.4/beautify-css.min.js"></script>
67+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.4/beautify-html.min.js"></script>
7268
```
7369

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

‎index.html

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

‎js/src/css/beautifier.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ function Beautifier(source_text, options) {
6868
"@document": true
6969
};
7070
this.NON_SEMICOLON_NEWLINE_PROPERTY = [
71+
"grid-template-areas",
7172
"grid-template"
7273
];
7374

@@ -399,7 +400,8 @@ Beautifier.prototype.beautify = function() {
399400
}
400401
}
401402
} else if (this._ch === '"' || this._ch === '\'') {
402-
this.preserveSingleSpace(isAfterSpace);
403+
var preserveQuoteSpace = previous_ch === '"' || previous_ch === '\'';
404+
this.preserveSingleSpace(preserveQuoteSpace || isAfterSpace);
403405
this.print_string(this._ch + this.eatString(this._ch));
404406
this.eatWhitespace(true);
405407
} else if (this._ch === ';') {
@@ -443,7 +445,12 @@ Beautifier.prototype.beautify = function() {
443445
}
444446
}
445447
} else {
446-
this.preserveSingleSpace(isAfterSpace);
448+
var space_needed = false;
449+
if (this._input.lookBack("with")) {
450+
// look back is not an accurate solution, we need tokens to confirm without whitespaces
451+
space_needed = true;
452+
}
453+
this.preserveSingleSpace(isAfterSpace || space_needed);
447454
this.print_string(this._ch);
448455

449456
// handle scss/sass map
@@ -501,7 +508,7 @@ Beautifier.prototype.beautify = function() {
501508
this._ch = '';
502509
}
503510
} else if (this._ch === '!' && !this._input.lookBack("\\")) { // !important
504-
this.print_string(' ');
511+
this._output.space_before_token = true;
505512
this.print_string(this._ch);
506513
} else {
507514
var preserveAfterSpace = previous_ch === '"' || previous_ch === '\'';

‎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

+18-8
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ Beautifier.prototype.create_flags = function(flags_base, mode) {
185185
inline_frame: false,
186186
if_block: false,
187187
else_block: false,
188+
class_start_block: false, // class A { INSIDE HERE } or class B extends C { INSIDE HERE }
188189
do_block: false,
189190
do_while: false,
190191
import_block: false,
@@ -597,6 +598,8 @@ Beautifier.prototype.handle_start_expr = function(current_token) {
597598
(peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) {
598599
this._output.space_before_token = true;
599600
}
601+
} else if (this._flags.parent && this._flags.parent.class_start_block) {
602+
this._output.space_before_token = true;
600603
}
601604
}
602605
} else {
@@ -711,6 +714,12 @@ Beautifier.prototype.handle_start_block = function(current_token) {
711714
this.set_mode(MODE.BlockStatement);
712715
}
713716

717+
if (this._flags.last_token) {
718+
if (reserved_array(this._flags.last_token.previous, ['class', 'extends'])) {
719+
this._flags.class_start_block = true;
720+
}
721+
}
722+
714723
var empty_braces = !next_token.comments_before && next_token.text === '}';
715724
var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' &&
716725
this._flags.last_token.type === TOKEN.END_EXPR;
@@ -1151,13 +1160,6 @@ Beautifier.prototype.handle_operator = function(current_token) {
11511160
this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
11521161
}
11531162

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-
11611163
// hack for actionscript's import .*;
11621164
if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) {
11631165
this.print_token(current_token);
@@ -1285,7 +1287,11 @@ Beautifier.prototype.handle_operator = function(current_token) {
12851287
// http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
12861288
// if there is a newline between -- or ++ and anything else we should preserve it.
12871289
if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) {
1288-
this.print_newline(false, true);
1290+
var new_line_needed = reserved_array(this._flags.last_token, special_words) && current_token.newlines;
1291+
if (new_line_needed && (this._previous_flags.if_block || this._previous_flags.else_block)) {
1292+
this.restore_mode();
1293+
}
1294+
this.print_newline(new_line_needed, true);
12891295
}
12901296

12911297
if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
@@ -1425,6 +1431,10 @@ Beautifier.prototype.handle_dot = function(current_token) {
14251431
this.handle_whitespace_and_comments(current_token, true);
14261432
}
14271433

1434+
if (this._flags.last_token.text.match('^[0-9]+$')) {
1435+
this._output.space_before_token = true;
1436+
}
1437+
14281438
if (reserved_array(this._flags.last_token, special_words)) {
14291439
this._output.space_before_token = false;
14301440
} else {

‎js/src/javascript/tokenizer.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ var punct_pattern = new RegExp(punct);
9595

9696
// words which should always start on new line.
9797
var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
98-
var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']);
98+
var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as', 'class', 'extends']);
9999
var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');
100100

101101
// var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
@@ -186,7 +186,8 @@ Tokenizer.prototype._read_word = function(previous_token) {
186186
if (!(previous_token.type === TOKEN.DOT ||
187187
(previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) &&
188188
reserved_word_pattern.test(resulting_string)) {
189-
if (resulting_string === 'in' || resulting_string === 'of') { // hack for 'in' and 'of' operators
189+
if ((resulting_string === 'in' || resulting_string === 'of') &&
190+
(previous_token.type === TOKEN.WORD || previous_token.type === TOKEN.STRING)) { // hack for 'in' and 'of' operators
190191
return this._create_token(TOKEN.OPERATOR, resulting_string);
191192
}
192193
return this._create_token(TOKEN.RESERVED, resulting_string);

‎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.3",
3+
"version": "1.14.4",
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.3"
1+
__version__ = "1.14.4"

‎python/cssbeautifier/css/beautifier.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -119,7 +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"]
122+
self.NON_SEMICOLON_NEWLINE_PROPERTY = ["grid-template-areas", "grid-template"]
123123

124124
def eatString(self, endChars):
125125
result = ""
@@ -422,7 +422,8 @@ def beautify(self):
422422
# pseudo-element
423423
self.print_string(":")
424424
elif self._ch == '"' or self._ch == "'":
425-
self.preserveSingleSpace(isAfterSpace)
425+
preserveQuoteSpace = previous_ch == '"' or previous_ch == "'"
426+
self.preserveSingleSpace(preserveQuoteSpace or isAfterSpace)
426427
self.print_string(self._ch + self.eatString(self._ch))
427428
self.eatWhitespace(True)
428429
elif self._ch == ";":
@@ -462,7 +463,11 @@ def beautify(self):
462463
parenLevel -= 1
463464
self.outdent()
464465
else:
465-
self.preserveSingleSpace(isAfterSpace)
466+
space_needed = False
467+
if self._input.lookBack("with"):
468+
# look back is not an accurate solution, we need tokens to confirm without whitespaces
469+
space_needed = True
470+
self.preserveSingleSpace(isAfterSpace or space_needed)
466471
self.print_string(self._ch)
467472

468473
# handle scss/sass map
@@ -533,7 +538,7 @@ def beautify(self):
533538
self._ch = ""
534539
elif self._ch == "!" and not (self._input.lookBack("\\")):
535540
# !important
536-
self.print_string(" ")
541+
self._output.space_before_token = True
537542
self.print_string(self._ch)
538543
else:
539544
preserveAfterSpace = previous_ch == '"' or previous_ch == "'"

‎python/jsbeautifier/__version__.py

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

‎python/jsbeautifier/javascript/beautifier.py

+19-7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def __init__(self, mode):
4848
self.inline_frame = False
4949
self.if_block = False
5050
self.else_block = False
51+
self.class_start_block = False
5152
self.do_block = False
5253
self.do_while = False
5354
self.import_block = False
@@ -609,6 +610,8 @@ def handle_start_expr(self, current_token):
609610
)
610611
):
611612
self._output.space_before_token = True
613+
elif self._flags.parent and self._flags.parent.class_start_block:
614+
self._output.space_before_token = True
612615
else:
613616
# Support preserving wrapped arrow function expressions
614617
# a.b('c',
@@ -759,6 +762,10 @@ def handle_start_block(self, current_token):
759762
else:
760763
self.set_mode(MODE.BlockStatement)
761764

765+
if self._flags.last_token:
766+
if reserved_array(self._flags.last_token.previous, ["class", "extends"]):
767+
self._flags.class_start_block = True
768+
762769
empty_braces = (
763770
(next_token is not None)
764771
and next_token.comments_before is None
@@ -1307,12 +1314,6 @@ def handle_operator(self, current_token):
13071314
preserve_statement_flags = not isGeneratorAsterisk
13081315
self.handle_whitespace_and_comments(current_token, preserve_statement_flags)
13091316

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-
13161317
# hack for actionscript's import .*;
13171318
if current_token.text == "*" and self._flags.last_token.type == TOKEN.DOT:
13181319
self.print_token(current_token)
@@ -1449,7 +1450,15 @@ def handle_operator(self, current_token):
14491450
or current_token.text == "++"
14501451
or current_token.text == "~"
14511452
):
1452-
self.print_newline(preserve_statement_flags=True)
1453+
new_line_needed = (
1454+
reserved_array(self._flags.last_token, _special_word_set)
1455+
and current_token.newlines
1456+
)
1457+
if new_line_needed and (
1458+
self._previous_flags.if_block or self._previous_flags.else_block
1459+
):
1460+
self.restore_mode()
1461+
self.print_newline(new_line_needed, True)
14531462

14541463
if self._flags.last_token.text == ";" and self.is_expression(
14551464
self._flags.mode
@@ -1593,6 +1602,9 @@ def handle_dot(self, current_token):
15931602
else:
15941603
self.handle_whitespace_and_comments(current_token, True)
15951604

1605+
if re.search("^([0-9])+$", self._flags.last_token.text):
1606+
self._flags.whitespace_before = True
1607+
15961608
if reserved_array(self._flags.last_token, _special_word_set):
15971609
self._output.space_before_token = False
15981610
else:

‎python/jsbeautifier/javascript/tokenizer.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ def __init__(self):
113113
"await",
114114
"from",
115115
"as",
116+
"class",
117+
"extends",
116118
]
117119
)
118120

@@ -267,7 +269,10 @@ def _read_word(self, previous_token):
267269
and (previous_token.text == "set" or previous_token.text == "get")
268270
)
269271
) and reserved_word_pattern.match(resulting_string):
270-
if resulting_string == "in" or resulting_string == "of":
272+
if (resulting_string == "in" or resulting_string == "of") and (
273+
previous_token.type == TOKEN.WORD
274+
or previous_token.type == TOKEN.STRING
275+
):
271276
# in and of are operators, need to hack
272277
return self._create_token(TOKEN.OPERATOR, resulting_string)
273278

‎test/data/css/tests.js

+50-1
Original file line numberDiff line numberDiff line change
@@ -1502,12 +1502,46 @@ exports.test_data = {
15021502
' filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);',
15031503
'}'
15041504
]
1505+
}, {
1506+
comment: "#2056 - Extra space before !important added",
1507+
unchanged: [
1508+
'.x {',
1509+
' $d: a !default;',
1510+
'}'
1511+
]
1512+
}, {
1513+
unchanged: [
1514+
'.x {',
1515+
' $d: a !default;',
1516+
' @if $x !=0 {',
1517+
' color: $var !important;',
1518+
' }',
1519+
'}'
1520+
]
1521+
}, {
1522+
comment: "#2051 - css format removes space after quoted value",
1523+
unchanged: [
1524+
'q {',
1525+
' quotes: \\\'"\\\' \\\'"\\\' "\\\'" "\\\'";',
1526+
' quotes: "some" \\\'thing\\\' "different";',
1527+
' quotes: \\\'some\\\' "thing" \\\'different\\\';',
1528+
'}'
1529+
]
15051530
}]
15061531
}, {
1507-
name: "Issue #1798 - space after strings in preserved",
1532+
name: "Regression tests - with default options",
15081533
description: "",
15091534
tests: [{
1535+
comment: "Issue #1798 - space after strings in preserved",
15101536
unchanged: '@use "variables" as *;'
1537+
}, {
1538+
comment: "Issue #1976 - support the new @forwards syntax",
1539+
input: [
1540+
'@forwards "a" with (',
1541+
' $a: 2',
1542+
');'
1543+
],
1544+
output: '@forwards "a" with ($a: 2);'
15111545
}]
15121546
}, {
15131547
name: "Issue #1817",
@@ -1531,6 +1565,21 @@ exports.test_data = {
15311565
' grid-template: "top-bar" 100px;',
15321566
'}'
15331567
]
1568+
}, {
1569+
input: [
1570+
'div {',
1571+
'grid-template-areas: "a"',
1572+
' "b" ',
1573+
' "c";',
1574+
'}'
1575+
],
1576+
output: [
1577+
'div {',
1578+
' grid-template-areas: "a"',
1579+
' "b"',
1580+
' "c";',
1581+
'}'
1582+
]
15341583
}, {
15351584
input: [
15361585
'div {',

‎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

+251
Original file line numberDiff line numberDiff line change
@@ -3191,6 +3191,71 @@ exports.test_data = {
31913191
input: 'switch(x){case -1:break;case !y:{break;}}',
31923192
output: 'switch (x) {\n{{c}}case -1:\n{{c}} break;\n{{c}}case !y: {\n{{c}} break;\n{{c}}\}\n}'
31933193
},
3194+
{
3195+
comment: "Issue #1622 - basic class with function definitions",
3196+
input: [
3197+
'class blah {',
3198+
' constructor() {',
3199+
' this.doStuff()',
3200+
' }',
3201+
' doStuff() {',
3202+
' console.log("stuff")',
3203+
' }',
3204+
'}'
3205+
],
3206+
output: [
3207+
'class blah {',
3208+
' constructor{{nf}}() {',
3209+
' this.doStuff()',
3210+
' }',
3211+
' doStuff{{nf}}() {',
3212+
' console.log("stuff")',
3213+
' }',
3214+
'}'
3215+
]
3216+
},
3217+
{
3218+
comment: "Issue #1622 - class with extends and function definitions",
3219+
input: [
3220+
'class blah extends something {',
3221+
' constructor() {',
3222+
' this.zz = 2 + 2;',
3223+
' }',
3224+
' someOtherFunction() {',
3225+
'this.y = 1;',
3226+
' }',
3227+
'}'
3228+
],
3229+
output: [
3230+
'class blah extends something {',
3231+
' constructor{{nf}}() {',
3232+
' this.zz = 2 + 2;',
3233+
' }',
3234+
' someOtherFunction{{nf}}() {',
3235+
' this.y = 1;',
3236+
' }',
3237+
'}'
3238+
]
3239+
},
3240+
{
3241+
comment: "Issue #1622 - class/extends as a property",
3242+
input: [
3243+
'var a.class = {',
3244+
' ...abc(),',
3245+
'}',
3246+
'b.extends({',
3247+
' bb.s(),',
3248+
'})'
3249+
],
3250+
output: [
3251+
'var a.class = {',
3252+
' ...abc(),',
3253+
'}',
3254+
'b.extends({',
3255+
' bb.s(),',
3256+
'})'
3257+
]
3258+
},
31943259
{
31953260
comment: 'typical greasemonkey start',
31963261
fragment: true,
@@ -3302,6 +3367,24 @@ exports.test_data = {
33023367
' });',
33033368
'var test = 1;'
33043369
]
3370+
}, {
3371+
comment: "Issue #772",
3372+
input: [
3373+
'this.initAttributes([',
3374+
'"name",',
3375+
'["parent", null, "parentName"],',
3376+
'"length",',
3377+
'["id", this.name],',
3378+
']);'
3379+
],
3380+
output: [
3381+
'this.initAttributes([',
3382+
' "name",',
3383+
' ["parent", null, "parentName"],',
3384+
' "length",',
3385+
' ["id", this.name],',
3386+
']);'
3387+
]
33053388
}, {
33063389
comment: "Issue #1663",
33073390
unchanged: [
@@ -3312,6 +3395,81 @@ exports.test_data = {
33123395
'}'
33133396
]
33143397
},
3398+
{
3399+
comment: "#1095 - Return without semicolon followed by prefix on a new line",
3400+
input: [
3401+
'function x(){',
3402+
'return',
3403+
'++a',
3404+
'}',
3405+
'',
3406+
'while(true) {',
3407+
'return',
3408+
'--b',
3409+
'}'
3410+
],
3411+
output: [
3412+
'function x() {',
3413+
' return',
3414+
' ++a',
3415+
'}',
3416+
'',
3417+
'while (true) {',
3418+
' return',
3419+
' --b',
3420+
'}'
3421+
]
3422+
},
3423+
{
3424+
comment: "#1095",
3425+
input: [
3426+
'function test(){',
3427+
'if(x) return',
3428+
'++x',
3429+
'var y= 1;',
3430+
'}',
3431+
'function t1(){',
3432+
'if(cc) return;',
3433+
'else return',
3434+
'--cc',
3435+
'}'
3436+
],
3437+
output: [
3438+
'function test() {',
3439+
' if (x) return',
3440+
' ++x',
3441+
' var y = 1;',
3442+
'}',
3443+
'',
3444+
'function t1() {',
3445+
' if (cc) return;',
3446+
' else return',
3447+
' --cc',
3448+
'}'
3449+
]
3450+
},
3451+
{
3452+
comment: "#1095 - Return with semicolon followed by a prefix on a new line",
3453+
input: [
3454+
'function x(){',
3455+
'return; ++a',
3456+
'}',
3457+
'',
3458+
'while(true){return; --b',
3459+
'}'
3460+
],
3461+
output: [
3462+
'function x() {',
3463+
' return;',
3464+
' ++a',
3465+
'}',
3466+
'',
3467+
'while (true) {',
3468+
' return;',
3469+
' --b',
3470+
'}'
3471+
]
3472+
},
33153473
{
33163474
comment: "#1838 - handle class and interface word as an object property",
33173475
unchanged: [
@@ -4627,6 +4785,99 @@ exports.test_data = {
46274785
' }',
46284786
')'
46294787
]
4788+
},
4789+
{
4790+
comment: "Issue ##1846 - in keyword in class method causes indentation problem",
4791+
input: [
4792+
'class {',
4793+
' get a() {',
4794+
'\n',
4795+
' }',
4796+
'\n',
4797+
' in() {',
4798+
'\n',
4799+
' }',
4800+
'\n',
4801+
' b() {',
4802+
'\n',
4803+
' }',
4804+
'}'
4805+
],
4806+
output: [
4807+
'class {',
4808+
' get a() {',
4809+
'\n',
4810+
' }',
4811+
'\n',
4812+
' in() {',
4813+
'\n',
4814+
' }',
4815+
'\n',
4816+
' b() {',
4817+
'\n',
4818+
' }',
4819+
'}'
4820+
]
4821+
},
4822+
{
4823+
comment: "Related to Issue ##1846 - Do not indent 'in' keyword if not a class method",
4824+
input: [
4825+
'function test() {',
4826+
'for x in nums {}',
4827+
'"make" in car',
4828+
'3 in number;',
4829+
'}'
4830+
],
4831+
output: [
4832+
'function test() {',
4833+
' for x in nums {}',
4834+
' "make" in car',
4835+
' 3 in number;',
4836+
'}'
4837+
]
4838+
},
4839+
{
4840+
comment: "Related to Issue ##1846 - of keyword in class method causes indentation problem",
4841+
input: [
4842+
'class {',
4843+
' get a() {',
4844+
'\n',
4845+
' }',
4846+
'\n',
4847+
' of() {',
4848+
'\n',
4849+
' }',
4850+
'\n',
4851+
' b() {',
4852+
'\n',
4853+
' }',
4854+
'}'
4855+
],
4856+
output: [
4857+
'class {',
4858+
' get a() {',
4859+
'\n',
4860+
' }',
4861+
'\n',
4862+
' of() {',
4863+
'\n',
4864+
' }',
4865+
'\n',
4866+
' b() {',
4867+
'\n',
4868+
' }',
4869+
'}'
4870+
]
4871+
},
4872+
{
4873+
comment: 'Issue #1950: Do not remove whitespace after number - test scenario: number before a dot',
4874+
input: '1000000000000001000 .toFixed(0)!==1000000000000001024',
4875+
output: '1000000000000001000 .toFixed(0) !== 1000000000000001024'
4876+
},
4877+
{
4878+
comment: 'Issue #1950: Do not remove whitespace after number - test scenario: variable ends with a number before a dot',
4879+
input: 'a.b21 . performAction()',
4880+
output: 'a.b21.performAction()'
46304881
}
46314882
]
46324883
}, {

‎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-2
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,10 @@ 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

89-
sedi -E 's@(cdn.rawgit.+beautify/v)[^/]+@\1'$NEW_VERSION'@' README.md
9089
sedi -E 's@(cdnjs.cloudflare.+beautify/)[^/]+@\1'$NEW_VERSION'@' README.md
9190
sedi -E 's/\((README\.md:.js-beautify@).+\)/(\1'$NEW_VERSION')/' README.md
9291

‎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.