js-beautify 1.14.2 → 1.14.5
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/README.md +14 -18
- package/js/lib/beautifier.js +104 -31
- package/js/lib/beautifier.min.js +1 -1
- package/js/lib/beautify-css.js +59 -10
- package/js/lib/beautify-html.js +18 -5
- package/js/lib/beautify.js +27 -16
- package/js/src/css/beautifier.js +59 -10
- package/js/src/html/beautifier.js +18 -5
- package/js/src/javascript/beautifier.js +22 -12
- package/js/src/javascript/tokenizer.js +5 -4
- package/package.json +15 -15
package/js/lib/beautify-css.js
CHANGED
|
@@ -1090,6 +1090,10 @@ function Beautifier(source_text, options) {
|
|
|
1090
1090
|
"@supports": true,
|
|
1091
1091
|
"@document": true
|
|
1092
1092
|
};
|
|
1093
|
+
this.NON_SEMICOLON_NEWLINE_PROPERTY = [
|
|
1094
|
+
"grid-template-areas",
|
|
1095
|
+
"grid-template"
|
|
1096
|
+
];
|
|
1093
1097
|
|
|
1094
1098
|
}
|
|
1095
1099
|
|
|
@@ -1214,7 +1218,9 @@ Beautifier.prototype.beautify = function() {
|
|
|
1214
1218
|
var enteringConditionalGroup = false;
|
|
1215
1219
|
var insideAtExtend = false;
|
|
1216
1220
|
var insideAtImport = false;
|
|
1221
|
+
var insideScssMap = false;
|
|
1217
1222
|
var topCharacter = this._ch;
|
|
1223
|
+
var insideNonSemiColonValues = false;
|
|
1218
1224
|
var whitespace;
|
|
1219
1225
|
var isAfterSpace;
|
|
1220
1226
|
var previous_ch;
|
|
@@ -1266,7 +1272,7 @@ Beautifier.prototype.beautify = function() {
|
|
|
1266
1272
|
|
|
1267
1273
|
// Ensures any new lines following the comment are preserved
|
|
1268
1274
|
this.eatWhitespace(true);
|
|
1269
|
-
} else if (this._ch === '@') {
|
|
1275
|
+
} else if (this._ch === '@' || this._ch === '$') {
|
|
1270
1276
|
this.preserveSingleSpace(isAfterSpace);
|
|
1271
1277
|
|
|
1272
1278
|
// deal with less propery mixins @{...}
|
|
@@ -1337,7 +1343,12 @@ Beautifier.prototype.beautify = function() {
|
|
|
1337
1343
|
this.indent();
|
|
1338
1344
|
this._output.set_indent(this._indentLevel);
|
|
1339
1345
|
} else {
|
|
1340
|
-
|
|
1346
|
+
// inside mixin and first param is object
|
|
1347
|
+
if (previous_ch === '(') {
|
|
1348
|
+
this._output.space_before_token = false;
|
|
1349
|
+
} else if (previous_ch !== ',') {
|
|
1350
|
+
this.indent();
|
|
1351
|
+
}
|
|
1341
1352
|
this.print_string(this._ch);
|
|
1342
1353
|
}
|
|
1343
1354
|
|
|
@@ -1369,7 +1380,21 @@ Beautifier.prototype.beautify = function() {
|
|
|
1369
1380
|
this._output.add_new_line(true);
|
|
1370
1381
|
}
|
|
1371
1382
|
}
|
|
1383
|
+
if (this._input.peek() === ')') {
|
|
1384
|
+
this._output.trim(true);
|
|
1385
|
+
if (this._options.brace_style === "expand") {
|
|
1386
|
+
this._output.add_new_line(true);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1372
1389
|
} else if (this._ch === ":") {
|
|
1390
|
+
|
|
1391
|
+
for (var i = 0; i < this.NON_SEMICOLON_NEWLINE_PROPERTY.length; i++) {
|
|
1392
|
+
if (this._input.lookBack(this.NON_SEMICOLON_NEWLINE_PROPERTY[i])) {
|
|
1393
|
+
insideNonSemiColonValues = true;
|
|
1394
|
+
break;
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1373
1398
|
if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) {
|
|
1374
1399
|
// 'property: value' delimiter
|
|
1375
1400
|
// which could be in a conditional group query
|
|
@@ -1398,10 +1423,12 @@ Beautifier.prototype.beautify = function() {
|
|
|
1398
1423
|
}
|
|
1399
1424
|
}
|
|
1400
1425
|
} else if (this._ch === '"' || this._ch === '\'') {
|
|
1401
|
-
|
|
1426
|
+
var preserveQuoteSpace = previous_ch === '"' || previous_ch === '\'';
|
|
1427
|
+
this.preserveSingleSpace(preserveQuoteSpace || isAfterSpace);
|
|
1402
1428
|
this.print_string(this._ch + this.eatString(this._ch));
|
|
1403
1429
|
this.eatWhitespace(true);
|
|
1404
1430
|
} else if (this._ch === ';') {
|
|
1431
|
+
insideNonSemiColonValues = false;
|
|
1405
1432
|
if (parenLevel === 0) {
|
|
1406
1433
|
if (insidePropertyValue) {
|
|
1407
1434
|
this.outdent();
|
|
@@ -1441,22 +1468,39 @@ Beautifier.prototype.beautify = function() {
|
|
|
1441
1468
|
}
|
|
1442
1469
|
}
|
|
1443
1470
|
} else {
|
|
1444
|
-
|
|
1471
|
+
var space_needed = false;
|
|
1472
|
+
if (this._input.lookBack("with")) {
|
|
1473
|
+
// look back is not an accurate solution, we need tokens to confirm without whitespaces
|
|
1474
|
+
space_needed = true;
|
|
1475
|
+
}
|
|
1476
|
+
this.preserveSingleSpace(isAfterSpace || space_needed);
|
|
1445
1477
|
this.print_string(this._ch);
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
this.
|
|
1478
|
+
|
|
1479
|
+
// handle scss/sass map
|
|
1480
|
+
if (insidePropertyValue && previous_ch === "$" && this._options.selector_separator_newline) {
|
|
1481
|
+
this._output.add_new_line();
|
|
1482
|
+
insideScssMap = true;
|
|
1483
|
+
} else {
|
|
1484
|
+
this.eatWhitespace();
|
|
1485
|
+
parenLevel++;
|
|
1486
|
+
this.indent();
|
|
1487
|
+
}
|
|
1449
1488
|
}
|
|
1450
1489
|
} else if (this._ch === ')') {
|
|
1451
1490
|
if (parenLevel) {
|
|
1452
1491
|
parenLevel--;
|
|
1453
1492
|
this.outdent();
|
|
1454
1493
|
}
|
|
1494
|
+
if (insideScssMap && this._input.peek() === ";" && this._options.selector_separator_newline) {
|
|
1495
|
+
insideScssMap = false;
|
|
1496
|
+
this.outdent();
|
|
1497
|
+
this._output.add_new_line();
|
|
1498
|
+
}
|
|
1455
1499
|
this.print_string(this._ch);
|
|
1456
1500
|
} else if (this._ch === ',') {
|
|
1457
1501
|
this.print_string(this._ch);
|
|
1458
1502
|
this.eatWhitespace(true);
|
|
1459
|
-
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
|
|
1503
|
+
if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
|
|
1460
1504
|
this._output.add_new_line();
|
|
1461
1505
|
} else {
|
|
1462
1506
|
this._output.space_before_token = true;
|
|
@@ -1487,11 +1531,16 @@ Beautifier.prototype.beautify = function() {
|
|
|
1487
1531
|
this._ch = '';
|
|
1488
1532
|
}
|
|
1489
1533
|
} else if (this._ch === '!' && !this._input.lookBack("\\")) { // !important
|
|
1490
|
-
this.
|
|
1534
|
+
this._output.space_before_token = true;
|
|
1491
1535
|
this.print_string(this._ch);
|
|
1492
1536
|
} else {
|
|
1493
|
-
|
|
1537
|
+
var preserveAfterSpace = previous_ch === '"' || previous_ch === '\'';
|
|
1538
|
+
this.preserveSingleSpace(preserveAfterSpace || isAfterSpace);
|
|
1494
1539
|
this.print_string(this._ch);
|
|
1540
|
+
|
|
1541
|
+
if (!this._output.just_added_newline() && this._input.peek() === '\n' && insideNonSemiColonValues) {
|
|
1542
|
+
this._output.add_new_line();
|
|
1543
|
+
}
|
|
1495
1544
|
}
|
|
1496
1545
|
}
|
|
1497
1546
|
|
package/js/lib/beautify-html.js
CHANGED
|
@@ -2355,14 +2355,19 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
2355
2355
|
tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
|
|
2356
2356
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
2357
2357
|
} else {
|
|
2358
|
-
tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
|
|
2358
|
+
tag_check_match = raw_token.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/);
|
|
2359
2359
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
2360
2360
|
|
|
2361
|
-
// handle "{{#> myPartial}}
|
|
2362
|
-
if (raw_token.text
|
|
2363
|
-
this.tag_check
|
|
2361
|
+
// handle "{{#> myPartial}}" or "{{~#> myPartial}}"
|
|
2362
|
+
if ((raw_token.text.startsWith('{{#>') || raw_token.text.startsWith('{{~#>')) && this.tag_check[0] === '>') {
|
|
2363
|
+
if (this.tag_check === '>' && raw_token.next !== null) {
|
|
2364
|
+
this.tag_check = raw_token.next.text.split(' ')[0];
|
|
2365
|
+
} else {
|
|
2366
|
+
this.tag_check = raw_token.text.split('>')[1];
|
|
2367
|
+
}
|
|
2364
2368
|
}
|
|
2365
2369
|
}
|
|
2370
|
+
|
|
2366
2371
|
this.tag_check = this.tag_check.toLowerCase();
|
|
2367
2372
|
|
|
2368
2373
|
if (raw_token.type === TOKEN.COMMENT) {
|
|
@@ -2374,9 +2379,17 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
2374
2379
|
this.is_end_tag = !this.is_start_tag ||
|
|
2375
2380
|
(raw_token.closed && raw_token.closed.text === '/>');
|
|
2376
2381
|
|
|
2382
|
+
// if whitespace handler ~ included (i.e. {{~#if true}}), handlebars tags start at pos 3 not pos 2
|
|
2383
|
+
var handlebar_starts = 2;
|
|
2384
|
+
if (this.tag_start_char === '{' && this.text.length >= 3) {
|
|
2385
|
+
if (this.text.charAt(2) === '~') {
|
|
2386
|
+
handlebar_starts = 3;
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2377
2390
|
// handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
|
|
2378
2391
|
this.is_end_tag = this.is_end_tag ||
|
|
2379
|
-
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(
|
|
2392
|
+
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
|
|
2380
2393
|
}
|
|
2381
2394
|
};
|
|
2382
2395
|
|
package/js/lib/beautify.js
CHANGED
|
@@ -330,6 +330,7 @@ Beautifier.prototype.create_flags = function(flags_base, mode) {
|
|
|
330
330
|
inline_frame: false,
|
|
331
331
|
if_block: false,
|
|
332
332
|
else_block: false,
|
|
333
|
+
class_start_block: false, // class A { INSIDE HERE } or class B extends C { INSIDE HERE }
|
|
333
334
|
do_block: false,
|
|
334
335
|
do_while: false,
|
|
335
336
|
import_block: false,
|
|
@@ -742,6 +743,8 @@ Beautifier.prototype.handle_start_expr = function(current_token) {
|
|
|
742
743
|
(peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) {
|
|
743
744
|
this._output.space_before_token = true;
|
|
744
745
|
}
|
|
746
|
+
} else if (this._flags.parent && this._flags.parent.class_start_block) {
|
|
747
|
+
this._output.space_before_token = true;
|
|
745
748
|
}
|
|
746
749
|
}
|
|
747
750
|
} else {
|
|
@@ -836,10 +839,10 @@ Beautifier.prototype.handle_start_block = function(current_token) {
|
|
|
836
839
|
)) {
|
|
837
840
|
// We don't support TypeScript,but we didn't break it for a very long time.
|
|
838
841
|
// We'll try to keep not breaking it.
|
|
839
|
-
if (
|
|
840
|
-
this.set_mode(MODE.ObjectLiteral);
|
|
841
|
-
} else {
|
|
842
|
+
if (in_array(this._last_last_text, ['class', 'interface']) && !in_array(second_token.text, [':', ','])) {
|
|
842
843
|
this.set_mode(MODE.BlockStatement);
|
|
844
|
+
} else {
|
|
845
|
+
this.set_mode(MODE.ObjectLiteral);
|
|
843
846
|
}
|
|
844
847
|
} else if (this._flags.last_token.type === TOKEN.OPERATOR && this._flags.last_token.text === '=>') {
|
|
845
848
|
// arrow function: (param1, paramN) => { statements }
|
|
@@ -856,6 +859,12 @@ Beautifier.prototype.handle_start_block = function(current_token) {
|
|
|
856
859
|
this.set_mode(MODE.BlockStatement);
|
|
857
860
|
}
|
|
858
861
|
|
|
862
|
+
if (this._flags.last_token) {
|
|
863
|
+
if (reserved_array(this._flags.last_token.previous, ['class', 'extends'])) {
|
|
864
|
+
this._flags.class_start_block = true;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
859
868
|
var empty_braces = !next_token.comments_before && next_token.text === '}';
|
|
860
869
|
var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' &&
|
|
861
870
|
this._flags.last_token.type === TOKEN.END_EXPR;
|
|
@@ -955,7 +964,7 @@ Beautifier.prototype.handle_word = function(current_token) {
|
|
|
955
964
|
if (current_token.type === TOKEN.RESERVED) {
|
|
956
965
|
if (in_array(current_token.text, ['set', 'get']) && this._flags.mode !== MODE.ObjectLiteral) {
|
|
957
966
|
current_token.type = TOKEN.WORD;
|
|
958
|
-
} else if (current_token.text === 'import' && this._tokens.peek().text
|
|
967
|
+
} else if (current_token.text === 'import' && in_array(this._tokens.peek().text, ['(', '.'])) {
|
|
959
968
|
current_token.type = TOKEN.WORD;
|
|
960
969
|
} else if (in_array(current_token.text, ['as', 'from']) && !this._flags.import_block) {
|
|
961
970
|
current_token.type = TOKEN.WORD;
|
|
@@ -1296,13 +1305,6 @@ Beautifier.prototype.handle_operator = function(current_token) {
|
|
|
1296
1305
|
this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
|
|
1297
1306
|
}
|
|
1298
1307
|
|
|
1299
|
-
if (reserved_array(this._flags.last_token, special_words)) {
|
|
1300
|
-
// "return" had a special handling in TK_WORD. Now we need to return the favor
|
|
1301
|
-
this._output.space_before_token = true;
|
|
1302
|
-
this.print_token(current_token);
|
|
1303
|
-
return;
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
1308
|
// hack for actionscript's import .*;
|
|
1307
1309
|
if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) {
|
|
1308
1310
|
this.print_token(current_token);
|
|
@@ -1430,7 +1432,11 @@ Beautifier.prototype.handle_operator = function(current_token) {
|
|
|
1430
1432
|
// http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
|
|
1431
1433
|
// if there is a newline between -- or ++ and anything else we should preserve it.
|
|
1432
1434
|
if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) {
|
|
1433
|
-
this.
|
|
1435
|
+
var new_line_needed = reserved_array(this._flags.last_token, special_words) && current_token.newlines;
|
|
1436
|
+
if (new_line_needed && (this._previous_flags.if_block || this._previous_flags.else_block)) {
|
|
1437
|
+
this.restore_mode();
|
|
1438
|
+
}
|
|
1439
|
+
this.print_newline(new_line_needed, true);
|
|
1434
1440
|
}
|
|
1435
1441
|
|
|
1436
1442
|
if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
|
|
@@ -1570,6 +1576,10 @@ Beautifier.prototype.handle_dot = function(current_token) {
|
|
|
1570
1576
|
this.handle_whitespace_and_comments(current_token, true);
|
|
1571
1577
|
}
|
|
1572
1578
|
|
|
1579
|
+
if (this._flags.last_token.text.match('^[0-9]+$')) {
|
|
1580
|
+
this._output.space_before_token = true;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1573
1583
|
if (reserved_array(this._flags.last_token, special_words)) {
|
|
1574
1584
|
this._output.space_before_token = false;
|
|
1575
1585
|
} else {
|
|
@@ -2533,7 +2543,7 @@ var digit = /[0-9]/;
|
|
|
2533
2543
|
var dot_pattern = /[^\d\.]/;
|
|
2534
2544
|
|
|
2535
2545
|
var positionable_operators = (
|
|
2536
|
-
">>> === !== " +
|
|
2546
|
+
">>> === !== &&= ??= ||= " +
|
|
2537
2547
|
"<< && >= ** != == <= >> || ?? |> " +
|
|
2538
2548
|
"< / - + > : & % ? ^ | *").split(' ');
|
|
2539
2549
|
|
|
@@ -2541,7 +2551,7 @@ var positionable_operators = (
|
|
|
2541
2551
|
// Also, you must update possitionable operators separately from punct
|
|
2542
2552
|
var punct =
|
|
2543
2553
|
">>>= " +
|
|
2544
|
-
"... >>= <<= === >>> !== **= " +
|
|
2554
|
+
"... >>= <<= === >>> !== **= &&= ??= ||= " +
|
|
2545
2555
|
"=> ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> " +
|
|
2546
2556
|
"= ! ? > < : / ^ - + * & % ~ |";
|
|
2547
2557
|
|
|
@@ -2554,7 +2564,7 @@ var punct_pattern = new RegExp(punct);
|
|
|
2554
2564
|
|
|
2555
2565
|
// words which should always start on new line.
|
|
2556
2566
|
var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
|
|
2557
|
-
var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']);
|
|
2567
|
+
var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as', 'class', 'extends']);
|
|
2558
2568
|
var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');
|
|
2559
2569
|
|
|
2560
2570
|
// var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
|
|
@@ -2645,7 +2655,8 @@ Tokenizer.prototype._read_word = function(previous_token) {
|
|
|
2645
2655
|
if (!(previous_token.type === TOKEN.DOT ||
|
|
2646
2656
|
(previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) &&
|
|
2647
2657
|
reserved_word_pattern.test(resulting_string)) {
|
|
2648
|
-
if (resulting_string === 'in' || resulting_string === 'of')
|
|
2658
|
+
if ((resulting_string === 'in' || resulting_string === 'of') &&
|
|
2659
|
+
(previous_token.type === TOKEN.WORD || previous_token.type === TOKEN.STRING)) { // hack for 'in' and 'of' operators
|
|
2649
2660
|
return this._create_token(TOKEN.OPERATOR, resulting_string);
|
|
2650
2661
|
}
|
|
2651
2662
|
return this._create_token(TOKEN.RESERVED, resulting_string);
|
package/js/src/css/beautifier.js
CHANGED
|
@@ -67,6 +67,10 @@ function Beautifier(source_text, options) {
|
|
|
67
67
|
"@supports": true,
|
|
68
68
|
"@document": true
|
|
69
69
|
};
|
|
70
|
+
this.NON_SEMICOLON_NEWLINE_PROPERTY = [
|
|
71
|
+
"grid-template-areas",
|
|
72
|
+
"grid-template"
|
|
73
|
+
];
|
|
70
74
|
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -191,7 +195,9 @@ Beautifier.prototype.beautify = function() {
|
|
|
191
195
|
var enteringConditionalGroup = false;
|
|
192
196
|
var insideAtExtend = false;
|
|
193
197
|
var insideAtImport = false;
|
|
198
|
+
var insideScssMap = false;
|
|
194
199
|
var topCharacter = this._ch;
|
|
200
|
+
var insideNonSemiColonValues = false;
|
|
195
201
|
var whitespace;
|
|
196
202
|
var isAfterSpace;
|
|
197
203
|
var previous_ch;
|
|
@@ -243,7 +249,7 @@ Beautifier.prototype.beautify = function() {
|
|
|
243
249
|
|
|
244
250
|
// Ensures any new lines following the comment are preserved
|
|
245
251
|
this.eatWhitespace(true);
|
|
246
|
-
} else if (this._ch === '@') {
|
|
252
|
+
} else if (this._ch === '@' || this._ch === '$') {
|
|
247
253
|
this.preserveSingleSpace(isAfterSpace);
|
|
248
254
|
|
|
249
255
|
// deal with less propery mixins @{...}
|
|
@@ -314,7 +320,12 @@ Beautifier.prototype.beautify = function() {
|
|
|
314
320
|
this.indent();
|
|
315
321
|
this._output.set_indent(this._indentLevel);
|
|
316
322
|
} else {
|
|
317
|
-
|
|
323
|
+
// inside mixin and first param is object
|
|
324
|
+
if (previous_ch === '(') {
|
|
325
|
+
this._output.space_before_token = false;
|
|
326
|
+
} else if (previous_ch !== ',') {
|
|
327
|
+
this.indent();
|
|
328
|
+
}
|
|
318
329
|
this.print_string(this._ch);
|
|
319
330
|
}
|
|
320
331
|
|
|
@@ -346,7 +357,21 @@ Beautifier.prototype.beautify = function() {
|
|
|
346
357
|
this._output.add_new_line(true);
|
|
347
358
|
}
|
|
348
359
|
}
|
|
360
|
+
if (this._input.peek() === ')') {
|
|
361
|
+
this._output.trim(true);
|
|
362
|
+
if (this._options.brace_style === "expand") {
|
|
363
|
+
this._output.add_new_line(true);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
349
366
|
} 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
|
+
|
|
350
375
|
if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) {
|
|
351
376
|
// 'property: value' delimiter
|
|
352
377
|
// which could be in a conditional group query
|
|
@@ -375,10 +400,12 @@ Beautifier.prototype.beautify = function() {
|
|
|
375
400
|
}
|
|
376
401
|
}
|
|
377
402
|
} else if (this._ch === '"' || this._ch === '\'') {
|
|
378
|
-
|
|
403
|
+
var preserveQuoteSpace = previous_ch === '"' || previous_ch === '\'';
|
|
404
|
+
this.preserveSingleSpace(preserveQuoteSpace || isAfterSpace);
|
|
379
405
|
this.print_string(this._ch + this.eatString(this._ch));
|
|
380
406
|
this.eatWhitespace(true);
|
|
381
407
|
} else if (this._ch === ';') {
|
|
408
|
+
insideNonSemiColonValues = false;
|
|
382
409
|
if (parenLevel === 0) {
|
|
383
410
|
if (insidePropertyValue) {
|
|
384
411
|
this.outdent();
|
|
@@ -418,22 +445,39 @@ Beautifier.prototype.beautify = function() {
|
|
|
418
445
|
}
|
|
419
446
|
}
|
|
420
447
|
} else {
|
|
421
|
-
|
|
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);
|
|
422
454
|
this.print_string(this._ch);
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
this.
|
|
455
|
+
|
|
456
|
+
// handle scss/sass map
|
|
457
|
+
if (insidePropertyValue && previous_ch === "$" && this._options.selector_separator_newline) {
|
|
458
|
+
this._output.add_new_line();
|
|
459
|
+
insideScssMap = true;
|
|
460
|
+
} else {
|
|
461
|
+
this.eatWhitespace();
|
|
462
|
+
parenLevel++;
|
|
463
|
+
this.indent();
|
|
464
|
+
}
|
|
426
465
|
}
|
|
427
466
|
} else if (this._ch === ')') {
|
|
428
467
|
if (parenLevel) {
|
|
429
468
|
parenLevel--;
|
|
430
469
|
this.outdent();
|
|
431
470
|
}
|
|
471
|
+
if (insideScssMap && this._input.peek() === ";" && this._options.selector_separator_newline) {
|
|
472
|
+
insideScssMap = false;
|
|
473
|
+
this.outdent();
|
|
474
|
+
this._output.add_new_line();
|
|
475
|
+
}
|
|
432
476
|
this.print_string(this._ch);
|
|
433
477
|
} else if (this._ch === ',') {
|
|
434
478
|
this.print_string(this._ch);
|
|
435
479
|
this.eatWhitespace(true);
|
|
436
|
-
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
|
|
480
|
+
if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
|
|
437
481
|
this._output.add_new_line();
|
|
438
482
|
} else {
|
|
439
483
|
this._output.space_before_token = true;
|
|
@@ -464,11 +508,16 @@ Beautifier.prototype.beautify = function() {
|
|
|
464
508
|
this._ch = '';
|
|
465
509
|
}
|
|
466
510
|
} else if (this._ch === '!' && !this._input.lookBack("\\")) { // !important
|
|
467
|
-
this.
|
|
511
|
+
this._output.space_before_token = true;
|
|
468
512
|
this.print_string(this._ch);
|
|
469
513
|
} else {
|
|
470
|
-
|
|
514
|
+
var preserveAfterSpace = previous_ch === '"' || previous_ch === '\'';
|
|
515
|
+
this.preserveSingleSpace(preserveAfterSpace || isAfterSpace);
|
|
471
516
|
this.print_string(this._ch);
|
|
517
|
+
|
|
518
|
+
if (!this._output.just_added_newline() && this._input.peek() === '\n' && insideNonSemiColonValues) {
|
|
519
|
+
this._output.add_new_line();
|
|
520
|
+
}
|
|
472
521
|
}
|
|
473
522
|
}
|
|
474
523
|
|
|
@@ -607,14 +607,19 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
607
607
|
tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
|
|
608
608
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
609
609
|
} else {
|
|
610
|
-
tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
|
|
610
|
+
tag_check_match = raw_token.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/);
|
|
611
611
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
612
612
|
|
|
613
|
-
// handle "{{#> myPartial}}
|
|
614
|
-
if (raw_token.text
|
|
615
|
-
this.tag_check
|
|
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
|
+
}
|
|
616
620
|
}
|
|
617
621
|
}
|
|
622
|
+
|
|
618
623
|
this.tag_check = this.tag_check.toLowerCase();
|
|
619
624
|
|
|
620
625
|
if (raw_token.type === TOKEN.COMMENT) {
|
|
@@ -626,9 +631,17 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
626
631
|
this.is_end_tag = !this.is_start_tag ||
|
|
627
632
|
(raw_token.closed && raw_token.closed.text === '/>');
|
|
628
633
|
|
|
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
|
+
|
|
629
642
|
// handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
|
|
630
643
|
this.is_end_tag = this.is_end_tag ||
|
|
631
|
-
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(
|
|
644
|
+
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
|
|
632
645
|
}
|
|
633
646
|
};
|
|
634
647
|
|
|
@@ -185,6 +185,7 @@ Beautifier.prototype.create_flags = function(flags_base, mode) {
|
|
|
185
185
|
inline_frame: false,
|
|
186
186
|
if_block: false,
|
|
187
187
|
else_block: false,
|
|
188
|
+
class_start_block: false, // class A { INSIDE HERE } or class B extends C { INSIDE HERE }
|
|
188
189
|
do_block: false,
|
|
189
190
|
do_while: false,
|
|
190
191
|
import_block: false,
|
|
@@ -597,6 +598,8 @@ Beautifier.prototype.handle_start_expr = function(current_token) {
|
|
|
597
598
|
(peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) {
|
|
598
599
|
this._output.space_before_token = true;
|
|
599
600
|
}
|
|
601
|
+
} else if (this._flags.parent && this._flags.parent.class_start_block) {
|
|
602
|
+
this._output.space_before_token = true;
|
|
600
603
|
}
|
|
601
604
|
}
|
|
602
605
|
} else {
|
|
@@ -691,10 +694,10 @@ Beautifier.prototype.handle_start_block = function(current_token) {
|
|
|
691
694
|
)) {
|
|
692
695
|
// We don't support TypeScript,but we didn't break it for a very long time.
|
|
693
696
|
// We'll try to keep not breaking it.
|
|
694
|
-
if (
|
|
695
|
-
this.set_mode(MODE.ObjectLiteral);
|
|
696
|
-
} else {
|
|
697
|
+
if (in_array(this._last_last_text, ['class', 'interface']) && !in_array(second_token.text, [':', ','])) {
|
|
697
698
|
this.set_mode(MODE.BlockStatement);
|
|
699
|
+
} else {
|
|
700
|
+
this.set_mode(MODE.ObjectLiteral);
|
|
698
701
|
}
|
|
699
702
|
} else if (this._flags.last_token.type === TOKEN.OPERATOR && this._flags.last_token.text === '=>') {
|
|
700
703
|
// arrow function: (param1, paramN) => { statements }
|
|
@@ -711,6 +714,12 @@ Beautifier.prototype.handle_start_block = function(current_token) {
|
|
|
711
714
|
this.set_mode(MODE.BlockStatement);
|
|
712
715
|
}
|
|
713
716
|
|
|
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
|
+
|
|
714
723
|
var empty_braces = !next_token.comments_before && next_token.text === '}';
|
|
715
724
|
var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' &&
|
|
716
725
|
this._flags.last_token.type === TOKEN.END_EXPR;
|
|
@@ -810,7 +819,7 @@ Beautifier.prototype.handle_word = function(current_token) {
|
|
|
810
819
|
if (current_token.type === TOKEN.RESERVED) {
|
|
811
820
|
if (in_array(current_token.text, ['set', 'get']) && this._flags.mode !== MODE.ObjectLiteral) {
|
|
812
821
|
current_token.type = TOKEN.WORD;
|
|
813
|
-
} else if (current_token.text === 'import' && this._tokens.peek().text
|
|
822
|
+
} else if (current_token.text === 'import' && in_array(this._tokens.peek().text, ['(', '.'])) {
|
|
814
823
|
current_token.type = TOKEN.WORD;
|
|
815
824
|
} else if (in_array(current_token.text, ['as', 'from']) && !this._flags.import_block) {
|
|
816
825
|
current_token.type = TOKEN.WORD;
|
|
@@ -1151,13 +1160,6 @@ Beautifier.prototype.handle_operator = function(current_token) {
|
|
|
1151
1160
|
this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
|
|
1152
1161
|
}
|
|
1153
1162
|
|
|
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
|
-
|
|
1161
1163
|
// hack for actionscript's import .*;
|
|
1162
1164
|
if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) {
|
|
1163
1165
|
this.print_token(current_token);
|
|
@@ -1285,7 +1287,11 @@ Beautifier.prototype.handle_operator = function(current_token) {
|
|
|
1285
1287
|
// http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
|
|
1286
1288
|
// if there is a newline between -- or ++ and anything else we should preserve it.
|
|
1287
1289
|
if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) {
|
|
1288
|
-
this.
|
|
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);
|
|
1289
1295
|
}
|
|
1290
1296
|
|
|
1291
1297
|
if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
|
|
@@ -1425,6 +1431,10 @@ Beautifier.prototype.handle_dot = function(current_token) {
|
|
|
1425
1431
|
this.handle_whitespace_and_comments(current_token, true);
|
|
1426
1432
|
}
|
|
1427
1433
|
|
|
1434
|
+
if (this._flags.last_token.text.match('^[0-9]+$')) {
|
|
1435
|
+
this._output.space_before_token = true;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1428
1438
|
if (reserved_array(this._flags.last_token, special_words)) {
|
|
1429
1439
|
this._output.space_before_token = false;
|
|
1430
1440
|
} else {
|
|
@@ -74,7 +74,7 @@ var digit = /[0-9]/;
|
|
|
74
74
|
var dot_pattern = /[^\d\.]/;
|
|
75
75
|
|
|
76
76
|
var positionable_operators = (
|
|
77
|
-
">>> === !== " +
|
|
77
|
+
">>> === !== &&= ??= ||= " +
|
|
78
78
|
"<< && >= ** != == <= >> || ?? |> " +
|
|
79
79
|
"< / - + > : & % ? ^ | *").split(' ');
|
|
80
80
|
|
|
@@ -82,7 +82,7 @@ var positionable_operators = (
|
|
|
82
82
|
// Also, you must update possitionable operators separately from punct
|
|
83
83
|
var punct =
|
|
84
84
|
">>>= " +
|
|
85
|
-
"... >>= <<= === >>> !== **= " +
|
|
85
|
+
"... >>= <<= === >>> !== **= &&= ??= ||= " +
|
|
86
86
|
"=> ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> " +
|
|
87
87
|
"= ! ? > < : / ^ - + * & % ~ |";
|
|
88
88
|
|
|
@@ -95,7 +95,7 @@ var punct_pattern = new RegExp(punct);
|
|
|
95
95
|
|
|
96
96
|
// words which should always start on new line.
|
|
97
97
|
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']);
|
|
99
99
|
var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');
|
|
100
100
|
|
|
101
101
|
// var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
|
|
@@ -186,7 +186,8 @@ Tokenizer.prototype._read_word = function(previous_token) {
|
|
|
186
186
|
if (!(previous_token.type === TOKEN.DOT ||
|
|
187
187
|
(previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) &&
|
|
188
188
|
reserved_word_pattern.test(resulting_string)) {
|
|
189
|
-
if (resulting_string === 'in' || resulting_string === 'of')
|
|
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
|
|
190
191
|
return this._create_token(TOKEN.OPERATOR, resulting_string);
|
|
191
192
|
}
|
|
192
193
|
return this._create_token(TOKEN.RESERVED, resulting_string);
|