@bmewburn/js-beautify 1.13.0 → 1.14.7-next1
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 +58 -30
- package/js/src/cli.js +16 -4
- package/js/src/core/options.js +2 -2
- package/js/src/core/templatablepattern.js +23 -3
- package/js/src/css/beautifier.js +62 -14
- package/js/src/html/beautifier.js +21 -8
- package/js/src/javascript/beautifier.js +35 -18
- package/js/src/javascript/tokenizer.js +21 -6
- package/package.json +19 -14
- package/CHANGELOG.md +0 -877
package/README.md
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
[](https://dev.azure.com/beautifier-io/js-beautify/_build/latest?definitionId=1)
|
|
1
|
+
<p align="center"><img src="https://raw.githubusercontent.com/beautify-web/js-beautify/7db71fc/web/wordmark-light.svg" height="200px" align="center" alt="JS Beautifier"/></p>
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
[](https://cdnjs.com/libraries/js-beautify)
|
|
6
|
-
[](https://www.npmjs.com/package/js-beautify)
|
|
7
|
-
[](https://www.npmjs.com/package/js-beautify?activeTab=versions)
|
|
3
|
+
<p align="center"><a href="https://github.com/beautify-web/js-beautify/actions/workflows/main.yml"><img alt="CI" src="https://github.com/beautify-web/js-beautify/workflows/CI/badge.svg"/></a> <a href="https://greenkeeper.io/" target="_blank"><img alt="Greenkeeper badge" src="https://badges.greenkeeper.io/beautify-web/js-beautify.svg"/></a></p>
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
[](https://twitter.com/intent/user?screen_name=js_beautifier)
|
|
5
|
+
<p align="center"><a href="https://pypi.python.org/pypi/jsbeautifier" target="_blank"><img alt="PyPI version" src="https://img.shields.io/pypi/v/jsbeautifier.svg"/></a> <a href="https://cdnjs.com/libraries/js-beautify" target="_blank"><img alt="CDNJS version" src="https://img.shields.io/cdnjs/v/js-beautify.svg"/></a> <a href="https://www.npmjs.com/package/js-beautify" target="_blank"><img alt="NPM @latest" src="https://img.shields.io/npm/v/js-beautify.svg"/></a> <a href="https://www.npmjs.com/package/js-beautify?activeTab=versions" target="_blank"><img alt="NPM @next" src="https://img.shields.io/npm/v/js-beautify/next.svg"/></a></p>
|
|
11
6
|
|
|
12
|
-
|
|
7
|
+
<p align="center"><a href="https://gitter.im/beautify-web/js-beautify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank"><img alt="Join the chat at https://gitter.im/beautify-web/js-beautify" src="https://badges.gitter.im/Join%20Chat.svg"></a> <a href="https://twitter.com/intent/user?screen_name=js_beautifier" target="_blank"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/js_beautifier.svg?style=social&label=Follow"/></a></p>
|
|
13
8
|
|
|
9
|
+
<p align="center"><a href="https://www.npmjs.org/package/js-beautify" target="_blank"><img alt="NPM stats" src=https://nodei.co/npm/js-beautify.svg?downloadRank=true&downloads=true"/></a></p>
|
|
14
10
|
|
|
15
11
|
This little beautifier will reformat and re-indent bookmarklets, ugly
|
|
16
12
|
JavaScript, unpack scripts packed by Dean Edward’s popular packer,
|
|
@@ -19,17 +15,18 @@ as well as partly deobfuscate scripts processed by the npm package
|
|
|
19
15
|
|
|
20
16
|
Open [beautifier.io](https://beautifier.io/) to try it out. Options are available via the UI.
|
|
21
17
|
|
|
18
|
+
|
|
22
19
|
# Contributors Needed
|
|
23
20
|
I'm putting this front and center above because existing owners have very limited time to work on this project currently.
|
|
24
21
|
This is a popular project and widely used but it desperately needs contributors who have time to commit to fixing both
|
|
25
22
|
customer facing bugs and underlying problems with the internal design and implementation.
|
|
26
23
|
|
|
27
|
-
If you are interested, please take a look at the [CONTRIBUTING.md](https://github.com/beautify-web/js-beautify/blob/
|
|
24
|
+
If you are interested, please take a look at the [CONTRIBUTING.md](https://github.com/beautify-web/js-beautify/blob/main/CONTRIBUTING.md) then fix an issue marked with the ["Good first issue"](https://github.com/beautify-web/js-beautify/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label and submit a PR. Repeat as often as possible. Thanks!
|
|
28
25
|
|
|
29
26
|
|
|
30
27
|
# Installation
|
|
31
28
|
|
|
32
|
-
You can install the beautifier for
|
|
29
|
+
You can install the beautifier for Node.js or Python.
|
|
33
30
|
|
|
34
31
|
## Node.js JavaScript
|
|
35
32
|
|
|
@@ -61,19 +58,29 @@ JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries
|
|
|
61
58
|
|
|
62
59
|
To pull the latest version from one of these services include one set of the script tags below in your document:
|
|
63
60
|
```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.
|
|
67
|
-
|
|
68
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.0/beautify.min.js"></script>
|
|
69
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.0/beautify-css.min.js"></script>
|
|
70
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.13.0/beautify-html.min.js"></script>
|
|
61
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify.js"></script>
|
|
62
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify-css.js"></script>
|
|
63
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify-html.js"></script>
|
|
71
64
|
|
|
72
|
-
<script src="https://
|
|
73
|
-
<script src="https://
|
|
74
|
-
<script src="https://
|
|
65
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify.min.js"></script>
|
|
66
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify-css.min.js"></script>
|
|
67
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify-html.min.js"></script>
|
|
75
68
|
```
|
|
76
69
|
|
|
70
|
+
Example usage of a JS tag in html:
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<!DOCTYPE html>
|
|
74
|
+
<html lang="en">
|
|
75
|
+
<body>
|
|
76
|
+
|
|
77
|
+
. . .
|
|
78
|
+
|
|
79
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.7/beautify.min.js"></script>
|
|
80
|
+
<script src="script.js"></script>
|
|
81
|
+
</body>
|
|
82
|
+
</html>
|
|
83
|
+
```
|
|
77
84
|
Older versions are available by changing the version number.
|
|
78
85
|
|
|
79
86
|
Disclaimer: These are free services, so there are [no uptime or support guarantees](https://github.com/rgrove/rawgit/wiki/Frequently-Asked-Questions#i-need-guaranteed-100-uptime-should-i-use-cdnrawgitcom).
|
|
@@ -92,13 +99,34 @@ $ pip install cssbeautifier
|
|
|
92
99
|
```
|
|
93
100
|
|
|
94
101
|
# Usage
|
|
95
|
-
You can beautify
|
|
102
|
+
You can beautify JavaScript using JS Beautifier in your web browser, or on the command-line using Node.js or Python.
|
|
96
103
|
|
|
97
104
|
## Web Browser
|
|
98
105
|
Open [beautifier.io](https://beautifier.io/). Options are available via the UI.
|
|
99
106
|
|
|
100
107
|
## Web Library
|
|
101
|
-
|
|
108
|
+
After you embed the `<script>` tags in your `html` file, they expose three functions: `js_beautify`, `css_beautify`, and `html_beautify`
|
|
109
|
+
|
|
110
|
+
Example usage of beautifying a json string:
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
const options = { indent_size: 2, space_in_empty_paren: true }
|
|
114
|
+
|
|
115
|
+
const dataObj = {completed: false,id: 1,title: "delectus aut autem",userId: 1,}
|
|
116
|
+
|
|
117
|
+
const dataJson = JSON.stringify(dataObj)
|
|
118
|
+
|
|
119
|
+
js_beautify(dataJson, options)
|
|
120
|
+
|
|
121
|
+
/* OUTPUT
|
|
122
|
+
{
|
|
123
|
+
"completed": false,
|
|
124
|
+
"id": 1,
|
|
125
|
+
"title": "delectus aut autem",
|
|
126
|
+
"userId": 1,
|
|
127
|
+
}
|
|
128
|
+
*/
|
|
129
|
+
```
|
|
102
130
|
|
|
103
131
|
## Node.js JavaScript
|
|
104
132
|
|
|
@@ -108,7 +136,7 @@ When installed globally, the beautifier provides an executable `js-beautify` scr
|
|
|
108
136
|
$ js-beautify foo.js
|
|
109
137
|
```
|
|
110
138
|
|
|
111
|
-
To use `js-beautify` as a `node` library (after install locally), import and call the appropriate beautifier method for
|
|
139
|
+
To use `js-beautify` as a `node` library (after install locally), import and call the appropriate beautifier method for JavaScript (JS), CSS, or HTML. All three method signatures are `beautify(code, options)`. `code` is the string of code to be beautified. options is an object with the settings you would like used to beautify the code.
|
|
112
140
|
|
|
113
141
|
The configuration option names are the same as the CLI names but with underscores instead of dashes. For example, `--indent-size 2 --space-in-empty-paren` would be `{ indent_size: 2, space_in_empty_paren: true }`.
|
|
114
142
|
|
|
@@ -137,7 +165,7 @@ To use `jsbeautifier` as a library is simple:
|
|
|
137
165
|
|
|
138
166
|
```python
|
|
139
167
|
import jsbeautifier
|
|
140
|
-
res = jsbeautifier.beautify('your
|
|
168
|
+
res = jsbeautifier.beautify('your JavaScript string')
|
|
141
169
|
res = jsbeautifier.beautify_file('some_file.js')
|
|
142
170
|
```
|
|
143
171
|
|
|
@@ -147,7 +175,7 @@ res = jsbeautifier.beautify_file('some_file.js')
|
|
|
147
175
|
opts = jsbeautifier.default_options()
|
|
148
176
|
opts.indent_size = 2
|
|
149
177
|
opts.space_in_empty_paren = True
|
|
150
|
-
res = jsbeautifier.beautify('some
|
|
178
|
+
res = jsbeautifier.beautify('some JavaScript', opts)
|
|
151
179
|
```
|
|
152
180
|
|
|
153
181
|
The configuration option names are the same as the CLI names but with underscores instead of dashes. The example above would be set on the command-line as `--indent-size 2 --space-in-empty-paren`.
|
|
@@ -195,7 +223,7 @@ Beautifier Options:
|
|
|
195
223
|
-C, --comma-first Put commas at the beginning of new line instead of end
|
|
196
224
|
-O, --operator-position Set operator position (before-newline|after-newline|preserve-newline) [before-newline]
|
|
197
225
|
--indent-empty-lines Keep indentation on empty lines
|
|
198
|
-
--templating List of templating languages (auto,django,erb,handlebars,php) ["auto"] auto = none in JavaScript, all in
|
|
226
|
+
--templating List of templating languages (auto,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in HTML
|
|
199
227
|
```
|
|
200
228
|
|
|
201
229
|
Which correspond to the underscored option keys for both library interfaces
|
|
@@ -258,7 +286,7 @@ Configuration sources provided earlier in this stack will override later ones.
|
|
|
258
286
|
|
|
259
287
|
The settings are a shallow tree whose values are inherited for all languages, but
|
|
260
288
|
can be overridden. This works for settings passed directly to the API in either implementation.
|
|
261
|
-
In the
|
|
289
|
+
In the JavaScript implementation, settings loaded from a config file, such as .jsbeautifyrc, can also use inheritance/overriding.
|
|
262
290
|
|
|
263
291
|
Below is an example configuration tree showing all the supported locations
|
|
264
292
|
for language override nodes. We'll use `indent_size` to discuss how this configuration would behave, but any number of settings can be inherited or overridden:
|
|
@@ -349,7 +377,7 @@ HTML Beautifier Options:
|
|
|
349
377
|
--indent_scripts Sets indent level inside script tags ("normal", "keep", "separate")
|
|
350
378
|
--unformatted_content_delimiter Keep text content together between this string [""]
|
|
351
379
|
--indent-empty-lines Keep indentation on empty lines
|
|
352
|
-
--templating List of templating languages (auto,none,django,erb,handlebars,php) ["auto"] auto = none in JavaScript, all in html
|
|
380
|
+
--templating List of templating languages (auto,none,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in html
|
|
353
381
|
```
|
|
354
382
|
|
|
355
383
|
## Directives
|
|
@@ -404,4 +432,4 @@ Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, D
|
|
|
404
432
|
Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
|
|
405
433
|
Mathias Bynens, Vittorio Gambaletta and others.
|
|
406
434
|
|
|
407
|
-
(README.md: js-beautify@1.
|
|
435
|
+
(README.md: js-beautify@1.14.7)
|
package/js/src/cli.js
CHANGED
|
@@ -40,7 +40,6 @@ var debug = process.env.DEBUG_JSBEAUTIFY || process.env.JSBEAUTIFY_DEBUG ? funct
|
|
|
40
40
|
var fs = require('fs'),
|
|
41
41
|
cc = require('config-chain'),
|
|
42
42
|
beautify = require('../index'),
|
|
43
|
-
mkdirp = require('mkdirp'),
|
|
44
43
|
nopt = require('nopt'),
|
|
45
44
|
glob = require('glob');
|
|
46
45
|
|
|
@@ -64,6 +63,19 @@ nopt.typeDefs.brace_style = {
|
|
|
64
63
|
return true;
|
|
65
64
|
}
|
|
66
65
|
};
|
|
66
|
+
nopt.typeDefs.glob = {
|
|
67
|
+
type: "glob",
|
|
68
|
+
validate: function(data, key, val) {
|
|
69
|
+
if (typeof val === 'string' && glob.hasMagic(val)) {
|
|
70
|
+
// Preserve value if it contains glob magic
|
|
71
|
+
data[key] = val;
|
|
72
|
+
return true;
|
|
73
|
+
} else {
|
|
74
|
+
// Otherwise validate it as regular path
|
|
75
|
+
return nopt.typeDefs.path.validate(data, key, val);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
67
79
|
var path = require('path'),
|
|
68
80
|
editorconfig = require('editorconfig'),
|
|
69
81
|
knownOpts = {
|
|
@@ -113,7 +125,7 @@ var path = require('path'),
|
|
|
113
125
|
// CLI
|
|
114
126
|
"version": Boolean,
|
|
115
127
|
"help": Boolean,
|
|
116
|
-
"files": [
|
|
128
|
+
"files": ["glob", Array],
|
|
117
129
|
"outfile": path,
|
|
118
130
|
"replace": Boolean,
|
|
119
131
|
"quiet": Boolean,
|
|
@@ -351,7 +363,7 @@ function usage(err) {
|
|
|
351
363
|
' [first newline in file, otherwise "\\n]',
|
|
352
364
|
' -n, --end-with-newline End output with newline',
|
|
353
365
|
' --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',
|
|
366
|
+
' --templating List of templating languages (auto,none,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in html',
|
|
355
367
|
' --editorconfig Use EditorConfig to set up the options'
|
|
356
368
|
];
|
|
357
369
|
|
|
@@ -485,7 +497,7 @@ function writePretty(err, pretty, outfile, config) {
|
|
|
485
497
|
}
|
|
486
498
|
|
|
487
499
|
if (outfile) {
|
|
488
|
-
|
|
500
|
+
fs.mkdirSync(path.dirname(outfile), { recursive: true });
|
|
489
501
|
|
|
490
502
|
if (isFileDifferent(outfile, pretty)) {
|
|
491
503
|
try {
|
package/js/src/core/options.js
CHANGED
|
@@ -67,10 +67,10 @@ function Options(options, merge_child_field) {
|
|
|
67
67
|
|
|
68
68
|
this.indent_empty_lines = this._get_boolean('indent_empty_lines');
|
|
69
69
|
|
|
70
|
-
// valid templating languages ['django', 'erb', 'handlebars', 'php']
|
|
70
|
+
// valid templating languages ['django', 'erb', 'handlebars', 'php', 'smarty']
|
|
71
71
|
// For now, 'auto' = all off for javascript, all on for html (and inline javascript).
|
|
72
72
|
// other values ignored
|
|
73
|
-
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
|
|
73
|
+
this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php', 'smarty'], ['auto']);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
Options.prototype._get_array = function(name, default_value) {
|
|
@@ -35,7 +35,8 @@ var template_names = {
|
|
|
35
35
|
django: false,
|
|
36
36
|
erb: false,
|
|
37
37
|
handlebars: false,
|
|
38
|
-
php: false
|
|
38
|
+
php: false,
|
|
39
|
+
smarty: false
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
// This lets templates appear anywhere we would do a readUntil
|
|
@@ -56,12 +57,15 @@ function TemplatablePattern(input_scanner, parent) {
|
|
|
56
57
|
handlebars_comment: pattern.starting_with(/{{!--/).until_after(/--}}/),
|
|
57
58
|
handlebars_unescaped: pattern.starting_with(/{{{/).until_after(/}}}/),
|
|
58
59
|
handlebars: pattern.starting_with(/{{/).until_after(/}}/),
|
|
59
|
-
php: pattern.starting_with(/<\?(?:[=]|php)/).until_after(/\?>/),
|
|
60
|
+
php: pattern.starting_with(/<\?(?:[= ]|php)/).until_after(/\?>/),
|
|
60
61
|
erb: pattern.starting_with(/<%[^%]/).until_after(/[^%]%>/),
|
|
61
62
|
// django coflicts with handlebars a bit.
|
|
62
63
|
django: pattern.starting_with(/{%/).until_after(/%}/),
|
|
63
64
|
django_value: pattern.starting_with(/{{/).until_after(/}}/),
|
|
64
|
-
django_comment: pattern.starting_with(/{#/).until_after(/#}/)
|
|
65
|
+
django_comment: pattern.starting_with(/{#/).until_after(/#}/),
|
|
66
|
+
smarty: pattern.starting_with(/{(?=[^}{\s\n])/).until_after(/[^\s\n]}/),
|
|
67
|
+
smarty_comment: pattern.starting_with(/{\*/).until_after(/\*}/),
|
|
68
|
+
smarty_literal: pattern.starting_with(/{literal}/).until_after(/{\/literal}/)
|
|
65
69
|
};
|
|
66
70
|
}
|
|
67
71
|
TemplatablePattern.prototype = new Pattern();
|
|
@@ -135,9 +139,14 @@ TemplatablePattern.prototype.__set_templated_pattern = function() {
|
|
|
135
139
|
}
|
|
136
140
|
if (!this._disabled.django) {
|
|
137
141
|
items.push(this.__patterns.django._starting_pattern.source);
|
|
142
|
+
// The starting pattern for django is more complex because it has different
|
|
143
|
+
// patterns for value, comment, and other sections
|
|
138
144
|
items.push(this.__patterns.django_value._starting_pattern.source);
|
|
139
145
|
items.push(this.__patterns.django_comment._starting_pattern.source);
|
|
140
146
|
}
|
|
147
|
+
if (!this._disabled.smarty) {
|
|
148
|
+
items.push(this.__patterns.smarty._starting_pattern.source);
|
|
149
|
+
}
|
|
141
150
|
|
|
142
151
|
if (this._until_pattern) {
|
|
143
152
|
items.push(this._until_pattern.source);
|
|
@@ -183,6 +192,17 @@ TemplatablePattern.prototype._read_template = function() {
|
|
|
183
192
|
this.__patterns.django.read();
|
|
184
193
|
}
|
|
185
194
|
}
|
|
195
|
+
if (!this._disabled.smarty) {
|
|
196
|
+
// smarty cannot be enabled with django or handlebars enabled
|
|
197
|
+
if (this._disabled.django && this._disabled.handlebars) {
|
|
198
|
+
resulting_string = resulting_string ||
|
|
199
|
+
this.__patterns.smarty_comment.read();
|
|
200
|
+
resulting_string = resulting_string ||
|
|
201
|
+
this.__patterns.smarty_literal.read();
|
|
202
|
+
resulting_string = resulting_string ||
|
|
203
|
+
this.__patterns.smarty.read();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
186
206
|
}
|
|
187
207
|
return resulting_string;
|
|
188
208
|
};
|
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
|
|
|
@@ -91,13 +95,12 @@ Beautifier.prototype.eatString = function(endChars) {
|
|
|
91
95
|
// the first newline will be output
|
|
92
96
|
Beautifier.prototype.eatWhitespace = function(allowAtLeastOneNewLine) {
|
|
93
97
|
var result = whitespaceChar.test(this._input.peek());
|
|
94
|
-
var
|
|
95
|
-
|
|
98
|
+
var newline_count = 0;
|
|
96
99
|
while (whitespaceChar.test(this._input.peek())) {
|
|
97
100
|
this._ch = this._input.next();
|
|
98
101
|
if (allowAtLeastOneNewLine && this._ch === '\n') {
|
|
99
|
-
if (this._options.
|
|
100
|
-
|
|
102
|
+
if (newline_count === 0 || newline_count < this._options.max_preserve_newlines) {
|
|
103
|
+
newline_count++;
|
|
101
104
|
this._output.add_new_line(true);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
@@ -192,7 +195,9 @@ Beautifier.prototype.beautify = function() {
|
|
|
192
195
|
var enteringConditionalGroup = false;
|
|
193
196
|
var insideAtExtend = false;
|
|
194
197
|
var insideAtImport = false;
|
|
198
|
+
var insideScssMap = false;
|
|
195
199
|
var topCharacter = this._ch;
|
|
200
|
+
var insideNonSemiColonValues = false;
|
|
196
201
|
var whitespace;
|
|
197
202
|
var isAfterSpace;
|
|
198
203
|
var previous_ch;
|
|
@@ -244,7 +249,7 @@ Beautifier.prototype.beautify = function() {
|
|
|
244
249
|
|
|
245
250
|
// Ensures any new lines following the comment are preserved
|
|
246
251
|
this.eatWhitespace(true);
|
|
247
|
-
} else if (this._ch === '@') {
|
|
252
|
+
} else if (this._ch === '@' || this._ch === '$') {
|
|
248
253
|
this.preserveSingleSpace(isAfterSpace);
|
|
249
254
|
|
|
250
255
|
// deal with less propery mixins @{...}
|
|
@@ -315,7 +320,12 @@ Beautifier.prototype.beautify = function() {
|
|
|
315
320
|
this.indent();
|
|
316
321
|
this._output.set_indent(this._indentLevel);
|
|
317
322
|
} else {
|
|
318
|
-
|
|
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
|
+
}
|
|
319
329
|
this.print_string(this._ch);
|
|
320
330
|
}
|
|
321
331
|
|
|
@@ -347,7 +357,21 @@ Beautifier.prototype.beautify = function() {
|
|
|
347
357
|
this._output.add_new_line(true);
|
|
348
358
|
}
|
|
349
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
|
+
}
|
|
350
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
|
+
|
|
351
375
|
if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) {
|
|
352
376
|
// 'property: value' delimiter
|
|
353
377
|
// which could be in a conditional group query
|
|
@@ -376,10 +400,12 @@ Beautifier.prototype.beautify = function() {
|
|
|
376
400
|
}
|
|
377
401
|
}
|
|
378
402
|
} else if (this._ch === '"' || this._ch === '\'') {
|
|
379
|
-
|
|
403
|
+
var preserveQuoteSpace = previous_ch === '"' || previous_ch === '\'';
|
|
404
|
+
this.preserveSingleSpace(preserveQuoteSpace || isAfterSpace);
|
|
380
405
|
this.print_string(this._ch + this.eatString(this._ch));
|
|
381
406
|
this.eatWhitespace(true);
|
|
382
407
|
} else if (this._ch === ';') {
|
|
408
|
+
insideNonSemiColonValues = false;
|
|
383
409
|
if (parenLevel === 0) {
|
|
384
410
|
if (insidePropertyValue) {
|
|
385
411
|
this.outdent();
|
|
@@ -419,22 +445,39 @@ Beautifier.prototype.beautify = function() {
|
|
|
419
445
|
}
|
|
420
446
|
}
|
|
421
447
|
} else {
|
|
422
|
-
|
|
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);
|
|
423
454
|
this.print_string(this._ch);
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
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
|
+
}
|
|
427
465
|
}
|
|
428
466
|
} else if (this._ch === ')') {
|
|
429
467
|
if (parenLevel) {
|
|
430
468
|
parenLevel--;
|
|
431
469
|
this.outdent();
|
|
432
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
|
+
}
|
|
433
476
|
this.print_string(this._ch);
|
|
434
477
|
} else if (this._ch === ',') {
|
|
435
478
|
this.print_string(this._ch);
|
|
436
479
|
this.eatWhitespace(true);
|
|
437
|
-
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel === 0 && !insideAtImport) {
|
|
480
|
+
if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) {
|
|
438
481
|
this._output.add_new_line();
|
|
439
482
|
} else {
|
|
440
483
|
this._output.space_before_token = true;
|
|
@@ -465,11 +508,16 @@ Beautifier.prototype.beautify = function() {
|
|
|
465
508
|
this._ch = '';
|
|
466
509
|
}
|
|
467
510
|
} else if (this._ch === '!' && !this._input.lookBack("\\")) { // !important
|
|
468
|
-
this.
|
|
511
|
+
this._output.space_before_token = true;
|
|
469
512
|
this.print_string(this._ch);
|
|
470
513
|
} else {
|
|
471
|
-
|
|
514
|
+
var preserveAfterSpace = previous_ch === '"' || previous_ch === '\'';
|
|
515
|
+
this.preserveSingleSpace(preserveAfterSpace || isAfterSpace);
|
|
472
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
|
+
}
|
|
473
521
|
}
|
|
474
522
|
}
|
|
475
523
|
|
|
@@ -615,14 +615,19 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
615
615
|
tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
|
|
616
616
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
617
617
|
} else {
|
|
618
|
-
tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
|
|
618
|
+
tag_check_match = raw_token.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/);
|
|
619
619
|
this.tag_check = tag_check_match ? tag_check_match[1] : '';
|
|
620
620
|
|
|
621
|
-
// handle "{{#> myPartial}}
|
|
622
|
-
if (raw_token.text
|
|
623
|
-
this.tag_check
|
|
621
|
+
// handle "{{#> myPartial}}" or "{{~#> myPartial}}"
|
|
622
|
+
if ((raw_token.text.startsWith('{{#>') || raw_token.text.startsWith('{{~#>')) && this.tag_check[0] === '>') {
|
|
623
|
+
if (this.tag_check === '>' && raw_token.next !== null) {
|
|
624
|
+
this.tag_check = raw_token.next.text.split(' ')[0];
|
|
625
|
+
} else {
|
|
626
|
+
this.tag_check = raw_token.text.split('>')[1];
|
|
627
|
+
}
|
|
624
628
|
}
|
|
625
629
|
}
|
|
630
|
+
|
|
626
631
|
this.tag_check = this.tag_check.toLowerCase();
|
|
627
632
|
|
|
628
633
|
if (raw_token.type === TOKEN.COMMENT) {
|
|
@@ -634,9 +639,17 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|
|
634
639
|
this.is_end_tag = !this.is_start_tag ||
|
|
635
640
|
(raw_token.closed && raw_token.closed.text === '/>');
|
|
636
641
|
|
|
642
|
+
// if whitespace handler ~ included (i.e. {{~#if true}}), handlebars tags start at pos 3 not pos 2
|
|
643
|
+
var handlebar_starts = 2;
|
|
644
|
+
if (this.tag_start_char === '{' && this.text.length >= 3) {
|
|
645
|
+
if (this.text.charAt(2) === '~') {
|
|
646
|
+
handlebar_starts = 3;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
637
650
|
// handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
|
|
638
651
|
this.is_end_tag = this.is_end_tag ||
|
|
639
|
-
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(
|
|
652
|
+
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
|
|
640
653
|
}
|
|
641
654
|
};
|
|
642
655
|
|
|
@@ -653,7 +666,7 @@ Beautifier.prototype._get_tag_open_token = function(raw_token) { //function to g
|
|
|
653
666
|
|
|
654
667
|
parser_token.is_unformatted = !parser_token.tag_complete && in_array(parser_token.tag_check, this._options.unformatted);
|
|
655
668
|
parser_token.is_content_unformatted = !parser_token.is_empty_element && in_array(parser_token.tag_check, this._options.content_unformatted);
|
|
656
|
-
parser_token.is_inline_element = in_array(parser_token.tag_name, this._options.inline) || parser_token.tag_start_char === '{';
|
|
669
|
+
parser_token.is_inline_element = in_array(parser_token.tag_name, this._options.inline) || parser_token.tag_name.includes("-") || parser_token.tag_start_char === '{';
|
|
657
670
|
|
|
658
671
|
return parser_token;
|
|
659
672
|
};
|
|
@@ -760,7 +773,7 @@ Beautifier.prototype._calcluate_parent_multiline = function(printer, parser_toke
|
|
|
760
773
|
};
|
|
761
774
|
|
|
762
775
|
//To be used for <p> tag special case:
|
|
763
|
-
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'];
|
|
776
|
+
var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'];
|
|
764
777
|
var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video'];
|
|
765
778
|
|
|
766
779
|
Beautifier.prototype._do_optional_end_element = function(parser_token) {
|
|
@@ -783,7 +796,7 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
|
|
|
783
796
|
|
|
784
797
|
} else if (parser_token.tag_name === 'li') {
|
|
785
798
|
// An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element.
|
|
786
|
-
result = result || this._tag_stack.try_pop('li', ['ol', 'ul']);
|
|
799
|
+
result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']);
|
|
787
800
|
|
|
788
801
|
} else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') {
|
|
789
802
|
// A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element.
|