js-beautify 1.9.0 → 1.10.1
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/CHANGELOG.md +46 -0
- package/README.md +45 -24
- package/js/lib/beautifier.js +198 -72
- package/js/lib/beautifier.min.js +1 -1
- package/js/lib/beautify-css.js +52 -23
- package/js/lib/beautify-html.js +129 -34
- package/js/lib/beautify.js +50 -17
- package/js/lib/cli.js +6 -0
- package/js/src/cli.js +6 -0
- package/js/src/core/options.js +6 -0
- package/js/src/core/output.js +6 -1
- package/js/src/core/templatablepattern.js +9 -0
- package/js/src/css/beautifier.js +40 -22
- package/js/src/html/beautifier.js +63 -19
- package/js/src/html/options.js +4 -0
- package/js/src/html/tokenizer.js +41 -14
- package/js/src/javascript/beautifier.js +26 -11
- package/js/src/javascript/tokenizer.js +3 -5
- package/package.json +7 -7
package/js/lib/beautify-css.js
CHANGED
|
@@ -321,7 +321,11 @@ OutputLine.prototype.trim = function() {
|
|
|
321
321
|
|
|
322
322
|
OutputLine.prototype.toString = function() {
|
|
323
323
|
var result = '';
|
|
324
|
-
if (
|
|
324
|
+
if (this.is_empty()) {
|
|
325
|
+
if (this.__parent.indent_empty_lines) {
|
|
326
|
+
result = this.__parent.get_indent_string(this.__indent_count);
|
|
327
|
+
}
|
|
328
|
+
} else {
|
|
325
329
|
result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count);
|
|
326
330
|
result += this.__items.join('');
|
|
327
331
|
}
|
|
@@ -398,6 +402,7 @@ function Output(options, baseIndentString) {
|
|
|
398
402
|
this._end_with_newline = options.end_with_newline;
|
|
399
403
|
this.indent_size = options.indent_size;
|
|
400
404
|
this.wrap_line_length = options.wrap_line_length;
|
|
405
|
+
this.indent_empty_lines = options.indent_empty_lines;
|
|
401
406
|
this.__lines = [];
|
|
402
407
|
this.previous_line = null;
|
|
403
408
|
this.current_line = null;
|
|
@@ -650,6 +655,12 @@ function Options(options, merge_child_field) {
|
|
|
650
655
|
// Backwards compat with 1.3.x
|
|
651
656
|
this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
|
|
652
657
|
|
|
658
|
+
this.indent_empty_lines = this._get_boolean('indent_empty_lines');
|
|
659
|
+
|
|
660
|
+
// valid templating languages ['django', 'erb', 'handlebars', 'php']
|
|
661
|
+
// For now, 'auto' = all off for javascript, all on for html (and inline javascript).
|
|
662
|
+
// other values ignored
|
|
663
|
+
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
|
|
653
664
|
}
|
|
654
665
|
|
|
655
666
|
Options.prototype._get_array = function(name, default_value) {
|
|
@@ -1304,6 +1315,9 @@ Beautifier.prototype.beautify = function() {
|
|
|
1304
1315
|
isAfterSpace = whitespace !== '';
|
|
1305
1316
|
previous_ch = topCharacter;
|
|
1306
1317
|
this._ch = this._input.next();
|
|
1318
|
+
if (this._ch === '\\' && this._input.hasNext()) {
|
|
1319
|
+
this._ch += this._input.next();
|
|
1320
|
+
}
|
|
1307
1321
|
topCharacter = this._ch;
|
|
1308
1322
|
|
|
1309
1323
|
if (!this._ch) {
|
|
@@ -1436,7 +1450,7 @@ Beautifier.prototype.beautify = function() {
|
|
|
1436
1450
|
}
|
|
1437
1451
|
}
|
|
1438
1452
|
} else if (this._ch === ":") {
|
|
1439
|
-
if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend) {
|
|
1453
|
+
if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) {
|
|
1440
1454
|
// 'property: value' delimiter
|
|
1441
1455
|
// which could be in a conditional group query
|
|
1442
1456
|
this.print_string(':');
|
|
@@ -1468,51 +1482,66 @@ Beautifier.prototype.beautify = function() {
|
|
|
1468
1482
|
this.print_string(this._ch + this.eatString(this._ch));
|
|
1469
1483
|
this.eatWhitespace(true);
|
|
1470
1484
|
} else if (this._ch === ';') {
|
|
1471
|
-
if (
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
this.
|
|
1485
|
+
if (parenLevel === 0) {
|
|
1486
|
+
if (insidePropertyValue) {
|
|
1487
|
+
this.outdent();
|
|
1488
|
+
insidePropertyValue = false;
|
|
1489
|
+
}
|
|
1490
|
+
insideAtExtend = false;
|
|
1491
|
+
insideAtImport = false;
|
|
1492
|
+
this.print_string(this._ch);
|
|
1493
|
+
this.eatWhitespace(true);
|
|
1494
|
+
|
|
1495
|
+
// This maintains single line comments on the same
|
|
1496
|
+
// line. Block comments are also affected, but
|
|
1497
|
+
// a new line is always output before one inside
|
|
1498
|
+
// that section
|
|
1499
|
+
if (this._input.peek() !== '/') {
|
|
1500
|
+
this._output.add_new_line();
|
|
1501
|
+
}
|
|
1502
|
+
} else {
|
|
1503
|
+
this.print_string(this._ch);
|
|
1504
|
+
this.eatWhitespace(true);
|
|
1505
|
+
this._output.space_before_token = true;
|
|
1486
1506
|
}
|
|
1487
1507
|
} else if (this._ch === '(') { // may be a url
|
|
1488
1508
|
if (this._input.lookBack("url")) {
|
|
1489
1509
|
this.print_string(this._ch);
|
|
1490
1510
|
this.eatWhitespace();
|
|
1511
|
+
parenLevel++;
|
|
1512
|
+
this.indent();
|
|
1491
1513
|
this._ch = this._input.next();
|
|
1492
1514
|
if (this._ch === ')' || this._ch === '"' || this._ch === '\'') {
|
|
1493
1515
|
this._input.back();
|
|
1494
|
-
parenLevel++;
|
|
1495
1516
|
} else if (this._ch) {
|
|
1496
1517
|
this.print_string(this._ch + this.eatString(')'));
|
|
1518
|
+
if (parenLevel) {
|
|
1519
|
+
parenLevel--;
|
|
1520
|
+
this.outdent();
|
|
1521
|
+
}
|
|
1497
1522
|
}
|
|
1498
1523
|
} else {
|
|
1499
|
-
parenLevel++;
|
|
1500
1524
|
this.preserveSingleSpace(isAfterSpace);
|
|
1501
1525
|
this.print_string(this._ch);
|
|
1502
1526
|
this.eatWhitespace();
|
|
1527
|
+
parenLevel++;
|
|
1528
|
+
this.indent();
|
|
1503
1529
|
}
|
|
1504
1530
|
} else if (this._ch === ')') {
|
|
1531
|
+
if (parenLevel) {
|
|
1532
|
+
parenLevel--;
|
|
1533
|
+
this.outdent();
|
|
1534
|
+
}
|
|
1505
1535
|
this.print_string(this._ch);
|
|
1506
|
-
parenLevel--;
|
|
1507
1536
|
} else if (this._ch === ',') {
|
|
1508
1537
|
this.print_string(this._ch);
|
|
1509
1538
|
this.eatWhitespace(true);
|
|
1510
|
-
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel
|
|
1539
|
+
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel === 0 && !insideAtImport) {
|
|
1511
1540
|
this._output.add_new_line();
|
|
1512
1541
|
} else {
|
|
1513
1542
|
this._output.space_before_token = true;
|
|
1514
1543
|
}
|
|
1515
|
-
} else if ((this._ch === '>' || this._ch === '+' || this._ch === '~') && !insidePropertyValue && parenLevel
|
|
1544
|
+
} else if ((this._ch === '>' || this._ch === '+' || this._ch === '~') && !insidePropertyValue && parenLevel === 0) {
|
|
1516
1545
|
//handle combinator spacing
|
|
1517
1546
|
if (this._options.space_around_combinator) {
|
|
1518
1547
|
this._output.space_before_token = true;
|
|
@@ -1537,7 +1566,7 @@ Beautifier.prototype.beautify = function() {
|
|
|
1537
1566
|
if (whitespaceChar.test(this._ch)) {
|
|
1538
1567
|
this._ch = '';
|
|
1539
1568
|
}
|
|
1540
|
-
} else if (this._ch === '!') { // !important
|
|
1569
|
+
} else if (this._ch === '!' && !this._input.lookBack("\\")) { // !important
|
|
1541
1570
|
this.print_string(' ');
|
|
1542
1571
|
this.print_string(this._ch);
|
|
1543
1572
|
} else {
|
package/js/lib/beautify-html.js
CHANGED
|
@@ -331,7 +331,11 @@ OutputLine.prototype.trim = function() {
|
|
|
331
331
|
|
|
332
332
|
OutputLine.prototype.toString = function() {
|
|
333
333
|
var result = '';
|
|
334
|
-
if (
|
|
334
|
+
if (this.is_empty()) {
|
|
335
|
+
if (this.__parent.indent_empty_lines) {
|
|
336
|
+
result = this.__parent.get_indent_string(this.__indent_count);
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
335
339
|
result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count);
|
|
336
340
|
result += this.__items.join('');
|
|
337
341
|
}
|
|
@@ -408,6 +412,7 @@ function Output(options, baseIndentString) {
|
|
|
408
412
|
this._end_with_newline = options.end_with_newline;
|
|
409
413
|
this.indent_size = options.indent_size;
|
|
410
414
|
this.wrap_line_length = options.wrap_line_length;
|
|
415
|
+
this.indent_empty_lines = options.indent_empty_lines;
|
|
411
416
|
this.__lines = [];
|
|
412
417
|
this.previous_line = null;
|
|
413
418
|
this.current_line = null;
|
|
@@ -720,6 +725,12 @@ function Options(options, merge_child_field) {
|
|
|
720
725
|
// Backwards compat with 1.3.x
|
|
721
726
|
this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
|
|
722
727
|
|
|
728
|
+
this.indent_empty_lines = this._get_boolean('indent_empty_lines');
|
|
729
|
+
|
|
730
|
+
// valid templating languages ['django', 'erb', 'handlebars', 'php']
|
|
731
|
+
// For now, 'auto' = all off for javascript, all on for html (and inline javascript).
|
|
732
|
+
// other values ignored
|
|
733
|
+
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
|
|
723
734
|
}
|
|
724
735
|
|
|
725
736
|
Options.prototype._get_array = function(name, default_value) {
|
|
@@ -1643,6 +1654,15 @@ TemplatablePattern.prototype.disable = function(language) {
|
|
|
1643
1654
|
return result;
|
|
1644
1655
|
};
|
|
1645
1656
|
|
|
1657
|
+
TemplatablePattern.prototype.read_options = function(options) {
|
|
1658
|
+
var result = this._create();
|
|
1659
|
+
for (var language in template_names) {
|
|
1660
|
+
result._disabled[language] = options.templating.indexOf(language) === -1;
|
|
1661
|
+
}
|
|
1662
|
+
result._update();
|
|
1663
|
+
return result;
|
|
1664
|
+
};
|
|
1665
|
+
|
|
1646
1666
|
TemplatablePattern.prototype.exclude = function(language) {
|
|
1647
1667
|
var result = this._create();
|
|
1648
1668
|
result._excluded[language] = true;
|
|
@@ -2243,10 +2263,12 @@ Beautifier.prototype._handle_text = function(printer, raw_token, last_tag_token)
|
|
|
2243
2263
|
Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, last_tag_token) {
|
|
2244
2264
|
var local = this;
|
|
2245
2265
|
if (raw_token.text !== '') {
|
|
2246
|
-
|
|
2266
|
+
|
|
2247
2267
|
var text = raw_token.text,
|
|
2248
2268
|
_beautifier,
|
|
2249
|
-
script_indent_level = 1
|
|
2269
|
+
script_indent_level = 1,
|
|
2270
|
+
pre = '',
|
|
2271
|
+
post = '';
|
|
2250
2272
|
if (last_tag_token.custom_beautifier_name === 'javascript' && typeof this._js_beautify === 'function') {
|
|
2251
2273
|
_beautifier = this._js_beautify;
|
|
2252
2274
|
} else if (last_tag_token.custom_beautifier_name === 'css' && typeof this._css_beautify === 'function') {
|
|
@@ -2258,7 +2280,6 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token,
|
|
|
2258
2280
|
};
|
|
2259
2281
|
}
|
|
2260
2282
|
|
|
2261
|
-
|
|
2262
2283
|
if (this._options.indent_scripts === "keep") {
|
|
2263
2284
|
script_indent_level = 0;
|
|
2264
2285
|
} else if (this._options.indent_scripts === "separate") {
|
|
@@ -2271,24 +2292,67 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token,
|
|
|
2271
2292
|
// we'll be adding one back after the text but before the containing tag.
|
|
2272
2293
|
text = text.replace(/\n[ \t]*$/, '');
|
|
2273
2294
|
|
|
2274
|
-
|
|
2295
|
+
// Handle the case where content is wrapped in a comment or cdata.
|
|
2296
|
+
if (last_tag_token.custom_beautifier_name !== 'html' &&
|
|
2297
|
+
text[0] === '<' && text.match(/^(<!--|<!\[CDATA\[)/)) {
|
|
2298
|
+
var matched = /^(<!--[^\n]*|<!\[CDATA\[)(\n?)([ \t\n]*)([\s\S]*)(-->|]]>)$/.exec(text);
|
|
2275
2299
|
|
|
2276
|
-
//
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
if (white) {
|
|
2287
|
-
text = text.replace(new RegExp('\n(' + white + ')?', 'g'), '\n');
|
|
2300
|
+
// if we start to wrap but don't finish, print raw
|
|
2301
|
+
if (!matched) {
|
|
2302
|
+
printer.add_raw_token(raw_token);
|
|
2303
|
+
return;
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
pre = indentation + matched[1] + '\n';
|
|
2307
|
+
text = matched[4];
|
|
2308
|
+
if (matched[5]) {
|
|
2309
|
+
post = indentation + matched[5];
|
|
2288
2310
|
}
|
|
2289
2311
|
|
|
2290
|
-
|
|
2312
|
+
// if there is at least one empty line at the end of this text, strip it
|
|
2313
|
+
// we'll be adding one back after the text but before the containing tag.
|
|
2314
|
+
text = text.replace(/\n[ \t]*$/, '');
|
|
2315
|
+
|
|
2316
|
+
if (matched[2] || matched[3].indexOf('\n') !== -1) {
|
|
2317
|
+
// if the first line of the non-comment text has spaces
|
|
2318
|
+
// use that as the basis for indenting in null case.
|
|
2319
|
+
matched = matched[3].match(/[ \t]+$/);
|
|
2320
|
+
if (matched) {
|
|
2321
|
+
raw_token.whitespace_before = matched[0];
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2291
2324
|
}
|
|
2325
|
+
|
|
2326
|
+
if (text) {
|
|
2327
|
+
if (_beautifier) {
|
|
2328
|
+
|
|
2329
|
+
// call the Beautifier if avaliable
|
|
2330
|
+
var Child_options = function() {
|
|
2331
|
+
this.eol = '\n';
|
|
2332
|
+
};
|
|
2333
|
+
Child_options.prototype = this._options.raw_options;
|
|
2334
|
+
var child_options = new Child_options();
|
|
2335
|
+
text = _beautifier(indentation + text, child_options);
|
|
2336
|
+
} else {
|
|
2337
|
+
// simply indent the string otherwise
|
|
2338
|
+
var white = raw_token.whitespace_before;
|
|
2339
|
+
if (white) {
|
|
2340
|
+
text = text.replace(new RegExp('\n(' + white + ')?', 'g'), '\n');
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
text = indentation + text.replace(/\n/g, '\n' + indentation);
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
if (pre) {
|
|
2348
|
+
if (!text) {
|
|
2349
|
+
text = pre + post;
|
|
2350
|
+
} else {
|
|
2351
|
+
text = pre + text + '\n' + post;
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
printer.print_newline(false);
|
|
2292
2356
|
if (text) {
|
|
2293
2357
|
raw_token.text = text;
|
|
2294
2358
|
raw_token.whitespace_before = '';
|
|
@@ -2579,8 +2643,8 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
|
|
|
2579
2643
|
} else if (parser_token.tag_name === 'th' || parser_token.tag_name === 'td') {
|
|
2580
2644
|
// A td element’s end tag may be omitted if the td element is immediately followed by a td or th element, or if there is no more content in the parent element.
|
|
2581
2645
|
// A th element’s end tag may be omitted if the th element is immediately followed by a td or th element, or if there is no more content in the parent element.
|
|
2582
|
-
result = result || this._tag_stack.try_pop('td', ['tr']);
|
|
2583
|
-
result = result || this._tag_stack.try_pop('th', ['tr']);
|
|
2646
|
+
result = result || this._tag_stack.try_pop('td', ['table', 'thead', 'tbody', 'tfoot', 'tr']);
|
|
2647
|
+
result = result || this._tag_stack.try_pop('th', ['table', 'thead', 'tbody', 'tfoot', 'tr']);
|
|
2584
2648
|
}
|
|
2585
2649
|
|
|
2586
2650
|
// Start element omission not handled currently
|
|
@@ -2636,6 +2700,9 @@ var BaseOptions = __webpack_require__(6).Options;
|
|
|
2636
2700
|
|
|
2637
2701
|
function Options(options) {
|
|
2638
2702
|
BaseOptions.call(this, options, 'html');
|
|
2703
|
+
if (this.templating.length === 1 && this.templating[0] === 'auto') {
|
|
2704
|
+
this.templating = ['django', 'erb', 'handlebars', 'php'];
|
|
2705
|
+
}
|
|
2639
2706
|
|
|
2640
2707
|
this.indent_inner_html = this._get_boolean('indent_inner_html');
|
|
2641
2708
|
this.indent_body_inner_html = this._get_boolean('indent_body_inner_html', true);
|
|
@@ -2683,6 +2750,7 @@ function Options(options) {
|
|
|
2683
2750
|
]);
|
|
2684
2751
|
this.unformatted_content_delimiter = this._get_characters('unformatted_content_delimiter');
|
|
2685
2752
|
this.indent_scripts = this._get_selection('indent_scripts', ['normal', 'keep', 'separate']);
|
|
2753
|
+
|
|
2686
2754
|
}
|
|
2687
2755
|
Options.prototype = new BaseOptions();
|
|
2688
2756
|
|
|
@@ -2754,7 +2822,7 @@ var Tokenizer = function(input_string, options) {
|
|
|
2754
2822
|
|
|
2755
2823
|
// Words end at whitespace or when a tag starts
|
|
2756
2824
|
// if we are indenting handlebars, they are considered tags
|
|
2757
|
-
var templatable_reader = new TemplatablePattern(this._input);
|
|
2825
|
+
var templatable_reader = new TemplatablePattern(this._input).read_options(this._options);
|
|
2758
2826
|
var pattern_reader = new Pattern(this._input);
|
|
2759
2827
|
|
|
2760
2828
|
this.__patterns = {
|
|
@@ -2769,7 +2837,7 @@ var Tokenizer = function(input_string, options) {
|
|
|
2769
2837
|
handlebars_open: pattern_reader.until(/[\n\r\t }]/),
|
|
2770
2838
|
handlebars_raw_close: pattern_reader.until(/}}/),
|
|
2771
2839
|
comment: pattern_reader.starting_with(/<!--/).until_after(/-->/),
|
|
2772
|
-
cdata: pattern_reader.starting_with(/<!\[
|
|
2840
|
+
cdata: pattern_reader.starting_with(/<!\[CDATA\[/).until_after(/]]>/),
|
|
2773
2841
|
// https://en.wikipedia.org/wiki/Conditional_comment
|
|
2774
2842
|
conditional_comment: pattern_reader.starting_with(/<!\[/).until_after(/]>/),
|
|
2775
2843
|
processing: pattern_reader.starting_with(/<\?/).until_after(/\?>/)
|
|
@@ -2820,27 +2888,27 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { //
|
|
|
2820
2888
|
|
|
2821
2889
|
token = token || this._read_open_handlebars(c, open_token);
|
|
2822
2890
|
token = token || this._read_attribute(c, previous_token, open_token);
|
|
2823
|
-
token = token || this._read_raw_content(previous_token, open_token);
|
|
2891
|
+
token = token || this._read_raw_content(c, previous_token, open_token);
|
|
2824
2892
|
token = token || this._read_close(c, open_token);
|
|
2825
2893
|
token = token || this._read_content_word(c);
|
|
2826
|
-
token = token || this.
|
|
2894
|
+
token = token || this._read_comment_or_cdata(c);
|
|
2895
|
+
token = token || this._read_processing(c);
|
|
2827
2896
|
token = token || this._read_open(c, open_token);
|
|
2828
2897
|
token = token || this._create_token(TOKEN.UNKNOWN, this._input.next());
|
|
2829
2898
|
|
|
2830
2899
|
return token;
|
|
2831
2900
|
};
|
|
2832
2901
|
|
|
2833
|
-
Tokenizer.prototype.
|
|
2902
|
+
Tokenizer.prototype._read_comment_or_cdata = function(c) { // jshint unused:false
|
|
2834
2903
|
var token = null;
|
|
2835
2904
|
var resulting_string = null;
|
|
2836
2905
|
var directives = null;
|
|
2837
2906
|
|
|
2838
2907
|
if (c === '<') {
|
|
2839
2908
|
var peek1 = this._input.peek(1);
|
|
2840
|
-
//if we're in a comment, do something special
|
|
2841
2909
|
// We treat all comments as literals, even more than preformatted tags
|
|
2842
|
-
// we
|
|
2843
|
-
if (
|
|
2910
|
+
// we only look for the appropriate closing marker
|
|
2911
|
+
if (peek1 === '!') {
|
|
2844
2912
|
resulting_string = this.__patterns.comment.read();
|
|
2845
2913
|
|
|
2846
2914
|
// only process directive on html comments
|
|
@@ -2851,8 +2919,6 @@ Tokenizer.prototype._read_comment = function(c) { // jshint unused:false
|
|
|
2851
2919
|
}
|
|
2852
2920
|
} else {
|
|
2853
2921
|
resulting_string = this.__patterns.cdata.read();
|
|
2854
|
-
resulting_string = resulting_string || this.__patterns.conditional_comment.read();
|
|
2855
|
-
resulting_string = resulting_string || this.__patterns.processing.read();
|
|
2856
2922
|
}
|
|
2857
2923
|
}
|
|
2858
2924
|
|
|
@@ -2865,6 +2931,27 @@ Tokenizer.prototype._read_comment = function(c) { // jshint unused:false
|
|
|
2865
2931
|
return token;
|
|
2866
2932
|
};
|
|
2867
2933
|
|
|
2934
|
+
Tokenizer.prototype._read_processing = function(c) { // jshint unused:false
|
|
2935
|
+
var token = null;
|
|
2936
|
+
var resulting_string = null;
|
|
2937
|
+
var directives = null;
|
|
2938
|
+
|
|
2939
|
+
if (c === '<') {
|
|
2940
|
+
var peek1 = this._input.peek(1);
|
|
2941
|
+
if (peek1 === '!' || peek1 === '?') {
|
|
2942
|
+
resulting_string = this.__patterns.conditional_comment.read();
|
|
2943
|
+
resulting_string = resulting_string || this.__patterns.processing.read();
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
if (resulting_string) {
|
|
2947
|
+
token = this._create_token(TOKEN.COMMENT, resulting_string);
|
|
2948
|
+
token.directives = directives;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
|
|
2952
|
+
return token;
|
|
2953
|
+
};
|
|
2954
|
+
|
|
2868
2955
|
Tokenizer.prototype._read_open = function(c, open_token) {
|
|
2869
2956
|
var resulting_string = null;
|
|
2870
2957
|
var token = null;
|
|
@@ -2956,19 +3043,27 @@ Tokenizer.prototype._is_content_unformatted = function(tag_name) {
|
|
|
2956
3043
|
// script and style tags should always be read as unformatted content
|
|
2957
3044
|
// finally content_unformatted and unformatted element contents are unformatted
|
|
2958
3045
|
return this._options.void_elements.indexOf(tag_name) === -1 &&
|
|
2959
|
-
(tag_name
|
|
2960
|
-
this._options.content_unformatted.indexOf(tag_name) !== -1 ||
|
|
3046
|
+
(this._options.content_unformatted.indexOf(tag_name) !== -1 ||
|
|
2961
3047
|
this._options.unformatted.indexOf(tag_name) !== -1);
|
|
2962
3048
|
};
|
|
2963
3049
|
|
|
2964
3050
|
|
|
2965
|
-
Tokenizer.prototype._read_raw_content = function(previous_token, open_token) { // jshint unused:false
|
|
3051
|
+
Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) { // jshint unused:false
|
|
2966
3052
|
var resulting_string = '';
|
|
2967
3053
|
if (open_token && open_token.text[0] === '{') {
|
|
2968
3054
|
resulting_string = this.__patterns.handlebars_raw_close.read();
|
|
2969
3055
|
} else if (previous_token.type === TOKEN.TAG_CLOSE && (previous_token.opened.text[0] === '<')) {
|
|
2970
3056
|
var tag_name = previous_token.opened.text.substr(1).toLowerCase();
|
|
2971
|
-
if (
|
|
3057
|
+
if (tag_name === 'script' || tag_name === 'style') {
|
|
3058
|
+
// Script and style tags are allowed to have comments wrapping their content
|
|
3059
|
+
// or just have regular content.
|
|
3060
|
+
var token = this._read_comment_or_cdata(c);
|
|
3061
|
+
if (token) {
|
|
3062
|
+
token.type = TOKEN.TEXT;
|
|
3063
|
+
return token;
|
|
3064
|
+
}
|
|
3065
|
+
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
|
3066
|
+
} else if (this._is_content_unformatted(tag_name)) {
|
|
2972
3067
|
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
|
2973
3068
|
}
|
|
2974
3069
|
}
|
package/js/lib/beautify.js
CHANGED
|
@@ -631,7 +631,7 @@ Beautifier.prototype.print_token_line_indentation = function(current_token) {
|
|
|
631
631
|
}
|
|
632
632
|
};
|
|
633
633
|
|
|
634
|
-
Beautifier.prototype.print_token = function(current_token
|
|
634
|
+
Beautifier.prototype.print_token = function(current_token) {
|
|
635
635
|
if (this._output.raw) {
|
|
636
636
|
this._output.add_raw_token(current_token);
|
|
637
637
|
return;
|
|
@@ -657,10 +657,9 @@ Beautifier.prototype.print_token = function(current_token, printable_token) {
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
-
printable_token = printable_token || current_token.text;
|
|
661
660
|
this.print_token_line_indentation(current_token);
|
|
662
661
|
this._output.non_breaking_space = true;
|
|
663
|
-
this._output.add_token(
|
|
662
|
+
this._output.add_token(current_token.text);
|
|
664
663
|
if (this._output.previous_token_wrapped) {
|
|
665
664
|
this._flags.multiline_frame = true;
|
|
666
665
|
}
|
|
@@ -914,6 +913,8 @@ Beautifier.prototype.handle_start_block = function(current_token) {
|
|
|
914
913
|
if (this._flags.last_word === 'switch' && this._flags.last_token.type === TOKEN.END_EXPR) {
|
|
915
914
|
this.set_mode(MODE.BlockStatement);
|
|
916
915
|
this._flags.in_case_statement = true;
|
|
916
|
+
} else if (this._flags.case_body) {
|
|
917
|
+
this.set_mode(MODE.BlockStatement);
|
|
917
918
|
} else if (second_token && (
|
|
918
919
|
(in_array(second_token.text, [':', ',']) && in_array(next_token.type, [TOKEN.STRING, TOKEN.WORD, TOKEN.RESERVED])) ||
|
|
919
920
|
(in_array(next_token.text, ['get', 'set', '...']) && in_array(second_token.type, [TOKEN.WORD, TOKEN.RESERVED]))
|
|
@@ -1099,11 +1100,12 @@ Beautifier.prototype.handle_word = function(current_token) {
|
|
|
1099
1100
|
|
|
1100
1101
|
if (this._flags.in_case_statement && reserved_array(current_token, ['case', 'default'])) {
|
|
1101
1102
|
this.print_newline();
|
|
1102
|
-
if (this._flags.case_body || this._options.jslint_happy) {
|
|
1103
|
+
if (this._flags.last_token.type !== TOKEN.END_BLOCK && (this._flags.case_body || this._options.jslint_happy)) {
|
|
1103
1104
|
// switch cases following one another
|
|
1104
1105
|
this.deindent();
|
|
1105
|
-
this._flags.case_body = false;
|
|
1106
1106
|
}
|
|
1107
|
+
this._flags.case_body = false;
|
|
1108
|
+
|
|
1107
1109
|
this.print_token(current_token);
|
|
1108
1110
|
this._flags.in_case = true;
|
|
1109
1111
|
return;
|
|
@@ -1401,11 +1403,16 @@ Beautifier.prototype.handle_operator = function(current_token) {
|
|
|
1401
1403
|
}
|
|
1402
1404
|
|
|
1403
1405
|
if (current_token.text === ':' && this._flags.in_case) {
|
|
1404
|
-
this._flags.case_body = true;
|
|
1405
|
-
this.indent();
|
|
1406
1406
|
this.print_token(current_token);
|
|
1407
|
-
|
|
1407
|
+
|
|
1408
1408
|
this._flags.in_case = false;
|
|
1409
|
+
this._flags.case_body = true;
|
|
1410
|
+
if (this._tokens.peek().type !== TOKEN.START_BLOCK) {
|
|
1411
|
+
this.indent();
|
|
1412
|
+
this.print_newline();
|
|
1413
|
+
} else {
|
|
1414
|
+
this._output.space_before_token = true;
|
|
1415
|
+
}
|
|
1409
1416
|
return;
|
|
1410
1417
|
}
|
|
1411
1418
|
|
|
@@ -1568,8 +1575,12 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
|
|
|
1568
1575
|
this.print_token(current_token);
|
|
1569
1576
|
this._output.space_before_token = true;
|
|
1570
1577
|
return;
|
|
1578
|
+
} else {
|
|
1579
|
+
this.print_block_commment(current_token, preserve_statement_flags);
|
|
1571
1580
|
}
|
|
1581
|
+
};
|
|
1572
1582
|
|
|
1583
|
+
Beautifier.prototype.print_block_commment = function(current_token, preserve_statement_flags) {
|
|
1573
1584
|
var lines = split_linebreaks(current_token.text);
|
|
1574
1585
|
var j; // iterator for this case
|
|
1575
1586
|
var javadoc = false;
|
|
@@ -1581,7 +1592,8 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
|
|
|
1581
1592
|
this.print_newline(false, preserve_statement_flags);
|
|
1582
1593
|
|
|
1583
1594
|
// first line always indented
|
|
1584
|
-
this.
|
|
1595
|
+
this.print_token_line_indentation(current_token);
|
|
1596
|
+
this._output.add_token(lines[0]);
|
|
1585
1597
|
this.print_newline(false, preserve_statement_flags);
|
|
1586
1598
|
|
|
1587
1599
|
|
|
@@ -1597,10 +1609,12 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
|
|
|
1597
1609
|
for (j = 0; j < lines.length; j++) {
|
|
1598
1610
|
if (javadoc) {
|
|
1599
1611
|
// javadoc: reformat and re-indent
|
|
1600
|
-
this.
|
|
1612
|
+
this.print_token_line_indentation(current_token);
|
|
1613
|
+
this._output.add_token(ltrim(lines[j]));
|
|
1601
1614
|
} else if (starless && lines[j]) {
|
|
1602
1615
|
// starless: re-indent non-empty content, avoiding trim
|
|
1603
|
-
this.
|
|
1616
|
+
this.print_token_line_indentation(current_token);
|
|
1617
|
+
this._output.add_token(lines[j].substring(lastIndentLength));
|
|
1604
1618
|
} else {
|
|
1605
1619
|
// normal comments output raw
|
|
1606
1620
|
this._output.current_line.set_indent(-1);
|
|
@@ -1615,6 +1629,7 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
|
|
|
1615
1629
|
}
|
|
1616
1630
|
};
|
|
1617
1631
|
|
|
1632
|
+
|
|
1618
1633
|
Beautifier.prototype.handle_comment = function(current_token, preserve_statement_flags) {
|
|
1619
1634
|
if (current_token.newlines) {
|
|
1620
1635
|
this.print_newline(false, preserve_statement_flags);
|
|
@@ -1838,7 +1853,11 @@ OutputLine.prototype.trim = function() {
|
|
|
1838
1853
|
|
|
1839
1854
|
OutputLine.prototype.toString = function() {
|
|
1840
1855
|
var result = '';
|
|
1841
|
-
if (
|
|
1856
|
+
if (this.is_empty()) {
|
|
1857
|
+
if (this.__parent.indent_empty_lines) {
|
|
1858
|
+
result = this.__parent.get_indent_string(this.__indent_count);
|
|
1859
|
+
}
|
|
1860
|
+
} else {
|
|
1842
1861
|
result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count);
|
|
1843
1862
|
result += this.__items.join('');
|
|
1844
1863
|
}
|
|
@@ -1915,6 +1934,7 @@ function Output(options, baseIndentString) {
|
|
|
1915
1934
|
this._end_with_newline = options.end_with_newline;
|
|
1916
1935
|
this.indent_size = options.indent_size;
|
|
1917
1936
|
this.wrap_line_length = options.wrap_line_length;
|
|
1937
|
+
this.indent_empty_lines = options.indent_empty_lines;
|
|
1918
1938
|
this.__lines = [];
|
|
1919
1939
|
this.previous_line = null;
|
|
1920
1940
|
this.current_line = null;
|
|
@@ -2389,6 +2409,12 @@ function Options(options, merge_child_field) {
|
|
|
2389
2409
|
// Backwards compat with 1.3.x
|
|
2390
2410
|
this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
|
|
2391
2411
|
|
|
2412
|
+
this.indent_empty_lines = this._get_boolean('indent_empty_lines');
|
|
2413
|
+
|
|
2414
|
+
// valid templating languages ['django', 'erb', 'handlebars', 'php']
|
|
2415
|
+
// For now, 'auto' = all off for javascript, all on for html (and inline javascript).
|
|
2416
|
+
// other values ignored
|
|
2417
|
+
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
|
|
2392
2418
|
}
|
|
2393
2419
|
|
|
2394
2420
|
Options.prototype._get_array = function(name, default_value) {
|
|
@@ -2626,10 +2652,8 @@ var Tokenizer = function(input_string, options) {
|
|
|
2626
2652
|
/\u2028\u2029/.source);
|
|
2627
2653
|
|
|
2628
2654
|
var pattern_reader = new Pattern(this._input);
|
|
2629
|
-
var templatable = new TemplatablePattern(this._input)
|
|
2630
|
-
|
|
2631
|
-
templatable = templatable.disable('django');
|
|
2632
|
-
|
|
2655
|
+
var templatable = new TemplatablePattern(this._input)
|
|
2656
|
+
.read_options(this._options);
|
|
2633
2657
|
|
|
2634
2658
|
this.__patterns = {
|
|
2635
2659
|
template: templatable,
|
|
@@ -2798,7 +2822,7 @@ Tokenizer.prototype._read_non_javascript = function(c) {
|
|
|
2798
2822
|
|
|
2799
2823
|
this._input.back();
|
|
2800
2824
|
|
|
2801
|
-
} else if (c === '<') {
|
|
2825
|
+
} else if (c === '<' && this._is_first_token()) {
|
|
2802
2826
|
resulting_string = this.__patterns.html_comment_start.read();
|
|
2803
2827
|
if (resulting_string) {
|
|
2804
2828
|
while (this._input.hasNext() && !this._input.testChar(acorn.newline)) {
|
|
@@ -3882,6 +3906,15 @@ TemplatablePattern.prototype.disable = function(language) {
|
|
|
3882
3906
|
return result;
|
|
3883
3907
|
};
|
|
3884
3908
|
|
|
3909
|
+
TemplatablePattern.prototype.read_options = function(options) {
|
|
3910
|
+
var result = this._create();
|
|
3911
|
+
for (var language in template_names) {
|
|
3912
|
+
result._disabled[language] = options.templating.indexOf(language) === -1;
|
|
3913
|
+
}
|
|
3914
|
+
result._update();
|
|
3915
|
+
return result;
|
|
3916
|
+
};
|
|
3917
|
+
|
|
3885
3918
|
TemplatablePattern.prototype.exclude = function(language) {
|
|
3886
3919
|
var result = this._create();
|
|
3887
3920
|
result._excluded[language] = true;
|
package/js/lib/cli.js
CHANGED
|
@@ -92,6 +92,8 @@ var path = require('path'),
|
|
|
92
92
|
"end_with_newline": Boolean,
|
|
93
93
|
"comma_first": Boolean,
|
|
94
94
|
"operator_position": ["before-newline", "after-newline", "preserve-newline"],
|
|
95
|
+
"indent_empty_lines": Boolean,
|
|
96
|
+
"templating": [String, Array],
|
|
95
97
|
// CSS-only
|
|
96
98
|
"selector_separator_newline": Boolean,
|
|
97
99
|
"newline_between_rules": Boolean,
|
|
@@ -177,6 +179,8 @@ var path = require('path'),
|
|
|
177
179
|
"q": ["--quiet"]
|
|
178
180
|
// no shorthand for "config"
|
|
179
181
|
// no shorthand for "editorconfig"
|
|
182
|
+
// no shorthand for "indent_empty_lines"
|
|
183
|
+
// not shorthad for "templating"
|
|
180
184
|
});
|
|
181
185
|
|
|
182
186
|
function verifyExists(fullPath) {
|
|
@@ -346,6 +350,8 @@ function usage(err) {
|
|
|
346
350
|
' -e, --eol Character(s) to use as line terminators.',
|
|
347
351
|
' [first newline in file, otherwise "\\n]',
|
|
348
352
|
' -n, --end-with-newline End output with newline',
|
|
353
|
+
' --indent-empty-lines Keep indentation on empty lines',
|
|
354
|
+
' --templating List of templating languages (auto,none,django,erb,handlebars,php) ["auto"] auto = none in JavaScript, all in html',
|
|
349
355
|
' --editorconfig Use EditorConfig to set up the options'
|
|
350
356
|
];
|
|
351
357
|
|