js-beautify 1.8.4 → 1.8.8

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +33 -10
  2. package/README.md +18 -15
  3. package/js/lib/beautifier.js +108 -46
  4. package/js/lib/beautifier.min.js +1 -1
  5. package/js/lib/beautify-css.js +12 -7
  6. package/js/lib/beautify-html.js +62 -39
  7. package/js/lib/beautify.js +56 -15
  8. package/js/lib/cli.js +5 -3
  9. package/js/lib/unpackers/javascriptobfuscator_unpacker.js +2 -2
  10. package/js/lib/unpackers/myobfuscate_unpacker.js +2 -2
  11. package/js/lib/unpackers/p_a_c_k_e_r_unpacker.js +1 -1
  12. package/js/lib/unpackers/urlencode_unpacker.js +2 -2
  13. package/js/src/cli.js +5 -3
  14. package/js/src/core/directives.js +1 -1
  15. package/js/src/core/inputscanner.js +1 -1
  16. package/js/src/core/options.js +4 -5
  17. package/js/src/core/output.js +1 -1
  18. package/js/src/core/token.js +1 -1
  19. package/js/src/core/tokenizer.js +1 -1
  20. package/js/src/core/tokenstream.js +1 -1
  21. package/js/src/css/beautifier.js +2 -2
  22. package/js/src/css/index.js +1 -1
  23. package/js/src/css/options.js +1 -1
  24. package/js/src/css/tokenizer.js +1 -1
  25. package/js/src/html/beautifier.js +46 -33
  26. package/js/src/html/index.js +1 -1
  27. package/js/src/html/options.js +2 -2
  28. package/js/src/html/tokenizer.js +1 -1
  29. package/js/src/index.js +1 -1
  30. package/js/src/javascript/acorn.js +1 -1
  31. package/js/src/javascript/beautifier.js +23 -2
  32. package/js/src/javascript/index.js +1 -1
  33. package/js/src/javascript/options.js +3 -1
  34. package/js/src/javascript/tokenizer.js +15 -8
  35. package/js/src/unpackers/javascriptobfuscator_unpacker.js +2 -2
  36. package/js/src/unpackers/myobfuscate_unpacker.js +2 -2
  37. package/js/src/unpackers/p_a_c_k_e_r_unpacker.js +1 -1
  38. package/js/src/unpackers/urlencode_unpacker.js +2 -2
  39. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,26 +1,49 @@
1
1
  # Changelog
2
- ## v1.8.4
2
+ ## v1.8.8
3
3
 
4
4
  ### Description
5
- Broader adoption of 1.8.x revealed a few more high priority fixes
6
5
 
7
6
 
8
7
  ### Closed Issues
9
- * Multiple newlines added between empty textarea and "unformatted" inline elements ([#1534](https://github.com/beautify-web/js-beautify/issues/1534))
10
- * unindent_chained_methods broken ([#1533](https://github.com/beautify-web/js-beautify/issues/1533))
8
+ * async function in object wrong indentation ([#1573](https://github.com/beautify-web/js-beautify/issues/1573))
11
9
 
12
10
 
13
- ## v1.8.3
11
+ ## v1.8.7
14
12
 
15
13
  ### Description
16
14
 
17
15
 
18
16
  ### Closed Issues
19
- * Missing Bower Assets ([#1521](https://github.com/beautify-web/js-beautify/issues/1521))
20
- * Javascript ternary breaked with `await` ([#1519](https://github.com/beautify-web/js-beautify/issues/1519))
21
- * Object property indented after `await` ([#1517](https://github.com/beautify-web/js-beautify/issues/1517))
22
- * Handlebars formatting problems ([#870](https://github.com/beautify-web/js-beautify/issues/870))
23
- * beautify.js doesn't have indent_level option ([#724](https://github.com/beautify-web/js-beautify/issues/724))
17
+ * Add tests for html `indent_scripts` option ([#1518](https://github.com/beautify-web/js-beautify/issues/1518))
18
+ * Support dynamic import ([#1197](https://github.com/beautify-web/js-beautify/issues/1197))
19
+ * HTML: add an option to preserve manual wrapping of attributes ([#1125](https://github.com/beautify-web/js-beautify/issues/1125))
20
+ * js-beautify adds a space between # and include ([#1114](https://github.com/beautify-web/js-beautify/issues/1114))
21
+ * space_after_anon_function doesn't work with anon async functions ([#1034](https://github.com/beautify-web/js-beautify/issues/1034))
22
+ * Space before function arguments (space-after-function) ([#608](https://github.com/beautify-web/js-beautify/issues/608))
23
+
24
+
25
+ ## v1.8.6
26
+
27
+ ### Description
28
+ Beautifier has moved to https://beautifier.io
29
+
30
+ ### Closed Issues
31
+ * JS beautify break the angular compile ([#1544](https://github.com/beautify-web/js-beautify/issues/1544))
32
+ * base64 string is broken with v1.8.4 ([#1535](https://github.com/beautify-web/js-beautify/issues/1535))
33
+ * Bookmarklet becomes totally useless ([#1408](https://github.com/beautify-web/js-beautify/issues/1408))
34
+ * HTTPS ([#1399](https://github.com/beautify-web/js-beautify/issues/1399))
35
+ * Beautify breaks when js starts with space followed by multi-line comment ([#789](https://github.com/beautify-web/js-beautify/issues/789))
36
+
37
+
38
+ ## v1.8.4
39
+
40
+ ### Description
41
+ Broader adoption of 1.8.x revealed a few more high priority fixes
42
+
43
+
44
+ ### Closed Issues
45
+ * Multiple newlines added between empty textarea and "unformatted" inline elements ([#1534](https://github.com/beautify-web/js-beautify/issues/1534))
46
+ * unindent_chained_methods broken ([#1533](https://github.com/beautify-web/js-beautify/issues/1533))
24
47
 
25
48
 
26
49
  ## v1.8.1
package/README.md CHANGED
@@ -18,7 +18,7 @@ JavaScript, unpack scripts packed by Dean Edward’s popular packer,
18
18
  as well as partly deobfuscate scripts processed by the npm package
19
19
  [javascript-obfuscator](https://github.com/javascript-obfuscator/javascript-obfuscator).
20
20
 
21
- Open [jsbeautifier.org](http://jsbeautifier.org/) to try it out. Options are available via the UI.
21
+ Open [beautifier.io](https://beautifier.io/) to try it out. Options are available via the UI.
22
22
 
23
23
  # Contributors Needed
24
24
  I'm putting this front and center above because existing owners have very limited time to work on this project currently.
@@ -62,17 +62,17 @@ JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries
62
62
 
63
63
  To pull the latest version from one of these services include one set of the script tags below in your document:
64
64
  ```html
65
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.4/beautify.js"></script>
66
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.4/beautify-css.js"></script>
67
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.4/beautify-html.js"></script>
65
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.8/beautify.js"></script>
66
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.8/beautify-css.js"></script>
67
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.8/beautify-html.js"></script>
68
68
 
69
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.4/beautify.min.js"></script>
70
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.4/beautify-css.min.js"></script>
71
- <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.4/beautify-html.min.js"></script>
69
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.8/beautify.min.js"></script>
70
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.8/beautify-css.min.js"></script>
71
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.8/beautify-html.min.js"></script>
72
72
 
73
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.8.4/js/lib/beautify.js"></script>
74
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.8.4/js/lib/beautify-css.js"></script>
75
- <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.8.4/js/lib/beautify-html.js"></script>
73
+ <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.8.8/js/lib/beautify.js"></script>
74
+ <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.8.8/js/lib/beautify-css.js"></script>
75
+ <script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.8.8/js/lib/beautify-html.js"></script>
76
76
  ```
77
77
 
78
78
  Older versions are available by changing the version number.
@@ -92,7 +92,7 @@ $ pip install jsbeautifier
92
92
  You can beautify javascript using JS Beautifier in your web browser, or on the command-line using node.js or python.
93
93
 
94
94
  ## Web Browser
95
- Open [jsbeautifier.org](http://jsbeautifier.org/). Options are available via the UI.
95
+ Open [beautifier.io](https://beautifier.io/). Options are available via the UI.
96
96
 
97
97
  ## Web Libary
98
98
  The script tags above expose three functions: `js_beautify`, `css_beautify`, and `html_beautify`.
@@ -180,6 +180,7 @@ Beautifier Options:
180
180
  -E, --space-in-empty-paren Add a single space inside empty paren, ie. f( )
181
181
  -j, --jslint-happy Enable jslint-stricter mode
182
182
  -a, --space-after-anon-function Add a space before an anonymous function's parens, ie. function ()
183
+ --space-after-named-function Add a space before a named function's parens, i.e. function example ()
183
184
  -b, --brace-style [collapse|expand|end-expand|none][,preserve-inline] [collapse,preserve-inline]
184
185
  -u, --unindent-chained-methods Don't indent chained method calls
185
186
  -B, --break-chained-methods Break chained method calls across subsequent lines
@@ -209,6 +210,7 @@ Which correspond to the underscored option keys for both library interfaces
209
210
  "space_in_empty_paren": false,
210
211
  "jslint_happy": false,
211
212
  "space_after_anon_function": false,
213
+ "space_after_named_function": false,
212
214
  "brace_style": "collapse",
213
215
  "unindent_chained_methods": false,
214
216
  "break_chained_methods": false,
@@ -327,13 +329,14 @@ HTML Beautifier Options:
327
329
  -b, --brace-style [collapse-preserve-inline|collapse|expand|end-expand|none] ["collapse"]
328
330
  -S, --indent-scripts [keep|separate|normal] ["normal"]
329
331
  -w, --wrap-line-length Maximum characters per line (0 disables) [250]
330
- -A, --wrap-attributes Wrap attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple] ["auto"]
332
+ -A, --wrap-attributes Wrap attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple|preserve|preserve-aligned] ["auto"]
331
333
  -i, --wrap-attributes-indent-size Indent wrapped attributes to after N characters [indent-size] (ignored if wrap-attributes is "aligned")
332
334
  -d, --inline List of tags to be considered inline tags
333
335
  -U, --unformatted List of tags (defaults to inline) that should not be reformatted
334
336
  -T, --content_unformatted List of tags (defaults to pre) whose content should not be reformatted
335
337
  -E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline before them.
336
338
  --editorconfig Use EditorConfig to set up the options
339
+ --indent_scripts Sets indent level inside script tags ("normal", "keep", "separate")
337
340
  ```
338
341
 
339
342
  ## Directives to Ignore or Preserve sections (Javascript beautifier only)
@@ -365,13 +368,13 @@ You are free to use this in any way you want, in case you find this useful or wo
365
368
 
366
369
  # Credits
367
370
 
368
- * Created by Einar Lielmanis, <einar@jsbeautifier.org>
371
+ * Created by Einar Lielmanis, <einar@beautifier.io>
369
372
  * Python version flourished by Stefano Sanfilippo <a.little.coder@gmail.com>
370
373
  * Command-line for node.js by Daniel Stockman <daniel.stockman@gmail.com>
371
- * Maintained and expanded by Liam Newman <bitwiseman@gmail.com>
374
+ * Maintained and expanded by Liam Newman <bitwiseman@beautifier.io>
372
375
 
373
376
  Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, Dave
374
377
  Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
375
378
  Mathias Bynens, Vittorio Gambaletta and others.
376
379
 
377
- (README.md: js-beautify@1.8.4)
380
+ (README.md: js-beautify@1.8.8)
@@ -143,6 +143,7 @@ module.exports.js = js_beautify;
143
143
  module.exports.css = css_beautify;
144
144
  module.exports.html = style_html;
145
145
 
146
+
146
147
  /***/ }),
147
148
  /* 1 */
148
149
  /***/ (function(module, exports, __webpack_require__) {
@@ -187,6 +188,7 @@ function js_beautify(js_source_text, options) {
187
188
 
188
189
  module.exports = js_beautify;
189
190
 
191
+
190
192
  /***/ }),
191
193
  /* 2 */
192
194
  /***/ (function(module, exports, __webpack_require__) {
@@ -667,7 +669,7 @@ Beautifier.prototype.start_of_statement = function(current_token) {
667
669
  var start = false;
668
670
  start = start || reserved_array(this._flags.last_token, ['var', 'let', 'const']) && current_token.type === TOKEN.WORD;
669
671
  start = start || reserved_word(this._flags.last_token, 'do');
670
- start = start || (reserved_array(this._flags.last_token, newline_restricted_tokens) && !current_token.newlines);
672
+ start = start || (!(this._flags.parent.mode === MODE.ObjectLiteral && this._flags.mode === MODE.Statement)) && reserved_array(this._flags.last_token, newline_restricted_tokens) && !current_token.newlines;
671
673
  start = start || reserved_word(this._flags.last_token, 'else') &&
672
674
  !(reserved_word(current_token, 'if') && !current_token.comments_before);
673
675
  start = start || (this._flags.last_token.type === TOKEN.END_EXPR && (this._previous_flags.mode === MODE.ForInitializer || this._previous_flags.mode === MODE.Conditional));
@@ -761,6 +763,19 @@ Beautifier.prototype.handle_start_expr = function(current_token) {
761
763
  }
762
764
  } else if (this._flags.last_token.type === TOKEN.WORD) {
763
765
  this._output.space_before_token = false;
766
+
767
+ // function name() vs function name ()
768
+ // function* name() vs function* name ()
769
+ // async name() vs async name ()
770
+ if (this._options.space_after_named_function) {
771
+ // peek starts at next character so -1 is current token
772
+ var peek_back_three = this._tokens.peek(-4);
773
+ var peek_back_two = this._tokens.peek(-3);
774
+ if (reserved_array(peek_back_two, ['async', 'function']) ||
775
+ (reserved_array(peek_back_three, ['async', 'function']) && peek_back_two.text === '*')) {
776
+ this._output.space_before_token = true;
777
+ }
778
+ }
764
779
  } else {
765
780
  // Support preserving wrapped arrow function expressions
766
781
  // a.b('c',
@@ -970,6 +985,8 @@ Beautifier.prototype.handle_word = function(current_token) {
970
985
  if (current_token.type === TOKEN.RESERVED) {
971
986
  if (in_array(current_token.text, ['set', 'get']) && this._flags.mode !== MODE.ObjectLiteral) {
972
987
  current_token.type = TOKEN.WORD;
988
+ } else if (current_token.text === 'import' && this._tokens.peek().text === '(') {
989
+ current_token.type = TOKEN.WORD;
973
990
  } else if (in_array(current_token.text, ['as', 'from']) && !this._flags.import_block) {
974
991
  current_token.type = TOKEN.WORD;
975
992
  } else if (this._flags.mode === MODE.ObjectLiteral) {
@@ -1060,6 +1077,9 @@ Beautifier.prototype.handle_word = function(current_token) {
1060
1077
  this._output.space_before_token = true;
1061
1078
  } else if (reserved_word(this._flags.last_token, 'default') && this._last_last_text === 'export') {
1062
1079
  this._output.space_before_token = true;
1080
+ } else if (this._flags.last_token.text === 'declare') {
1081
+ // accomodates Typescript declare function formatting
1082
+ this._output.space_before_token = true;
1063
1083
  } else {
1064
1084
  this.print_newline();
1065
1085
  }
@@ -1148,6 +1168,9 @@ Beautifier.prototype.handle_word = function(current_token) {
1148
1168
  if (reserved_array(this._flags.last_token, special_words)) {
1149
1169
  // no newline between 'return nnn'
1150
1170
  this._output.space_before_token = true;
1171
+ } else if (this._flags.last_token.text === 'declare' && reserved_array(current_token, ['var', 'let', 'const'])) {
1172
+ // accomodates Typescript declare formatting
1173
+ this._output.space_before_token = true;
1151
1174
  } else if (this._flags.last_token.type !== TOKEN.END_EXPR) {
1152
1175
  if ((this._flags.last_token.type !== TOKEN.START_EXPR || !reserved_array(current_token, ['var', 'let', 'const'])) && this._flags.last_token.text !== ':') {
1153
1176
  // no need to force newline on 'var': for (var x = 0...)
@@ -1582,6 +1605,7 @@ Beautifier.prototype.handle_eof = function(current_token) {
1582
1605
 
1583
1606
  module.exports.Beautifier = Beautifier;
1584
1607
 
1608
+
1585
1609
  /***/ }),
1586
1610
  /* 3 */
1587
1611
  /***/ (function(module, exports, __webpack_require__) {
@@ -1897,6 +1921,7 @@ Output.prototype.ensure_empty_line_above = function(starts_with, ends_with) {
1897
1921
 
1898
1922
  module.exports.Output = Output;
1899
1923
 
1924
+
1900
1925
  /***/ }),
1901
1926
  /* 4 */
1902
1927
  /***/ (function(module, exports, __webpack_require__) {
@@ -1957,6 +1982,7 @@ function Token(type, text, newlines, whitespace_before) {
1957
1982
 
1958
1983
  module.exports.Token = Token;
1959
1984
 
1985
+
1960
1986
  /***/ }),
1961
1987
  /* 5 */
1962
1988
  /***/ (function(module, exports, __webpack_require__) {
@@ -2019,6 +2045,7 @@ exports.newline = /[\n\r\u2028\u2029]/;
2019
2045
  exports.lineBreak = new RegExp('\r\n|' + exports.newline.source);
2020
2046
  exports.allLineBreaks = new RegExp(exports.lineBreak.source, 'g');
2021
2047
 
2048
+
2022
2049
  /***/ }),
2023
2050
  /* 6 */
2024
2051
  /***/ (function(module, exports, __webpack_require__) {
@@ -2095,6 +2122,7 @@ function Options(options) {
2095
2122
  this.space_in_empty_paren = this._get_boolean('space_in_empty_paren');
2096
2123
  this.jslint_happy = this._get_boolean('jslint_happy');
2097
2124
  this.space_after_anon_function = this._get_boolean('space_after_anon_function');
2125
+ this.space_after_named_function = this._get_boolean('space_after_named_function');
2098
2126
  this.keep_array_indentation = this._get_boolean('keep_array_indentation');
2099
2127
  this.space_before_conditional = this._get_boolean('space_before_conditional', true);
2100
2128
  this.unescape_strings = this._get_boolean('unescape_strings');
@@ -2109,6 +2137,7 @@ function Options(options) {
2109
2137
  if (this.jslint_happy) {
2110
2138
  this.space_after_anon_function = true;
2111
2139
  }
2140
+
2112
2141
  }
2113
2142
  Options.prototype = new BaseOptions();
2114
2143
 
@@ -2116,6 +2145,7 @@ Options.prototype = new BaseOptions();
2116
2145
 
2117
2146
  module.exports.Options = Options;
2118
2147
 
2148
+
2119
2149
  /***/ }),
2120
2150
  /* 7 */
2121
2151
  /***/ (function(module, exports, __webpack_require__) {
@@ -2152,8 +2182,7 @@ module.exports.Options = Options;
2152
2182
 
2153
2183
 
2154
2184
  function Options(options, merge_child_field) {
2155
- options = _mergeOpts(options, merge_child_field);
2156
- this.raw_options = _normalizeOpts(options);
2185
+ this.raw_options = _mergeOpts(options, merge_child_field);
2157
2186
 
2158
2187
  // Support passing the source text back with no change
2159
2188
  this.disabled = this._get_boolean('disabled');
@@ -2264,10 +2293,10 @@ Options.prototype._is_valid_selection = function(result, selection_list) {
2264
2293
  // Example: obj = {a: 1, b: {a: 2}}
2265
2294
  // mergeOpts(obj, 'b')
2266
2295
  //
2267
- // Returns: {a: 2, b: {a: 2}}
2296
+ // Returns: {a: 2}
2268
2297
  function _mergeOpts(allOptions, childFieldName) {
2269
2298
  var finalOpts = {};
2270
- allOptions = allOptions || {};
2299
+ allOptions = _normalizeOpts(allOptions);
2271
2300
  var name;
2272
2301
 
2273
2302
  for (name in allOptions) {
@@ -2300,6 +2329,7 @@ module.exports.Options = Options;
2300
2329
  module.exports.normalizeOpts = _normalizeOpts;
2301
2330
  module.exports.mergeOpts = _mergeOpts;
2302
2331
 
2332
+
2303
2333
  /***/ }),
2304
2334
  /* 8 */
2305
2335
  /***/ (function(module, exports, __webpack_require__) {
@@ -2394,6 +2424,8 @@ punct = punct.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&");
2394
2424
  punct = punct.replace(/ /g, '|');
2395
2425
 
2396
2426
  var punct_pattern = new RegExp(punct, 'g');
2427
+ var shebang_pattern = /#![^\n\r\u2028\u2029]*(?:\r\n|[\n\r\u2028\u2029])?/g;
2428
+ var include_pattern = /#include[^\n\r\u2028\u2029]*(?:\r\n|[\n\r\u2028\u2029])?/g;
2397
2429
 
2398
2430
  // words which should always start on new line.
2399
2431
  var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
@@ -2520,18 +2552,23 @@ Tokenizer.prototype._read_non_javascript = function(c) {
2520
2552
  var resulting_string = '';
2521
2553
 
2522
2554
  if (c === '#') {
2523
- c = this._input.next();
2555
+ if (this._is_first_token()) {
2556
+ resulting_string = this._input.read(shebang_pattern);
2524
2557
 
2525
- if (this._is_first_token() && this._input.peek() === '!') {
2526
- // shebang
2527
- resulting_string = c;
2528
- while (this._input.hasNext() && c !== '\n') {
2529
- c = this._input.next();
2530
- resulting_string += c;
2558
+ if (resulting_string) {
2559
+ return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n');
2531
2560
  }
2561
+ }
2562
+
2563
+ // handles extendscript #includes
2564
+ resulting_string = this._input.read(include_pattern);
2565
+
2566
+ if (resulting_string) {
2532
2567
  return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n');
2533
2568
  }
2534
2569
 
2570
+ c = this._input.next();
2571
+
2535
2572
  // Spidermonkey-specific sharp variables for circular references. Considered obsolete.
2536
2573
  var sharp = '#';
2537
2574
  if (this._input.hasNext() && this._input.testChar(digit)) {
@@ -2840,6 +2877,7 @@ module.exports.TOKEN = TOKEN;
2840
2877
  module.exports.positionable_operators = positionable_operators.slice();
2841
2878
  module.exports.line_starters = line_starters.slice();
2842
2879
 
2880
+
2843
2881
  /***/ }),
2844
2882
  /* 9 */
2845
2883
  /***/ (function(module, exports, __webpack_require__) {
@@ -2994,6 +3032,7 @@ InputScanner.prototype.lookBack = function(testVal) {
2994
3032
 
2995
3033
  module.exports.InputScanner = InputScanner;
2996
3034
 
3035
+
2997
3036
  /***/ }),
2998
3037
  /* 10 */
2999
3038
  /***/ (function(module, exports, __webpack_require__) {
@@ -3152,6 +3191,7 @@ Tokenizer.prototype._readWhitespace = function() {
3152
3191
  module.exports.Tokenizer = Tokenizer;
3153
3192
  module.exports.TOKEN = TOKEN;
3154
3193
 
3194
+
3155
3195
  /***/ }),
3156
3196
  /* 11 */
3157
3197
  /***/ (function(module, exports, __webpack_require__) {
@@ -3236,6 +3276,7 @@ TokenStream.prototype.add = function(token) {
3236
3276
 
3237
3277
  module.exports.TokenStream = TokenStream;
3238
3278
 
3279
+
3239
3280
  /***/ }),
3240
3281
  /* 12 */
3241
3282
  /***/ (function(module, exports, __webpack_require__) {
@@ -3304,6 +3345,7 @@ Directives.prototype.readIgnored = function(input) {
3304
3345
 
3305
3346
  module.exports.Directives = Directives;
3306
3347
 
3348
+
3307
3349
  /***/ }),
3308
3350
  /* 13 */
3309
3351
  /***/ (function(module, exports, __webpack_require__) {
@@ -3348,6 +3390,7 @@ function css_beautify(source_text, options) {
3348
3390
 
3349
3391
  module.exports = css_beautify;
3350
3392
 
3393
+
3351
3394
  /***/ }),
3352
3395
  /* 14 */
3353
3396
  /***/ (function(module, exports, __webpack_require__) {
@@ -3728,7 +3771,7 @@ Beautifier.prototype.beautify = function() {
3728
3771
  this.print_string(this._ch);
3729
3772
  this.eatWhitespace();
3730
3773
  this._ch = this._input.next();
3731
- if (this._ch === ')' || this._ch === '"' || this._ch !== '\'') {
3774
+ if (this._ch === ')' || this._ch === '"' || this._ch === '\'') {
3732
3775
  this._input.back();
3733
3776
  parenLevel++;
3734
3777
  } else if (this._ch) {
@@ -3792,6 +3835,7 @@ Beautifier.prototype.beautify = function() {
3792
3835
 
3793
3836
  module.exports.Beautifier = Beautifier;
3794
3837
 
3838
+
3795
3839
  /***/ }),
3796
3840
  /* 15 */
3797
3841
  /***/ (function(module, exports, __webpack_require__) {
@@ -3844,6 +3888,7 @@ Options.prototype = new BaseOptions();
3844
3888
 
3845
3889
  module.exports.Options = Options;
3846
3890
 
3891
+
3847
3892
  /***/ }),
3848
3893
  /* 16 */
3849
3894
  /***/ (function(module, exports, __webpack_require__) {
@@ -3888,6 +3933,7 @@ function style_html(html_source, options, js_beautify, css_beautify) {
3888
3933
 
3889
3934
  module.exports = style_html;
3890
3935
 
3936
+
3891
3937
  /***/ }),
3892
3938
  /* 17 */
3893
3939
  /***/ (function(module, exports, __webpack_require__) {
@@ -3955,23 +4001,25 @@ Printer.prototype.add_raw_token = function(token) {
3955
4001
  this._output.add_raw_token(token);
3956
4002
  };
3957
4003
 
3958
- Printer.prototype.traverse_whitespace = function(raw_token) {
3959
- if (raw_token.whitespace_before || raw_token.newlines) {
3960
- var newlines = 0;
4004
+ Printer.prototype.print_preserved_newlines = function(raw_token) {
4005
+ var newlines = 0;
4006
+ if (raw_token.type !== TOKEN.TEXT && raw_token.previous.type !== TOKEN.TEXT) {
4007
+ newlines = raw_token.newlines ? 1 : 0;
4008
+ }
3961
4009
 
3962
- if (raw_token.type !== TOKEN.TEXT && raw_token.previous.type !== TOKEN.TEXT) {
3963
- newlines = raw_token.newlines ? 1 : 0;
3964
- }
4010
+ if (this.preserve_newlines) {
4011
+ newlines = raw_token.newlines < this.max_preserve_newlines + 1 ? raw_token.newlines : this.max_preserve_newlines + 1;
4012
+ }
4013
+ for (var n = 0; n < newlines; n++) {
4014
+ this.print_newline(n > 0);
4015
+ }
3965
4016
 
3966
- if (this.preserve_newlines) {
3967
- newlines = raw_token.newlines < this.max_preserve_newlines + 1 ? raw_token.newlines : this.max_preserve_newlines + 1;
3968
- }
4017
+ return newlines !== 0;
4018
+ };
3969
4019
 
3970
- if (newlines) {
3971
- for (var n = 0; n < newlines; n++) {
3972
- this.print_newline(n > 0);
3973
- }
3974
- } else {
4020
+ Printer.prototype.traverse_whitespace = function(raw_token) {
4021
+ if (raw_token.whitespace_before || raw_token.newlines) {
4022
+ if (!this.print_preserved_newlines(raw_token)) {
3975
4023
  this._output.space_before_token = true;
3976
4024
  this.print_space_or_wrap(raw_token.text);
3977
4025
  }
@@ -4136,6 +4184,8 @@ function Beautifier(source_text, options, js_beautify, css_beautify) {
4136
4184
  this._is_wrap_attributes_force_expand_multiline = (this._options.wrap_attributes === 'force-expand-multiline');
4137
4185
  this._is_wrap_attributes_force_aligned = (this._options.wrap_attributes === 'force-aligned');
4138
4186
  this._is_wrap_attributes_aligned_multiple = (this._options.wrap_attributes === 'aligned-multiple');
4187
+ this._is_wrap_attributes_preserve = this._options.wrap_attributes.substr(0, 'preserve'.length) === 'preserve';
4188
+ this._is_wrap_attributes_preserve_aligned = (this._options.wrap_attributes === 'preserve-aligned');
4139
4189
  }
4140
4190
 
4141
4191
  Beautifier.prototype.beautify = function() {
@@ -4234,25 +4284,37 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_
4234
4284
  printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '');
4235
4285
  if (last_tag_token.is_unformatted) {
4236
4286
  printer.add_raw_token(raw_token);
4287
+ } else if (last_tag_token.tag_start_char === '{' && raw_token.type === TOKEN.TEXT) {
4288
+ // For the insides of handlebars allow newlines or a single space between open and contents
4289
+ if (printer.print_preserved_newlines(raw_token)) {
4290
+ printer.print_raw_text(raw_token.whitespace_before + raw_token.text);
4291
+ } else {
4292
+ printer.print_token(raw_token.text);
4293
+ }
4237
4294
  } else {
4238
- if (last_tag_token.tag_start_char === '<') {
4239
- if (raw_token.type === TOKEN.ATTRIBUTE) {
4240
- printer.set_space_before_token(true);
4241
- last_tag_token.attr_count += 1;
4242
- } else if (raw_token.type === TOKEN.EQUALS) { //no space before =
4243
- printer.set_space_before_token(false);
4244
- } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value
4245
- printer.set_space_before_token(false);
4246
- }
4295
+ if (raw_token.type === TOKEN.ATTRIBUTE) {
4296
+ printer.set_space_before_token(true);
4297
+ last_tag_token.attr_count += 1;
4298
+ } else if (raw_token.type === TOKEN.EQUALS) { //no space before =
4299
+ printer.set_space_before_token(false);
4300
+ } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value
4301
+ printer.set_space_before_token(false);
4247
4302
  }
4248
4303
 
4249
4304
  if (printer._output.space_before_token && last_tag_token.tag_start_char === '<') {
4305
+ // Allow the current attribute to wrap
4306
+ // Set wrapped to true if the line is wrapped
4250
4307
  var wrapped = printer.print_space_or_wrap(raw_token.text);
4251
4308
  if (raw_token.type === TOKEN.ATTRIBUTE) {
4252
- var indentAttrs = wrapped && !this._is_wrap_attributes_force;
4309
+ if (this._is_wrap_attributes_preserve || this._is_wrap_attributes_preserve_aligned) {
4310
+ printer.traverse_whitespace(raw_token);
4311
+ wrapped = wrapped || raw_token.newlines !== 0;
4312
+ }
4313
+ // Save whether we have wrapped any attributes
4314
+ last_tag_token.has_wrapped_attrs = last_tag_token.has_wrapped_attrs || wrapped;
4253
4315
 
4254
4316
  if (this._is_wrap_attributes_force) {
4255
- var force_first_attr_wrap = false;
4317
+ var force_attr_wrap = last_tag_token.attr_count > 1;
4256
4318
  if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count === 1) {
4257
4319
  var is_only_attribute = true;
4258
4320
  var peek_index = 0;
@@ -4266,17 +4328,14 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_
4266
4328
  peek_index += 1;
4267
4329
  } while (peek_index < 4 && peek_token.type !== TOKEN.EOF && peek_token.type !== TOKEN.TAG_CLOSE);
4268
4330
 
4269
- force_first_attr_wrap = !is_only_attribute;
4331
+ force_attr_wrap = !is_only_attribute;
4270
4332
  }
4271
4333
 
4272
- if (last_tag_token.attr_count > 1 || force_first_attr_wrap) {
4334
+ if (force_attr_wrap) {
4273
4335
  printer.print_newline(false);
4274
- indentAttrs = true;
4336
+ last_tag_token.has_wrapped_attrs = true;
4275
4337
  }
4276
4338
  }
4277
- if (indentAttrs) {
4278
- last_tag_token.has_wrapped_attrs = true;
4279
- }
4280
4339
  }
4281
4340
  }
4282
4341
  printer.print_token(raw_token.text);
@@ -4360,7 +4419,7 @@ Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_to
4360
4419
  }
4361
4420
 
4362
4421
  //indent attributes an auto, forced, aligned or forced-align line-wrap
4363
- if (this._is_wrap_attributes_force_aligned || this._is_wrap_attributes_aligned_multiple) {
4422
+ if (this._is_wrap_attributes_force_aligned || this._is_wrap_attributes_aligned_multiple || this._is_wrap_attributes_preserve_aligned) {
4364
4423
  parser_token.alignment_size = raw_token.text.length + 1;
4365
4424
  }
4366
4425
 
@@ -4630,6 +4689,7 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
4630
4689
 
4631
4690
  module.exports.Beautifier = Beautifier;
4632
4691
 
4692
+
4633
4693
  /***/ }),
4634
4694
  /* 18 */
4635
4695
  /***/ (function(module, exports, __webpack_require__) {
@@ -4676,7 +4736,7 @@ function Options(options) {
4676
4736
 
4677
4737
  this.indent_handlebars = this._get_boolean('indent_handlebars', true);
4678
4738
  this.wrap_attributes = this._get_selection('wrap_attributes',
4679
- ['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple']);
4739
+ ['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple', 'preserve', 'preserve-aligned']);
4680
4740
  this.wrap_attributes_indent_size = this._get_number('wrap_attributes_indent_size', this.indent_size);
4681
4741
  this.extra_liners = this._get_array('extra_liners', ['head', 'body', '/html']);
4682
4742
 
@@ -4718,6 +4778,7 @@ Options.prototype = new BaseOptions();
4718
4778
 
4719
4779
  module.exports.Options = Options;
4720
4780
 
4781
+
4721
4782
  /***/ }),
4722
4783
  /* 19 */
4723
4784
  /***/ (function(module, exports, __webpack_require__) {
@@ -5012,6 +5073,7 @@ Tokenizer.prototype._read_content_word = function() {
5012
5073
  module.exports.Tokenizer = Tokenizer;
5013
5074
  module.exports.TOKEN = TOKEN;
5014
5075
 
5076
+
5015
5077
  /***/ })
5016
5078
  /******/ ]);
5017
5079
  });