js-beautify 1.14.3 → 1.14.6

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 CHANGED
@@ -26,7 +26,7 @@ If you are interested, please take a look at the [CONTRIBUTING.md](https://githu
26
26
 
27
27
  # Installation
28
28
 
29
- You can install the beautifier for node.js or python.
29
+ You can install the beautifier for Node.js or Python.
30
30
 
31
31
  ## Node.js JavaScript
32
32
 
@@ -58,17 +58,13 @@ JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries
58
58
 
59
59
  To pull the latest version from one of these services include one set of the script tags below in your document:
60
60
  ```html
61
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify.js"></script>
62
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-css.js"></script>
63
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-html.js"></script>
61
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.6/beautify.js"></script>
62
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.6/beautify-css.js"></script>
63
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.6/beautify-html.js"></script>
64
64
 
65
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify.min.js"></script>
66
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-css.min.js"></script>
67
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.3/beautify-html.min.js"></script>
68
-
69
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.3/js/lib/beautify.js"></script>
70
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.3/js/lib/beautify-css.js"></script>
71
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.14.3/js/lib/beautify-html.js"></script>
65
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.6/beautify.min.js"></script>
66
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.6/beautify-css.min.js"></script>
67
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.6/beautify-html.min.js"></script>
72
68
  ```
73
69
 
74
70
  Older versions are available by changing the version number.
@@ -89,7 +85,7 @@ $ pip install cssbeautifier
89
85
  ```
90
86
 
91
87
  # Usage
92
- You can beautify javascript using JS Beautifier in your web browser, or on the command-line using node.js or python.
88
+ You can beautify JavaScript using JS Beautifier in your web browser, or on the command-line using Node.js or Python.
93
89
 
94
90
  ## Web Browser
95
91
  Open [beautifier.io](https://beautifier.io/). Options are available via the UI.
@@ -105,7 +101,7 @@ When installed globally, the beautifier provides an executable `js-beautify` scr
105
101
  $ js-beautify foo.js
106
102
  ```
107
103
 
108
- 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.
104
+ 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.
109
105
 
110
106
  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 }`.
111
107
 
@@ -134,7 +130,7 @@ To use `jsbeautifier` as a library is simple:
134
130
 
135
131
  ```python
136
132
  import jsbeautifier
137
- res = jsbeautifier.beautify('your javascript string')
133
+ res = jsbeautifier.beautify('your JavaScript string')
138
134
  res = jsbeautifier.beautify_file('some_file.js')
139
135
  ```
140
136
 
@@ -144,7 +140,7 @@ res = jsbeautifier.beautify_file('some_file.js')
144
140
  opts = jsbeautifier.default_options()
145
141
  opts.indent_size = 2
146
142
  opts.space_in_empty_paren = True
147
- res = jsbeautifier.beautify('some javascript', opts)
143
+ res = jsbeautifier.beautify('some JavaScript', opts)
148
144
  ```
149
145
 
150
146
  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`.
@@ -192,7 +188,7 @@ Beautifier Options:
192
188
  -C, --comma-first Put commas at the beginning of new line instead of end
193
189
  -O, --operator-position Set operator position (before-newline|after-newline|preserve-newline) [before-newline]
194
190
  --indent-empty-lines Keep indentation on empty lines
195
- --templating List of templating languages (auto,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in html
191
+ --templating List of templating languages (auto,django,erb,handlebars,php,smarty) ["auto"] auto = none in JavaScript, all in HTML
196
192
  ```
197
193
 
198
194
  Which correspond to the underscored option keys for both library interfaces
@@ -255,7 +251,7 @@ Configuration sources provided earlier in this stack will override later ones.
255
251
 
256
252
  The settings are a shallow tree whose values are inherited for all languages, but
257
253
  can be overridden. This works for settings passed directly to the API in either implementation.
258
- In the Javascript implementation, settings loaded from a config file, such as .jsbeautifyrc, can also use inheritance/overriding.
254
+ In the JavaScript implementation, settings loaded from a config file, such as .jsbeautifyrc, can also use inheritance/overriding.
259
255
 
260
256
  Below is an example configuration tree showing all the supported locations
261
257
  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:
@@ -401,4 +397,4 @@ Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, D
401
397
  Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
402
398
  Mathias Bynens, Vittorio Gambaletta and others.
403
399
 
404
- (README.md: js-beautify@1.14.3)
400
+ (README.md: js-beautify@1.14.6)
@@ -299,6 +299,7 @@ Beautifier.prototype.create_flags = function(flags_base, mode) {
299
299
  inline_frame: false,
300
300
  if_block: false,
301
301
  else_block: false,
302
+ class_start_block: false, // class A { INSIDE HERE } or class B extends C { INSIDE HERE }
302
303
  do_block: false,
303
304
  do_while: false,
304
305
  import_block: false,
@@ -711,6 +712,8 @@ Beautifier.prototype.handle_start_expr = function(current_token) {
711
712
  (peek_back_two.text === '*' && (peek_back_three.text === '{' || peek_back_three.text === ','))) {
712
713
  this._output.space_before_token = true;
713
714
  }
715
+ } else if (this._flags.parent && this._flags.parent.class_start_block) {
716
+ this._output.space_before_token = true;
714
717
  }
715
718
  }
716
719
  } else {
@@ -825,6 +828,12 @@ Beautifier.prototype.handle_start_block = function(current_token) {
825
828
  this.set_mode(MODE.BlockStatement);
826
829
  }
827
830
 
831
+ if (this._flags.last_token) {
832
+ if (reserved_array(this._flags.last_token.previous, ['class', 'extends'])) {
833
+ this._flags.class_start_block = true;
834
+ }
835
+ }
836
+
828
837
  var empty_braces = !next_token.comments_before && next_token.text === '}';
829
838
  var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' &&
830
839
  this._flags.last_token.type === TOKEN.END_EXPR;
@@ -1265,13 +1274,6 @@ Beautifier.prototype.handle_operator = function(current_token) {
1265
1274
  this.handle_whitespace_and_comments(current_token, preserve_statement_flags);
1266
1275
  }
1267
1276
 
1268
- if (reserved_array(this._flags.last_token, special_words)) {
1269
- // "return" had a special handling in TK_WORD. Now we need to return the favor
1270
- this._output.space_before_token = true;
1271
- this.print_token(current_token);
1272
- return;
1273
- }
1274
-
1275
1277
  // hack for actionscript's import .*;
1276
1278
  if (current_token.text === '*' && this._flags.last_token.type === TOKEN.DOT) {
1277
1279
  this.print_token(current_token);
@@ -1399,7 +1401,11 @@ Beautifier.prototype.handle_operator = function(current_token) {
1399
1401
  // http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
1400
1402
  // if there is a newline between -- or ++ and anything else we should preserve it.
1401
1403
  if (current_token.newlines && (current_token.text === '--' || current_token.text === '++' || current_token.text === '~')) {
1402
- this.print_newline(false, true);
1404
+ var new_line_needed = reserved_array(this._flags.last_token, special_words) && current_token.newlines;
1405
+ if (new_line_needed && (this._previous_flags.if_block || this._previous_flags.else_block)) {
1406
+ this.restore_mode();
1407
+ }
1408
+ this.print_newline(new_line_needed, true);
1403
1409
  }
1404
1410
 
1405
1411
  if (this._flags.last_token.text === ';' && is_expression(this._flags.mode)) {
@@ -1539,6 +1545,10 @@ Beautifier.prototype.handle_dot = function(current_token) {
1539
1545
  this.handle_whitespace_and_comments(current_token, true);
1540
1546
  }
1541
1547
 
1548
+ if (this._flags.last_token.text.match('^[0-9]+$')) {
1549
+ this._output.space_before_token = true;
1550
+ }
1551
+
1542
1552
  if (reserved_array(this._flags.last_token, special_words)) {
1543
1553
  this._output.space_before_token = false;
1544
1554
  } else {
@@ -2523,7 +2533,7 @@ var punct_pattern = new RegExp(punct);
2523
2533
 
2524
2534
  // words which should always start on new line.
2525
2535
  var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
2526
- var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']);
2536
+ var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as', 'class', 'extends']);
2527
2537
  var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');
2528
2538
 
2529
2539
  // var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
@@ -2614,7 +2624,8 @@ Tokenizer.prototype._read_word = function(previous_token) {
2614
2624
  if (!(previous_token.type === TOKEN.DOT ||
2615
2625
  (previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) &&
2616
2626
  reserved_word_pattern.test(resulting_string)) {
2617
- if (resulting_string === 'in' || resulting_string === 'of') { // hack for 'in' and 'of' operators
2627
+ if ((resulting_string === 'in' || resulting_string === 'of') &&
2628
+ (previous_token.type === TOKEN.WORD || previous_token.type === TOKEN.STRING)) { // hack for 'in' and 'of' operators
2618
2629
  return this._create_token(TOKEN.OPERATOR, resulting_string);
2619
2630
  }
2620
2631
  return this._create_token(TOKEN.RESERVED, resulting_string);
@@ -4040,6 +4051,7 @@ function Beautifier(source_text, options) {
4040
4051
  "@document": true
4041
4052
  };
4042
4053
  this.NON_SEMICOLON_NEWLINE_PROPERTY = [
4054
+ "grid-template-areas",
4043
4055
  "grid-template"
4044
4056
  ];
4045
4057
 
@@ -4371,7 +4383,8 @@ Beautifier.prototype.beautify = function() {
4371
4383
  }
4372
4384
  }
4373
4385
  } else if (this._ch === '"' || this._ch === '\'') {
4374
- this.preserveSingleSpace(isAfterSpace);
4386
+ var preserveQuoteSpace = previous_ch === '"' || previous_ch === '\'';
4387
+ this.preserveSingleSpace(preserveQuoteSpace || isAfterSpace);
4375
4388
  this.print_string(this._ch + this.eatString(this._ch));
4376
4389
  this.eatWhitespace(true);
4377
4390
  } else if (this._ch === ';') {
@@ -4415,7 +4428,12 @@ Beautifier.prototype.beautify = function() {
4415
4428
  }
4416
4429
  }
4417
4430
  } else {
4418
- this.preserveSingleSpace(isAfterSpace);
4431
+ var space_needed = false;
4432
+ if (this._input.lookBack("with")) {
4433
+ // look back is not an accurate solution, we need tokens to confirm without whitespaces
4434
+ space_needed = true;
4435
+ }
4436
+ this.preserveSingleSpace(isAfterSpace || space_needed);
4419
4437
  this.print_string(this._ch);
4420
4438
 
4421
4439
  // handle scss/sass map
@@ -4473,7 +4491,7 @@ Beautifier.prototype.beautify = function() {
4473
4491
  this._ch = '';
4474
4492
  }
4475
4493
  } else if (this._ch === '!' && !this._input.lookBack("\\")) { // !important
4476
- this.print_string(' ');
4494
+ this._output.space_before_token = true;
4477
4495
  this.print_string(this._ch);
4478
4496
  } else {
4479
4497
  var preserveAfterSpace = previous_ch === '"' || previous_ch === '\'';
@@ -5217,14 +5235,19 @@ var TagOpenParserToken = function(parent, raw_token) {
5217
5235
  tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
5218
5236
  this.tag_check = tag_check_match ? tag_check_match[1] : '';
5219
5237
  } else {
5220
- tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
5238
+ tag_check_match = raw_token.text.match(/^{{~?(?:[\^]|#\*?)?([^\s}]+)/);
5221
5239
  this.tag_check = tag_check_match ? tag_check_match[1] : '';
5222
5240
 
5223
- // handle "{{#> myPartial}}
5224
- if (raw_token.text === '{{#>' && this.tag_check === '>' && raw_token.next !== null) {
5225
- this.tag_check = raw_token.next.text.split(' ')[0];
5241
+ // handle "{{#> myPartial}}" or "{{~#> myPartial}}"
5242
+ if ((raw_token.text.startsWith('{{#>') || raw_token.text.startsWith('{{~#>')) && this.tag_check[0] === '>') {
5243
+ if (this.tag_check === '>' && raw_token.next !== null) {
5244
+ this.tag_check = raw_token.next.text.split(' ')[0];
5245
+ } else {
5246
+ this.tag_check = raw_token.text.split('>')[1];
5247
+ }
5226
5248
  }
5227
5249
  }
5250
+
5228
5251
  this.tag_check = this.tag_check.toLowerCase();
5229
5252
 
5230
5253
  if (raw_token.type === TOKEN.COMMENT) {
@@ -5236,9 +5259,17 @@ var TagOpenParserToken = function(parent, raw_token) {
5236
5259
  this.is_end_tag = !this.is_start_tag ||
5237
5260
  (raw_token.closed && raw_token.closed.text === '/>');
5238
5261
 
5262
+ // if whitespace handler ~ included (i.e. {{~#if true}}), handlebars tags start at pos 3 not pos 2
5263
+ var handlebar_starts = 2;
5264
+ if (this.tag_start_char === '{' && this.text.length >= 3) {
5265
+ if (this.text.charAt(2) === '~') {
5266
+ handlebar_starts = 3;
5267
+ }
5268
+ }
5269
+
5239
5270
  // handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
5240
5271
  this.is_end_tag = this.is_end_tag ||
5241
- (this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(2)))));
5272
+ (this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
5242
5273
  }
5243
5274
  };
5244
5275