js-beautify 1.10.3 → 1.13.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 +60 -0
- package/README.md +19 -14
- package/js/lib/beautifier.js +124 -48
- package/js/lib/beautifier.min.js +1 -1
- package/js/lib/beautify-css.js +31 -11
- package/js/lib/beautify-html.js +83 -35
- package/js/lib/beautify.js +36 -8
- package/js/lib/cli.js +2 -1
- package/js/lib/unpackers/p_a_c_k_e_r_unpacker.js +8 -0
- package/js/src/cli.js +2 -1
- package/js/src/core/options.js +2 -2
- package/js/src/core/templatablepattern.js +22 -2
- package/js/src/css/beautifier.js +19 -9
- package/js/src/css/options.js +10 -0
- package/js/src/html/beautifier.js +54 -29
- package/js/src/html/tokenizer.js +5 -2
- package/js/src/javascript/beautifier.js +5 -1
- package/js/src/javascript/tokenizer.js +7 -3
- package/js/src/unpackers/p_a_c_k_e_r_unpacker.js +8 -0
- package/package.json +15 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,64 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
## v1.13.1
|
|
3
|
+
|
|
4
|
+
### Description
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
### Closed Issues
|
|
8
|
+
* Option 'max_preserve_newlines' not working on beautify_css.js CSS Beautifier ([#1863](https://github.com/beautify-web/js-beautify/issues/1863))
|
|
9
|
+
* React Fragment Short Syntax <></> issue ([#1854](https://github.com/beautify-web/js-beautify/issues/1854))
|
|
10
|
+
* add viewport meta tag to index.html ([#1843](https://github.com/beautify-web/js-beautify/pull/1843))
|
|
11
|
+
* Add basic smarty templating support ([#1820](https://github.com/beautify-web/js-beautify/issues/1820))
|
|
12
|
+
* Tagged Template literals ([#1244](https://github.com/beautify-web/js-beautify/issues/1244))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## v1.13.0
|
|
16
|
+
|
|
17
|
+
### Description
|
|
18
|
+
This release truly fixes the python cssbeautifier installation and updates cssbeautifier cli to use the same general code as jsbeautifier.
|
|
19
|
+
|
|
20
|
+
Also, as of this release Node.js 8.x is no longer guaranteed to work. Node.js 8.x LTS reached end-of-life in January 2020.
|
|
21
|
+
Parts of our test infrastructure no longer support Node.js 8.x. The js-beautifier should still run on Node.js 8.x, but it is not part of the CI system and so not guaranteed to work.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Closed Issues
|
|
25
|
+
* (internal) Refactor python cssbeautifier to reuse jsbeautifier CLI methods ([#1832](https://github.com/beautify-web/js-beautify/pull/1832))
|
|
26
|
+
* (internal) Switch from node-static to serve ([#1831](https://github.com/beautify-web/js-beautify/pull/1831))
|
|
27
|
+
* Fixed pip install cssbeautifier ([#1830](https://github.com/beautify-web/js-beautify/pull/1830))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## v1.12.0
|
|
31
|
+
|
|
32
|
+
### Description
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Closed Issues
|
|
36
|
+
* Python jsbeautifier fails for special chars ([#1809](https://github.com/beautify-web/js-beautify/issues/1809))
|
|
37
|
+
* pip install cssbeautifier fails ([#1808](https://github.com/beautify-web/js-beautify/issues/1808))
|
|
38
|
+
* Add expand brace-style option to css beautifier ([#1796](https://github.com/beautify-web/js-beautify/pull/1796))
|
|
39
|
+
* Support nullish-coalescing ([#1794](https://github.com/beautify-web/js-beautify/issues/1794))
|
|
40
|
+
* Upgrade ga.js to analytics.js ([#1777](https://github.com/beautify-web/js-beautify/issues/1777))
|
|
41
|
+
* Newline rule not working with css-like files ([#1776](https://github.com/beautify-web/js-beautify/issues/1776))
|
|
42
|
+
* no new line after self closing tag ([#1718](https://github.com/beautify-web/js-beautify/issues/1718))
|
|
43
|
+
* HTML format, no break after <label>? ([#1365](https://github.com/beautify-web/js-beautify/issues/1365))
|
|
44
|
+
* Does this extension still supports applying Allman style to CSS? ([#1353](https://github.com/beautify-web/js-beautify/issues/1353))
|
|
45
|
+
* Add brace_style option for CSS ([#1259](https://github.com/beautify-web/js-beautify/issues/1259))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## v1.11.0
|
|
49
|
+
|
|
50
|
+
### Description
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Closed Issues
|
|
54
|
+
* Please bump mkdirp to fix mkdirp@0.5.1 vulnerability ([#1768](https://github.com/beautify-web/js-beautify/issues/1768))
|
|
55
|
+
* Incorrect indentation of Handlebars inline partials ([#1756](https://github.com/beautify-web/js-beautify/issues/1756))
|
|
56
|
+
* Support optional-chaining ([#1727](https://github.com/beautify-web/js-beautify/issues/1727))
|
|
57
|
+
* Please support es module ([#1706](https://github.com/beautify-web/js-beautify/issues/1706))
|
|
58
|
+
* Support new js proposals: optional-chaining & pipeline-operator ([#1530](https://github.com/beautify-web/js-beautify/issues/1530))
|
|
59
|
+
* Optional <p> closing not implemented ([#1503](https://github.com/beautify-web/js-beautify/issues/1503))
|
|
60
|
+
|
|
61
|
+
|
|
2
62
|
## v1.10.3
|
|
3
63
|
|
|
4
64
|
### Description
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# JS Beautifier
|
|
2
|
-
|
|
2
|
+

|
|
3
3
|
|
|
4
4
|
[](https://pypi.python.org/pypi/jsbeautifier)
|
|
5
5
|
[](https://cdnjs.com/libraries/js-beautify)
|
|
@@ -61,17 +61,17 @@ JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries
|
|
|
61
61
|
|
|
62
62
|
To pull the latest version from one of these services include one set of the script tags below in your document:
|
|
63
63
|
```html
|
|
64
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.
|
|
65
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.
|
|
66
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.
|
|
64
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.1/beautify.js"></script>
|
|
65
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.1/beautify-css.js"></script>
|
|
66
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.1/beautify-html.js"></script>
|
|
67
67
|
|
|
68
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.
|
|
69
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.
|
|
70
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.
|
|
68
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.1/beautify.min.js"></script>
|
|
69
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.1/beautify-css.min.js"></script>
|
|
70
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.1/beautify-html.min.js"></script>
|
|
71
71
|
|
|
72
|
-
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.
|
|
73
|
-
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.
|
|
74
|
-
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.
|
|
72
|
+
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.13.1/js/lib/beautify.js"></script>
|
|
73
|
+
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.13.1/js/lib/beautify-css.js"></script>
|
|
74
|
+
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.13.1/js/lib/beautify-html.js"></script>
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
Older versions are available by changing the version number.
|
|
@@ -85,7 +85,11 @@ To install the Python version of the beautifier:
|
|
|
85
85
|
```bash
|
|
86
86
|
$ pip install jsbeautifier
|
|
87
87
|
```
|
|
88
|
-
Unlike the JavaScript version, the Python version can only reformat JavaScript. It does not work against HTML or CSS files
|
|
88
|
+
Unlike the JavaScript version, the Python version can only reformat JavaScript. It does not work against HTML or CSS files, but you can install _css-beautify_ for CSS:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
$ pip install cssbeautifier
|
|
92
|
+
```
|
|
89
93
|
|
|
90
94
|
# Usage
|
|
91
95
|
You can beautify javascript using JS Beautifier in your web browser, or on the command-line using node.js or python.
|
|
@@ -191,7 +195,7 @@ Beautifier Options:
|
|
|
191
195
|
-C, --comma-first Put commas at the beginning of new line instead of end
|
|
192
196
|
-O, --operator-position Set operator position (before-newline|after-newline|preserve-newline) [before-newline]
|
|
193
197
|
--indent-empty-lines Keep indentation on empty lines
|
|
194
|
-
--templating List of templating languages (auto,django,erb,handlebars,php) ["auto"] auto = none in JavaScript, all in html
|
|
198
|
+
--templating List of templating languages (auto,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in html
|
|
195
199
|
```
|
|
196
200
|
|
|
197
201
|
Which correspond to the underscored option keys for both library interfaces
|
|
@@ -318,6 +322,7 @@ CSS Beautifier Options:
|
|
|
318
322
|
-t, --indent-with-tabs Indent with tabs, overrides -s and -c
|
|
319
323
|
-e, --eol Character(s) to use as line terminators. (default newline - "\\n")
|
|
320
324
|
-n, --end-with-newline End output with newline
|
|
325
|
+
-b, --brace-style [collapse|expand] ["collapse"]
|
|
321
326
|
-L, --selector-separator-newline Add a newline between multiple selectors
|
|
322
327
|
-N, --newline-between-rules Add a newline between CSS rules
|
|
323
328
|
--indent-empty-lines Keep indentation on empty lines
|
|
@@ -344,7 +349,7 @@ HTML Beautifier Options:
|
|
|
344
349
|
--indent_scripts Sets indent level inside script tags ("normal", "keep", "separate")
|
|
345
350
|
--unformatted_content_delimiter Keep text content together between this string [""]
|
|
346
351
|
--indent-empty-lines Keep indentation on empty lines
|
|
347
|
-
--templating List of templating languages (auto,none,django,erb,handlebars,php) ["auto"] auto = none in JavaScript, all in html
|
|
352
|
+
--templating List of templating languages (auto,none,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in html
|
|
348
353
|
```
|
|
349
354
|
|
|
350
355
|
## Directives
|
|
@@ -399,4 +404,4 @@ Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, D
|
|
|
399
404
|
Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
|
|
400
405
|
Mathias Bynens, Vittorio Gambaletta and others.
|
|
401
406
|
|
|
402
|
-
(README.md: js-beautify@1.
|
|
407
|
+
(README.md: js-beautify@1.13.1)
|
package/js/lib/beautifier.js
CHANGED
|
@@ -1258,7 +1258,9 @@ Beautifier.prototype.handle_semicolon = function(current_token) {
|
|
|
1258
1258
|
};
|
|
1259
1259
|
|
|
1260
1260
|
Beautifier.prototype.handle_string = function(current_token) {
|
|
1261
|
-
if (
|
|
1261
|
+
if (current_token.text.startsWith("`") && current_token.newlines === 0 && current_token.whitespace_before === '' && (current_token.previous.text === ')' || this._flags.last_token.type === TOKEN.WORD)) {
|
|
1262
|
+
//Conditional for detectign backtick strings
|
|
1263
|
+
} else if (this.start_of_statement(current_token)) {
|
|
1262
1264
|
// The conditional starts the statement if appropriate.
|
|
1263
1265
|
// One difference - strings want at least a space before
|
|
1264
1266
|
this._output.space_before_token = true;
|
|
@@ -1270,6 +1272,8 @@ Beautifier.prototype.handle_string = function(current_token) {
|
|
|
1270
1272
|
if (!this.start_of_object_property()) {
|
|
1271
1273
|
this.allow_wrap_or_preserved_newline(current_token);
|
|
1272
1274
|
}
|
|
1275
|
+
} else if ((current_token.text.startsWith("`") && this._flags.last_token.type === TOKEN.END_EXPR && (current_token.previous.text === ']' || current_token.previous.text === ')') && current_token.newlines === 0)) {
|
|
1276
|
+
this._output.space_before_token = true;
|
|
1273
1277
|
} else {
|
|
1274
1278
|
this.print_newline();
|
|
1275
1279
|
}
|
|
@@ -2381,10 +2385,10 @@ function Options(options, merge_child_field) {
|
|
|
2381
2385
|
|
|
2382
2386
|
this.indent_empty_lines = this._get_boolean('indent_empty_lines');
|
|
2383
2387
|
|
|
2384
|
-
// valid templating languages ['django', 'erb', 'handlebars', 'php']
|
|
2388
|
+
// valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty']
|
|
2385
2389
|
// For now, 'auto' = all off for javascript, all on for html (and inline javascript).
|
|
2386
2390
|
// other values ignored
|
|
2387
|
-
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
|
|
2391
|
+
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']);
|
|
2388
2392
|
}
|
|
2389
2393
|
|
|
2390
2394
|
Options.prototype._get_array = function(name, default_value) {
|
|
@@ -2589,7 +2593,7 @@ var dot_pattern = /[^\d\.]/;
|
|
|
2589
2593
|
|
|
2590
2594
|
var positionable_operators = (
|
|
2591
2595
|
">>> === !== " +
|
|
2592
|
-
"<< && >= ** != == <= >> || " +
|
|
2596
|
+
"<< && >= ** != == <= >> || ?? |> " +
|
|
2593
2597
|
"< / - + > : & % ? ^ | *").split(' ');
|
|
2594
2598
|
|
|
2595
2599
|
// IMPORTANT: this must be sorted longest to shortest or tokenizing many not work.
|
|
@@ -2597,10 +2601,12 @@ var positionable_operators = (
|
|
|
2597
2601
|
var punct =
|
|
2598
2602
|
">>>= " +
|
|
2599
2603
|
"... >>= <<= === >>> !== **= " +
|
|
2600
|
-
"=> ^= :: /= << <= == && -= >= >> != -- += ** || ++ %= &= *= |= " +
|
|
2604
|
+
"=> ^= :: /= << <= == && -= >= >> != -- += ** || ?? ++ %= &= *= |= |> " +
|
|
2601
2605
|
"= ! ? > < : / ^ - + * & % ~ |";
|
|
2602
2606
|
|
|
2603
2607
|
punct = punct.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&");
|
|
2608
|
+
// ?. but not if followed by a number
|
|
2609
|
+
punct = '\\?\\.(?!\\d) ' + punct;
|
|
2604
2610
|
punct = punct.replace(/ /g, '|');
|
|
2605
2611
|
|
|
2606
2612
|
var punct_pattern = new RegExp(punct);
|
|
@@ -2638,7 +2644,7 @@ var Tokenizer = function(input_string, options) {
|
|
|
2638
2644
|
html_comment_end: pattern_reader.matching(/-->/),
|
|
2639
2645
|
include: pattern_reader.starting_with(/#include/).until_after(acorn.lineBreak),
|
|
2640
2646
|
shebang: pattern_reader.starting_with(/#!/).until_after(acorn.lineBreak),
|
|
2641
|
-
xml: pattern_reader.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{[\s\S]+?}))*\s*(\/?)\s*>/),
|
|
2647
|
+
xml: pattern_reader.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\]|)(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{[\s\S]+?}))*\s*(\/?)\s*>/),
|
|
2642
2648
|
single_quote: templatable.until(/['\\\n\r\u2028\u2029]/),
|
|
2643
2649
|
double_quote: templatable.until(/["\\\n\r\u2028\u2029]/),
|
|
2644
2650
|
template_text: templatable.until(/[`\\$]/),
|
|
@@ -2742,6 +2748,8 @@ Tokenizer.prototype._read_punctuation = function() {
|
|
|
2742
2748
|
if (resulting_string !== '') {
|
|
2743
2749
|
if (resulting_string === '=') {
|
|
2744
2750
|
return this._create_token(TOKEN.EQUALS, resulting_string);
|
|
2751
|
+
} else if (resulting_string === '?.') {
|
|
2752
|
+
return this._create_token(TOKEN.DOT, resulting_string);
|
|
2745
2753
|
} else {
|
|
2746
2754
|
return this._create_token(TOKEN.OPERATOR, resulting_string);
|
|
2747
2755
|
}
|
|
@@ -3831,7 +3839,8 @@ var template_names = {
|
|
|
3831
3839
|
django: false,
|
|
3832
3840
|
erb: false,
|
|
3833
3841
|
handlebars: false,
|
|
3834
|
-
php: false
|
|
3842
|
+
php: false,
|
|
3843
|
+
smarty: false
|
|
3835
3844
|
};
|
|
3836
3845
|
|
|
3837
3846
|
// This lets templates appear anywhere we would do a readUntil
|
|
@@ -3857,7 +3866,10 @@ function TemplatablePattern(input_scanner, parent) {
|
|
|
3857
3866
|
// django coflicts with handlebars a bit.
|
|
3858
3867
|
django: pattern.starting_with(/{%/).until_after(/%}/),
|
|
3859
3868
|
django_value: pattern.starting_with(/{{/).until_after(/}}/),
|
|
3860
|
-
django_comment: pattern.starting_with(/{#/).until_after(/#}/)
|
|
3869
|
+
django_comment: pattern.starting_with(/{#/).until_after(/#}/),
|
|
3870
|
+
smarty: pattern.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/),
|
|
3871
|
+
smarty_comment: pattern.starting_with(/{\*/).until_after(/\*}/),
|
|
3872
|
+
smarty_literal: pattern.starting_with(/{literal}/).until_after(/{\/literal}/)
|
|
3861
3873
|
};
|
|
3862
3874
|
}
|
|
3863
3875
|
TemplatablePattern.prototype = new Pattern();
|
|
@@ -3931,9 +3943,14 @@ TemplatablePattern.prototype.__set_templated_pattern = function() {
|
|
|
3931
3943
|
}
|
|
3932
3944
|
if (!this._disabled.django) {
|
|
3933
3945
|
items.push(this.__patterns.django._starting_pattern.source);
|
|
3946
|
+
// The starting pattern for django is more complex because it has different
|
|
3947
|
+
// patterns for value, comment, and other sections
|
|
3934
3948
|
items.push(this.__patterns.django_value._starting_pattern.source);
|
|
3935
3949
|
items.push(this.__patterns.django_comment._starting_pattern.source);
|
|
3936
3950
|
}
|
|
3951
|
+
if (!this._disabled.smarty) {
|
|
3952
|
+
items.push(this.__patterns.smarty._starting_pattern.source);
|
|
3953
|
+
}
|
|
3937
3954
|
|
|
3938
3955
|
if (this._until_pattern) {
|
|
3939
3956
|
items.push(this._until_pattern.source);
|
|
@@ -3979,6 +3996,17 @@ TemplatablePattern.prototype._read_template = function() {
|
|
|
3979
3996
|
this.__patterns.django.read();
|
|
3980
3997
|
}
|
|
3981
3998
|
}
|
|
3999
|
+
if (!this._disabled.smarty) {
|
|
4000
|
+
// smarty cannot be enabled with django or handlebars enabled
|
|
4001
|
+
if (this._disabled.django && this._disabled.handlebars) {
|
|
4002
|
+
resulting_string = resulting_string ||
|
|
4003
|
+
this.__patterns.smarty_comment.read();
|
|
4004
|
+
resulting_string = resulting_string ||
|
|
4005
|
+
this.__patterns.smarty_literal.read();
|
|
4006
|
+
resulting_string = resulting_string ||
|
|
4007
|
+
this.__patterns.smarty.read();
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
3982
4010
|
}
|
|
3983
4011
|
return resulting_string;
|
|
3984
4012
|
};
|
|
@@ -4134,13 +4162,12 @@ Beautifier.prototype.eatString = function(endChars) {
|
|
|
4134
4162
|
// the first newline will be output
|
|
4135
4163
|
Beautifier.prototype.eatWhitespace = function(allowAtLeastOneNewLine) {
|
|
4136
4164
|
var result = whitespaceChar.test(this._input.peek());
|
|
4137
|
-
var
|
|
4138
|
-
|
|
4165
|
+
var newline_count = 0;
|
|
4139
4166
|
while (whitespaceChar.test(this._input.peek())) {
|
|
4140
4167
|
this._ch = this._input.next();
|
|
4141
4168
|
if (allowAtLeastOneNewLine && this._ch === '\n') {
|
|
4142
|
-
if (this._options.
|
|
4143
|
-
|
|
4169
|
+
if (newline_count === 0 || newline_count < this._options.max_preserve_newlines) {
|
|
4170
|
+
newline_count++;
|
|
4144
4171
|
this._output.add_new_line(true);
|
|
4145
4172
|
}
|
|
4146
4173
|
}
|
|
@@ -4334,23 +4361,34 @@ Beautifier.prototype.beautify = function() {
|
|
|
4334
4361
|
insidePropertyValue = false;
|
|
4335
4362
|
this.outdent();
|
|
4336
4363
|
}
|
|
4337
|
-
this.indent();
|
|
4338
|
-
this._output.space_before_token = true;
|
|
4339
|
-
this.print_string(this._ch);
|
|
4340
4364
|
|
|
4341
4365
|
// when entering conditional groups, only rulesets are allowed
|
|
4342
4366
|
if (enteringConditionalGroup) {
|
|
4343
4367
|
enteringConditionalGroup = false;
|
|
4344
|
-
insideRule = (this._indentLevel
|
|
4368
|
+
insideRule = (this._indentLevel >= this._nestedLevel);
|
|
4345
4369
|
} else {
|
|
4346
4370
|
// otherwise, declarations are also allowed
|
|
4347
|
-
insideRule = (this._indentLevel >= this._nestedLevel);
|
|
4371
|
+
insideRule = (this._indentLevel >= this._nestedLevel - 1);
|
|
4348
4372
|
}
|
|
4349
4373
|
if (this._options.newline_between_rules && insideRule) {
|
|
4350
4374
|
if (this._output.previous_line && this._output.previous_line.item(-1) !== '{') {
|
|
4351
4375
|
this._output.ensure_empty_line_above('/', ',');
|
|
4352
4376
|
}
|
|
4353
4377
|
}
|
|
4378
|
+
|
|
4379
|
+
this._output.space_before_token = true;
|
|
4380
|
+
|
|
4381
|
+
// The difference in print_string and indent order is necessary to indent the '{' correctly
|
|
4382
|
+
if (this._options.brace_style === 'expand') {
|
|
4383
|
+
this._output.add_new_line();
|
|
4384
|
+
this.print_string(this._ch);
|
|
4385
|
+
this.indent();
|
|
4386
|
+
this._output.set_indent(this._indentLevel);
|
|
4387
|
+
} else {
|
|
4388
|
+
this.indent();
|
|
4389
|
+
this.print_string(this._ch);
|
|
4390
|
+
}
|
|
4391
|
+
|
|
4354
4392
|
this.eatWhitespace(true);
|
|
4355
4393
|
this._output.add_new_line();
|
|
4356
4394
|
} else if (this._ch === '}') {
|
|
@@ -4558,6 +4596,16 @@ function Options(options) {
|
|
|
4558
4596
|
var space_around_selector_separator = this._get_boolean('space_around_selector_separator');
|
|
4559
4597
|
this.space_around_combinator = this._get_boolean('space_around_combinator') || space_around_selector_separator;
|
|
4560
4598
|
|
|
4599
|
+
var brace_style_split = this._get_selection_list('brace_style', ['collapse', 'expand', 'end-expand', 'none', 'preserve-inline']);
|
|
4600
|
+
this.brace_style = 'collapse';
|
|
4601
|
+
for (var bs = 0; bs < brace_style_split.length; bs++) {
|
|
4602
|
+
if (brace_style_split[bs] !== 'expand') {
|
|
4603
|
+
// default to collapse, as only collapse|expand is implemented for now
|
|
4604
|
+
this.brace_style = 'collapse';
|
|
4605
|
+
} else {
|
|
4606
|
+
this.brace_style = brace_style_split[bs];
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4561
4609
|
}
|
|
4562
4610
|
Options.prototype = new BaseOptions();
|
|
4563
4611
|
|
|
@@ -4781,7 +4829,7 @@ var get_custom_beautifier_name = function(tag_check, raw_token) {
|
|
|
4781
4829
|
// For those without a type attribute use default;
|
|
4782
4830
|
if (typeAttribute.search('text/css') > -1) {
|
|
4783
4831
|
result = 'css';
|
|
4784
|
-
} else if (typeAttribute.search(/(text|application|dojo)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json|method|aspect)/) > -1) {
|
|
4832
|
+
} else if (typeAttribute.search(/module|((text|application|dojo)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json|method|aspect))/) > -1) {
|
|
4785
4833
|
result = 'javascript';
|
|
4786
4834
|
} else if (typeAttribute.search(/(text|application|dojo)\/(x-)?(html)/) > -1) {
|
|
4787
4835
|
result = 'html';
|
|
@@ -5168,10 +5216,12 @@ Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_to
|
|
|
5168
5216
|
var parser_token = this._get_tag_open_token(raw_token);
|
|
5169
5217
|
|
|
5170
5218
|
if ((last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) &&
|
|
5219
|
+
!last_tag_token.is_empty_element &&
|
|
5171
5220
|
raw_token.type === TOKEN.TAG_OPEN && raw_token.text.indexOf('</') === 0) {
|
|
5172
5221
|
// End element tags for unformatted or content_unformatted elements
|
|
5173
5222
|
// are printed raw to keep any newlines inside them exactly the same.
|
|
5174
5223
|
printer.add_raw_token(raw_token);
|
|
5224
|
+
parser_token.start_tag_token = this._tag_stack.try_pop(parser_token.tag_name);
|
|
5175
5225
|
} else {
|
|
5176
5226
|
printer.traverse_whitespace(raw_token);
|
|
5177
5227
|
this._set_tag_position(printer, raw_token, parser_token, last_tag_token, last_token);
|
|
@@ -5227,8 +5277,13 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
5227
5277
|
tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
|
|
5228
5278
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
5229
5279
|
} else {
|
|
5230
|
-
tag_check_match = raw_token.text.match(/^{{[
|
|
5280
|
+
tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
|
|
5231
5281
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
5282
|
+
|
|
5283
|
+
// handle "{{#> myPartial}}
|
|
5284
|
+
if (raw_token.text === '{{#>' && this.tag_check === '>' && raw_token.next !== null) {
|
|
5285
|
+
this.tag_check = raw_token.next.text;
|
|
5286
|
+
}
|
|
5232
5287
|
}
|
|
5233
5288
|
this.tag_check = this.tag_check.toLowerCase();
|
|
5234
5289
|
|
|
@@ -5275,12 +5330,8 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok
|
|
|
5275
5330
|
// and do an ending needed
|
|
5276
5331
|
if (this._do_optional_end_element(parser_token)) {
|
|
5277
5332
|
if (!parser_token.is_inline_element) {
|
|
5278
|
-
if (parser_token.parent) {
|
|
5279
|
-
parser_token.parent.multiline_content = true;
|
|
5280
|
-
}
|
|
5281
5333
|
printer.print_newline(false);
|
|
5282
5334
|
}
|
|
5283
|
-
|
|
5284
5335
|
}
|
|
5285
5336
|
|
|
5286
5337
|
this._tag_stack.record_tag(parser_token); //push it on the tag stack
|
|
@@ -5317,21 +5368,28 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok
|
|
|
5317
5368
|
if (parser_token.tag_name === '!--' && last_token.type === TOKEN.TAG_CLOSE &&
|
|
5318
5369
|
last_tag_token.is_end_tag && parser_token.text.indexOf('\n') === -1) {
|
|
5319
5370
|
//Do nothing. Leave comments on same line.
|
|
5320
|
-
} else
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
printer.print_newline(false);
|
|
5371
|
+
} else {
|
|
5372
|
+
if (!(parser_token.is_inline_element || parser_token.is_unformatted)) {
|
|
5373
|
+
printer.print_newline(false);
|
|
5374
|
+
}
|
|
5375
|
+
this._calcluate_parent_multiline(printer, parser_token);
|
|
5326
5376
|
}
|
|
5327
5377
|
} else if (parser_token.is_end_tag) { //this tag is a double tag so check for tag-ending
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
)
|
|
5378
|
+
var do_end_expand = false;
|
|
5379
|
+
|
|
5380
|
+
// deciding whether a block is multiline should not be this hard
|
|
5381
|
+
do_end_expand = parser_token.start_tag_token && parser_token.start_tag_token.multiline_content;
|
|
5382
|
+
do_end_expand = do_end_expand || (!parser_token.is_inline_element &&
|
|
5383
|
+
!(last_tag_token.is_inline_element || last_tag_token.is_unformatted) &&
|
|
5384
|
+
!(last_token.type === TOKEN.TAG_CLOSE && parser_token.start_tag_token === last_tag_token) &&
|
|
5385
|
+
last_token.type !== 'TK_CONTENT'
|
|
5386
|
+
);
|
|
5387
|
+
|
|
5388
|
+
if (parser_token.is_content_unformatted || parser_token.is_unformatted) {
|
|
5389
|
+
do_end_expand = false;
|
|
5390
|
+
}
|
|
5391
|
+
|
|
5392
|
+
if (do_end_expand) {
|
|
5335
5393
|
printer.print_newline(false);
|
|
5336
5394
|
}
|
|
5337
5395
|
} else { // it's a start-tag
|
|
@@ -5347,17 +5405,25 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok
|
|
|
5347
5405
|
}
|
|
5348
5406
|
}
|
|
5349
5407
|
|
|
5350
|
-
if (!parser_token.is_inline_element
|
|
5351
|
-
|
|
5352
|
-
parser_token.parent.multiline_content = true;
|
|
5353
|
-
}
|
|
5408
|
+
if (!(parser_token.is_inline_element || parser_token.is_unformatted) &&
|
|
5409
|
+
(last_token.type !== 'TK_CONTENT' || parser_token.is_content_unformatted)) {
|
|
5354
5410
|
printer.print_newline(false);
|
|
5355
5411
|
}
|
|
5412
|
+
|
|
5413
|
+
this._calcluate_parent_multiline(printer, parser_token);
|
|
5414
|
+
}
|
|
5415
|
+
};
|
|
5416
|
+
|
|
5417
|
+
Beautifier.prototype._calcluate_parent_multiline = function(printer, parser_token) {
|
|
5418
|
+
if (parser_token.parent && printer._output.just_added_newline() &&
|
|
5419
|
+
!((parser_token.is_inline_element || parser_token.is_unformatted) && parser_token.parent.is_inline_element)) {
|
|
5420
|
+
parser_token.parent.multiline_content = true;
|
|
5356
5421
|
}
|
|
5357
5422
|
};
|
|
5358
5423
|
|
|
5359
5424
|
//To be used for <p> tag special case:
|
|
5360
|
-
|
|
5425
|
+
var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'];
|
|
5426
|
+
var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video'];
|
|
5361
5427
|
|
|
5362
5428
|
Beautifier.prototype._do_optional_end_element = function(parser_token) {
|
|
5363
5429
|
var result = null;
|
|
@@ -5368,7 +5434,9 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
|
|
|
5368
5434
|
if (parser_token.is_empty_element || !parser_token.is_start_tag || !parser_token.parent) {
|
|
5369
5435
|
return;
|
|
5370
5436
|
|
|
5371
|
-
}
|
|
5437
|
+
}
|
|
5438
|
+
|
|
5439
|
+
if (parser_token.tag_name === 'body') {
|
|
5372
5440
|
// A head element’s end tag may be omitted if the head element is not immediately followed by a space character or a comment.
|
|
5373
5441
|
result = result || this._tag_stack.try_pop('head');
|
|
5374
5442
|
|
|
@@ -5385,11 +5453,16 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
|
|
|
5385
5453
|
result = result || this._tag_stack.try_pop('dt', ['dl']);
|
|
5386
5454
|
result = result || this._tag_stack.try_pop('dd', ['dl']);
|
|
5387
5455
|
|
|
5388
|
-
//} else if (p_closers.indexOf(parser_token.tag_name) !== -1) {
|
|
5389
|
-
//TODO: THIS IS A BUG FARM. We are not putting this into 1.8.0 as it is likely to blow up.
|
|
5390
|
-
//A p element’s end tag may be omitted if the p element is immediately followed by an address, article, aside, blockquote, details, div, dl, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hr, main, nav, ol, p, pre, section, table, or ul element, or if there is no more content in the parent element and the parent element is an HTML element that is not an a, audio, del, ins, map, noscript, or video element, or an autonomous custom element.
|
|
5391
|
-
//result = result || this._tag_stack.try_pop('p', ['body']);
|
|
5392
5456
|
|
|
5457
|
+
} else if (parser_token.parent.tag_name === 'p' && p_closers.indexOf(parser_token.tag_name) !== -1) {
|
|
5458
|
+
// IMPORTANT: this else-if works because p_closers has no overlap with any other element we look for in this method
|
|
5459
|
+
// check for the parent element is an HTML element that is not an <a>, <audio>, <del>, <ins>, <map>, <noscript>, or <video> element, or an autonomous custom element.
|
|
5460
|
+
// To do this right, this needs to be coded as an inclusion of the inverse of the exclusion above.
|
|
5461
|
+
// But to start with (if we ignore "autonomous custom elements") the exclusion would be fine.
|
|
5462
|
+
var p_parent = parser_token.parent.parent;
|
|
5463
|
+
if (!p_parent || p_parent_excludes.indexOf(p_parent.tag_name) === -1) {
|
|
5464
|
+
result = result || this._tag_stack.try_pop('p');
|
|
5465
|
+
}
|
|
5393
5466
|
} else if (parser_token.tag_name === 'rp' || parser_token.tag_name === 'rt') {
|
|
5394
5467
|
// An rt element’s end tag may be omitted if the rt element is immediately followed by an rt or rp element, or if there is no more content in the parent element.
|
|
5395
5468
|
// An rp element’s end tag may be omitted if the rp element is immediately followed by an rt or rp element, or if there is no more content in the parent element.
|
|
@@ -5689,8 +5762,8 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { //
|
|
|
5689
5762
|
|
|
5690
5763
|
token = token || this._read_open_handlebars(c, open_token);
|
|
5691
5764
|
token = token || this._read_attribute(c, previous_token, open_token);
|
|
5692
|
-
token = token || this._read_raw_content(c, previous_token, open_token);
|
|
5693
5765
|
token = token || this._read_close(c, open_token);
|
|
5766
|
+
token = token || this._read_raw_content(c, previous_token, open_token);
|
|
5694
5767
|
token = token || this._read_content_word(c);
|
|
5695
5768
|
token = token || this._read_comment_or_cdata(c);
|
|
5696
5769
|
token = token || this._read_processing(c);
|
|
@@ -5853,7 +5926,9 @@ Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token)
|
|
|
5853
5926
|
var resulting_string = '';
|
|
5854
5927
|
if (open_token && open_token.text[0] === '{') {
|
|
5855
5928
|
resulting_string = this.__patterns.handlebars_raw_close.read();
|
|
5856
|
-
} else if (previous_token.type === TOKEN.TAG_CLOSE &&
|
|
5929
|
+
} else if (previous_token.type === TOKEN.TAG_CLOSE &&
|
|
5930
|
+
previous_token.opened.text[0] === '<' && previous_token.text[0] !== '/') {
|
|
5931
|
+
// ^^ empty tag has no content
|
|
5857
5932
|
var tag_name = previous_token.opened.text.substr(1).toLowerCase();
|
|
5858
5933
|
if (tag_name === 'script' || tag_name === 'style') {
|
|
5859
5934
|
// Script and style tags are allowed to have comments wrapping their content
|
|
@@ -5865,6 +5940,7 @@ Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token)
|
|
|
5865
5940
|
}
|
|
5866
5941
|
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
|
5867
5942
|
} else if (this._is_content_unformatted(tag_name)) {
|
|
5943
|
+
|
|
5868
5944
|
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
|
5869
5945
|
}
|
|
5870
5946
|
}
|