js-beautify 1.9.0-beta2 → 1.9.0

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.
@@ -130,8 +130,8 @@ return /******/ (function(modules) { // webpackBootstrap
130
130
 
131
131
 
132
132
  var js_beautify = __webpack_require__(1);
133
- var css_beautify = __webpack_require__(13);
134
- var html_beautify = __webpack_require__(16);
133
+ var css_beautify = __webpack_require__(16);
134
+ var html_beautify = __webpack_require__(19);
135
135
 
136
136
  function style_html(html_source, options, js, css) {
137
137
  js = js || js_beautify;
@@ -1552,6 +1552,7 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
1552
1552
 
1553
1553
  // first line always indented
1554
1554
  this.print_token(current_token, lines[0]);
1555
+ this.print_newline(false, preserve_statement_flags);
1555
1556
 
1556
1557
 
1557
1558
  if (lines.length > 1) {
@@ -1564,8 +1565,6 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
1564
1565
  }
1565
1566
 
1566
1567
  for (j = 0; j < lines.length; j++) {
1567
- this.print_newline(false, true);
1568
- this._output.current_line.set_indent(-1);
1569
1568
  if (javadoc) {
1570
1569
  // javadoc: reformat and re-indent
1571
1570
  this.print_token(current_token, ltrim(lines[j]));
@@ -1574,16 +1573,16 @@ Beautifier.prototype.handle_block_comment = function(current_token, preserve_sta
1574
1573
  this.print_token(current_token, lines[j].substring(lastIndentLength));
1575
1574
  } else {
1576
1575
  // normal comments output raw
1576
+ this._output.current_line.set_indent(-1);
1577
1577
  this._output.add_token(lines[j]);
1578
1578
  }
1579
+
1580
+ // for comments on their own line or more than one line, make sure there's a new line after
1581
+ this.print_newline(false, preserve_statement_flags);
1579
1582
  }
1580
1583
 
1581
1584
  this._flags.alignment = 0;
1582
1585
  }
1583
-
1584
- // for comments on their own line or more than one line, make sure there's a new line after
1585
- this.print_newline(false, preserve_statement_flags);
1586
-
1587
1586
  };
1588
1587
 
1589
1588
  Beautifier.prototype.handle_comment = function(current_token, preserve_statement_flags) {
@@ -1770,14 +1769,11 @@ OutputLine.prototype.last = function() {
1770
1769
 
1771
1770
  OutputLine.prototype.push = function(item) {
1772
1771
  this.__items.push(item);
1773
- this.__character_count += item.length;
1774
- };
1775
-
1776
- OutputLine.prototype.push_raw = function(item) {
1777
- this.push(item);
1778
1772
  var last_newline_index = item.lastIndexOf('\n');
1779
1773
  if (last_newline_index !== -1) {
1780
1774
  this.__character_count = item.length - last_newline_index;
1775
+ } else {
1776
+ this.__character_count += item.length;
1781
1777
  }
1782
1778
  };
1783
1779
 
@@ -1990,7 +1986,7 @@ Output.prototype.add_raw_token = function(token) {
1990
1986
  }
1991
1987
  this.current_line.set_indent(-1);
1992
1988
  this.current_line.push(token.whitespace_before);
1993
- this.current_line.push_raw(token.text);
1989
+ this.current_line.push(token.text);
1994
1990
  this.space_before_token = false;
1995
1991
  this.non_breaking_space = false;
1996
1992
  this.previous_token_wrapped = false;
@@ -2169,11 +2165,12 @@ var nonASCIIidentifierChars = "\\u0300-\\u036f\\u0483-\\u0487\\u0591-\\u05bd\\u0
2169
2165
  //var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
2170
2166
  //var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
2171
2167
 
2172
- var identifierStart = "[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "]";
2173
- var identifierChars = "[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]*";
2168
+ var identifierStart = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierStartChars + nonASCIIidentifierStartChars + "])";
2169
+ var identifierChars = "(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])*";
2174
2170
 
2175
2171
  exports.identifier = new RegExp(identifierStart + identifierChars, 'g');
2176
-
2172
+ exports.identifierStart = new RegExp(identifierStart);
2173
+ exports.identifierMatch = new RegExp("(?:\\\\u[0-9a-fA-F]{4}|[" + baseASCIIidentifierChars + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "])+");
2177
2174
 
2178
2175
  var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; // jshint ignore:line
2179
2176
 
@@ -2522,8 +2519,11 @@ module.exports.mergeOpts = _mergeOpts;
2522
2519
  var InputScanner = __webpack_require__(9).InputScanner;
2523
2520
  var BaseTokenizer = __webpack_require__(10).Tokenizer;
2524
2521
  var BASETOKEN = __webpack_require__(10).TOKEN;
2525
- var Directives = __webpack_require__(12).Directives;
2522
+ var Directives = __webpack_require__(14).Directives;
2526
2523
  var acorn = __webpack_require__(5);
2524
+ var Pattern = __webpack_require__(13).Pattern;
2525
+ var TemplatablePattern = __webpack_require__(15).TemplatablePattern;
2526
+
2527
2527
 
2528
2528
  function in_array(what, arr) {
2529
2529
  return arr.indexOf(what) !== -1;
@@ -2554,7 +2554,7 @@ var TOKEN = {
2554
2554
 
2555
2555
  var directives_core = new Directives(/\/\*/, /\*\//);
2556
2556
 
2557
- var number_pattern = /0[xX][0123456789abcdefABCDEF]*|0[oO][01234567]*|0[bB][01]*|\d+n|(?:\.\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?/g;
2557
+ var number_pattern = /0[xX][0123456789abcdefABCDEF]*|0[oO][01234567]*|0[bB][01]*|\d+n|(?:\.\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?/;
2558
2558
 
2559
2559
  var digit = /[0-9]/;
2560
2560
 
@@ -2577,30 +2577,50 @@ var punct =
2577
2577
  punct = punct.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&");
2578
2578
  punct = punct.replace(/ /g, '|');
2579
2579
 
2580
- var punct_pattern = new RegExp(punct, 'g');
2581
- var shebang_pattern = /#![^\n\r\u2028\u2029]*(?:\r\n|[\n\r\u2028\u2029])?/g;
2582
- var include_pattern = /#include[^\n\r\u2028\u2029]*(?:\r\n|[\n\r\u2028\u2029])?/g;
2580
+ var punct_pattern = new RegExp(punct);
2583
2581
 
2584
2582
  // words which should always start on new line.
2585
2583
  var line_starters = 'continue,try,throw,return,var,let,const,if,switch,case,default,for,while,break,function,import,export'.split(',');
2586
2584
  var reserved_words = line_starters.concat(['do', 'in', 'of', 'else', 'get', 'set', 'new', 'catch', 'finally', 'typeof', 'yield', 'async', 'await', 'from', 'as']);
2587
2585
  var reserved_word_pattern = new RegExp('^(?:' + reserved_words.join('|') + ')$');
2588
2586
 
2589
- // /* ... */ comment ends with nearest */ or end of file
2590
- var block_comment_pattern = /\/\*(?:[\s\S]*?)((?:\*\/)|$)/g;
2591
-
2592
- // comment ends just before nearest linefeed or end of file
2593
- var comment_pattern = /\/\/(?:[^\n\r\u2028\u2029]*)/g;
2594
-
2595
- var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
2587
+ // var template_pattern = /(?:(?:<\?php|<\?=)[\s\S]*?\?>)|(?:<%[\s\S]*?%>)/g;
2596
2588
 
2597
2589
  var in_html_comment;
2598
2590
 
2599
2591
  var Tokenizer = function(input_string, options) {
2600
2592
  BaseTokenizer.call(this, input_string, options);
2601
2593
 
2602
- this._whitespace_pattern = /[\n\r\u2028\u2029\t\u000B\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff ]+/g;
2603
- this._newline_pattern = /([^\n\r\u2028\u2029]*)(\r\n|[\n\r\u2028\u2029])?/g;
2594
+ this._patterns.whitespace = this._patterns.whitespace.matching(
2595
+ /\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff/.source,
2596
+ /\u2028\u2029/.source);
2597
+
2598
+ var pattern_reader = new Pattern(this._input);
2599
+ var templatable = new TemplatablePattern(this._input);
2600
+ templatable = templatable.disable('handlebars');
2601
+ templatable = templatable.disable('django');
2602
+
2603
+
2604
+ this.__patterns = {
2605
+ template: templatable,
2606
+ identifier: templatable.starting_with(acorn.identifier).matching(acorn.identifierMatch),
2607
+ number: pattern_reader.matching(number_pattern),
2608
+ punct: pattern_reader.matching(punct_pattern),
2609
+ // comment ends just before nearest linefeed or end of file
2610
+ comment: pattern_reader.starting_with(/\/\//).until(/[\n\r\u2028\u2029]/),
2611
+ // /* ... */ comment ends with nearest */ or end of file
2612
+ block_comment: pattern_reader.starting_with(/\/\*/).until_after(/\*\//),
2613
+ html_comment_start: pattern_reader.matching(/<!--/),
2614
+ html_comment_end: pattern_reader.matching(/-->/),
2615
+ include: pattern_reader.starting_with(/#include/).until_after(acorn.lineBreak),
2616
+ shebang: pattern_reader.starting_with(/#!/).until_after(acorn.lineBreak),
2617
+ 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*>/),
2618
+ single_quote: templatable.until(/['\\\n\r\u2028\u2029]/),
2619
+ double_quote: templatable.until(/["\\\n\r\u2028\u2029]/),
2620
+ template_text: templatable.until(/[`\\$]/),
2621
+ template_expression: templatable.until(/[`}\\]/)
2622
+ };
2623
+
2604
2624
  };
2605
2625
  Tokenizer.prototype = new BaseTokenizer();
2606
2626
 
@@ -2625,14 +2645,18 @@ Tokenizer.prototype._reset = function() {
2625
2645
  };
2626
2646
 
2627
2647
  Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false
2628
- this._readWhitespace();
2629
2648
  var token = null;
2649
+ this._readWhitespace();
2630
2650
  var c = this._input.peek();
2631
2651
 
2632
- token = token || this._read_singles(c);
2652
+ if (c === null) {
2653
+ return this._create_token(TOKEN.EOF, '');
2654
+ }
2655
+
2656
+ token = token || this._read_string(c);
2633
2657
  token = token || this._read_word(previous_token);
2658
+ token = token || this._read_singles(c);
2634
2659
  token = token || this._read_comment(c);
2635
- token = token || this._read_string(c);
2636
2660
  token = token || this._read_regexp(c, previous_token);
2637
2661
  token = token || this._read_xml(c, previous_token);
2638
2662
  token = token || this._read_non_javascript(c);
@@ -2644,8 +2668,9 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { //
2644
2668
 
2645
2669
  Tokenizer.prototype._read_word = function(previous_token) {
2646
2670
  var resulting_string;
2647
- resulting_string = this._input.read(acorn.identifier);
2671
+ resulting_string = this.__patterns.identifier.read();
2648
2672
  if (resulting_string !== '') {
2673
+ resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n');
2649
2674
  if (!(previous_token.type === TOKEN.DOT ||
2650
2675
  (previous_token.type === TOKEN.RESERVED && (previous_token.text === 'set' || previous_token.text === 'get'))) &&
2651
2676
  reserved_word_pattern.test(resulting_string)) {
@@ -2654,11 +2679,10 @@ Tokenizer.prototype._read_word = function(previous_token) {
2654
2679
  }
2655
2680
  return this._create_token(TOKEN.RESERVED, resulting_string);
2656
2681
  }
2657
-
2658
2682
  return this._create_token(TOKEN.WORD, resulting_string);
2659
2683
  }
2660
2684
 
2661
- resulting_string = this._input.read(number_pattern);
2685
+ resulting_string = this.__patterns.number.read();
2662
2686
  if (resulting_string !== '') {
2663
2687
  return this._create_token(TOKEN.WORD, resulting_string);
2664
2688
  }
@@ -2666,9 +2690,7 @@ Tokenizer.prototype._read_word = function(previous_token) {
2666
2690
 
2667
2691
  Tokenizer.prototype._read_singles = function(c) {
2668
2692
  var token = null;
2669
- if (c === null) {
2670
- token = this._create_token(TOKEN.EOF, '');
2671
- } else if (c === '(' || c === '[') {
2693
+ if (c === '(' || c === '[') {
2672
2694
  token = this._create_token(TOKEN.START_EXPR, c);
2673
2695
  } else if (c === ')' || c === ']') {
2674
2696
  token = this._create_token(TOKEN.END_EXPR, c);
@@ -2691,7 +2713,7 @@ Tokenizer.prototype._read_singles = function(c) {
2691
2713
  };
2692
2714
 
2693
2715
  Tokenizer.prototype._read_punctuation = function() {
2694
- var resulting_string = this._input.read(punct_pattern);
2716
+ var resulting_string = this.__patterns.punct.read();
2695
2717
 
2696
2718
  if (resulting_string !== '') {
2697
2719
  if (resulting_string === '=') {
@@ -2707,7 +2729,7 @@ Tokenizer.prototype._read_non_javascript = function(c) {
2707
2729
 
2708
2730
  if (c === '#') {
2709
2731
  if (this._is_first_token()) {
2710
- resulting_string = this._input.read(shebang_pattern);
2732
+ resulting_string = this.__patterns.shebang.read();
2711
2733
 
2712
2734
  if (resulting_string) {
2713
2735
  return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n');
@@ -2715,7 +2737,7 @@ Tokenizer.prototype._read_non_javascript = function(c) {
2715
2737
  }
2716
2738
 
2717
2739
  // handles extendscript #includes
2718
- resulting_string = this._input.read(include_pattern);
2740
+ resulting_string = this.__patterns.include.read();
2719
2741
 
2720
2742
  if (resulting_string) {
2721
2743
  return this._create_token(TOKEN.UNKNOWN, resulting_string.trim() + '\n');
@@ -2747,23 +2769,20 @@ Tokenizer.prototype._read_non_javascript = function(c) {
2747
2769
  this._input.back();
2748
2770
 
2749
2771
  } else if (c === '<') {
2750
- if (this._input.peek(1) === '?' || this._input.peek(1) === '%') {
2751
- resulting_string = this._input.read(template_pattern);
2752
- if (resulting_string) {
2753
- resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n');
2754
- return this._create_token(TOKEN.STRING, resulting_string);
2755
- }
2756
- } else if (this._input.match(/<\!--/g)) {
2757
- c = '<!--';
2772
+ resulting_string = this.__patterns.html_comment_start.read();
2773
+ if (resulting_string) {
2758
2774
  while (this._input.hasNext() && !this._input.testChar(acorn.newline)) {
2759
- c += this._input.next();
2775
+ resulting_string += this._input.next();
2760
2776
  }
2761
2777
  in_html_comment = true;
2762
- return this._create_token(TOKEN.COMMENT, c);
2778
+ return this._create_token(TOKEN.COMMENT, resulting_string);
2779
+ }
2780
+ } else if (in_html_comment && c === '-') {
2781
+ resulting_string = this.__patterns.html_comment_end.read();
2782
+ if (resulting_string) {
2783
+ in_html_comment = false;
2784
+ return this._create_token(TOKEN.COMMENT, resulting_string);
2763
2785
  }
2764
- } else if (c === '-' && in_html_comment && this._input.match(/-->/g)) {
2765
- in_html_comment = false;
2766
- return this._create_token(TOKEN.COMMENT, '-->');
2767
2786
  }
2768
2787
 
2769
2788
  return null;
@@ -2775,7 +2794,7 @@ Tokenizer.prototype._read_comment = function(c) {
2775
2794
  var comment = '';
2776
2795
  if (this._input.peek(1) === '*') {
2777
2796
  // peek for comment /* ... */
2778
- comment = this._input.read(block_comment_pattern);
2797
+ comment = this.__patterns.block_comment.read();
2779
2798
  var directives = directives_core.get_directives(comment);
2780
2799
  if (directives && directives.ignore === 'start') {
2781
2800
  comment += directives_core.readIgnored(this._input);
@@ -2785,7 +2804,7 @@ Tokenizer.prototype._read_comment = function(c) {
2785
2804
  token.directives = directives;
2786
2805
  } else if (this._input.peek(1) === '/') {
2787
2806
  // peek for comment // ...
2788
- comment = this._input.read(comment_pattern);
2807
+ comment = this.__patterns.comment.read();
2789
2808
  token = this._create_token(TOKEN.COMMENT, comment);
2790
2809
  }
2791
2810
  }
@@ -2806,10 +2825,13 @@ Tokenizer.prototype._read_string = function(c) {
2806
2825
  if (this.has_char_escapes && this._options.unescape_strings) {
2807
2826
  resulting_string = unescape_string(resulting_string);
2808
2827
  }
2828
+
2809
2829
  if (this._input.peek() === c) {
2810
2830
  resulting_string += this._input.next();
2811
2831
  }
2812
2832
 
2833
+ resulting_string = resulting_string.replace(acorn.allLineBreaks, '\n');
2834
+
2813
2835
  return this._create_token(TOKEN.STRING, resulting_string);
2814
2836
  }
2815
2837
 
@@ -2864,17 +2886,13 @@ Tokenizer.prototype._read_regexp = function(c, previous_token) {
2864
2886
  return null;
2865
2887
  };
2866
2888
 
2867
-
2868
- var startXmlRegExp = /<()([-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*>/g;
2869
- var xmlRegExp = /[\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*>/g;
2870
-
2871
2889
  Tokenizer.prototype._read_xml = function(c, previous_token) {
2872
2890
 
2873
- if (this._options.e4x && c === "<" && this._input.test(startXmlRegExp) && this._allow_regexp_or_xml(previous_token)) {
2891
+ if (this._options.e4x && c === "<" && this._allow_regexp_or_xml(previous_token)) {
2892
+ var xmlStr = '';
2893
+ var match = this.__patterns.xml.read_match();
2874
2894
  // handle e4x xml literals
2875
2895
  //
2876
- var xmlStr = '';
2877
- var match = this._input.match(startXmlRegExp);
2878
2896
  if (match) {
2879
2897
  // Trim root tag to attempt to
2880
2898
  var rootTag = match[2].replace(/^{\s+/, '{').replace(/\s+}$/, '}');
@@ -2896,7 +2914,7 @@ Tokenizer.prototype._read_xml = function(c, previous_token) {
2896
2914
  if (depth <= 0) {
2897
2915
  break;
2898
2916
  }
2899
- match = this._input.match(xmlRegExp);
2917
+ match = this.__patterns.xml.read_match();
2900
2918
  }
2901
2919
  // if we didn't close correctly, keep unformatted.
2902
2920
  if (!match) {
@@ -2976,51 +2994,53 @@ function unescape_string(s) {
2976
2994
  // handle string
2977
2995
  //
2978
2996
  Tokenizer.prototype._read_string_recursive = function(delimiter, allow_unescaped_newlines, start_sub) {
2979
- // Template strings can travers lines without escape characters.
2980
- // Other strings cannot
2981
2997
  var current_char;
2982
- var resulting_string = '';
2983
- var esc = false;
2998
+ var pattern;
2999
+ if (delimiter === '\'') {
3000
+ pattern = this.__patterns.single_quote;
3001
+ } else if (delimiter === '"') {
3002
+ pattern = this.__patterns.double_quote;
3003
+ } else if (delimiter === '`') {
3004
+ pattern = this.__patterns.template_text;
3005
+ } else if (delimiter === '}') {
3006
+ pattern = this.__patterns.template_expression;
3007
+ }
3008
+
3009
+ var resulting_string = pattern.read();
3010
+ var next = '';
2984
3011
  while (this._input.hasNext()) {
2985
- current_char = this._input.peek();
2986
- if (!(esc || (current_char !== delimiter &&
2987
- (allow_unescaped_newlines || !acorn.newline.test(current_char))))) {
3012
+ next = this._input.next();
3013
+ if (next === delimiter ||
3014
+ (!allow_unescaped_newlines && acorn.newline.test(next))) {
3015
+ this._input.back();
2988
3016
  break;
2989
- }
2990
-
2991
- // Handle \r\n linebreaks after escapes or in template strings
2992
- if ((esc || allow_unescaped_newlines) && acorn.newline.test(current_char)) {
2993
- if (current_char === '\r' && this._input.peek(1) === '\n') {
2994
- this._input.next();
2995
- current_char = this._input.peek();
2996
- }
2997
- resulting_string += '\n';
2998
- } else {
2999
- resulting_string += current_char;
3000
- }
3017
+ } else if (next === '\\' && this._input.hasNext()) {
3018
+ current_char = this._input.peek();
3001
3019
 
3002
- if (esc) {
3003
3020
  if (current_char === 'x' || current_char === 'u') {
3004
3021
  this.has_char_escapes = true;
3022
+ } else if (current_char === '\r' && this._input.peek(1) === '\n') {
3023
+ this._input.next();
3005
3024
  }
3006
- esc = false;
3007
- } else {
3008
- esc = current_char === '\\';
3009
- }
3010
-
3011
- this._input.next();
3012
-
3013
- if (start_sub && resulting_string.indexOf(start_sub, resulting_string.length - start_sub.length) !== -1) {
3014
- if (delimiter === '`') {
3015
- resulting_string += this._read_string_recursive('}', allow_unescaped_newlines, '`');
3016
- } else {
3017
- resulting_string += this._read_string_recursive('`', allow_unescaped_newlines, '${');
3025
+ next += this._input.next();
3026
+ } else if (start_sub) {
3027
+ if (start_sub === '${' && next === '$' && this._input.peek() === '{') {
3028
+ next += this._input.next();
3018
3029
  }
3019
3030
 
3020
- if (this._input.hasNext()) {
3021
- resulting_string += this._input.next();
3031
+ if (start_sub === next) {
3032
+ if (delimiter === '`') {
3033
+ next += this._read_string_recursive('}', allow_unescaped_newlines, '`');
3034
+ } else {
3035
+ next += this._read_string_recursive('`', allow_unescaped_newlines, '${');
3036
+ }
3037
+ if (this._input.hasNext()) {
3038
+ next += this._input.next();
3039
+ }
3022
3040
  }
3023
3041
  }
3042
+ next += pattern.read();
3043
+ resulting_string += next;
3024
3044
  }
3025
3045
 
3026
3046
  return resulting_string;
@@ -3067,6 +3087,8 @@ module.exports.line_starters = line_starters.slice();
3067
3087
 
3068
3088
 
3069
3089
 
3090
+ var regexp_has_sticky = RegExp.prototype.hasOwnProperty('sticky');
3091
+
3070
3092
  function InputScanner(input_string) {
3071
3093
  this.__input = input_string || '';
3072
3094
  this.__input_length = this.__input.length;
@@ -3106,14 +3128,32 @@ InputScanner.prototype.peek = function(index) {
3106
3128
  return val;
3107
3129
  };
3108
3130
 
3131
+ // This is a JavaScript only helper function (not in python)
3132
+ // Javascript doesn't have a match method
3133
+ // and not all implementation support "sticky" flag.
3134
+ // If they do not support sticky then both this.match() and this.test() method
3135
+ // must get the match and check the index of the match.
3136
+ // If sticky is supported and set, this method will use it.
3137
+ // Otherwise it will check that global is set, and fall back to the slower method.
3138
+ InputScanner.prototype.__match = function(pattern, index) {
3139
+ pattern.lastIndex = index;
3140
+ var pattern_match = pattern.exec(this.__input);
3141
+
3142
+ if (pattern_match && !(regexp_has_sticky && pattern.sticky)) {
3143
+ if (pattern_match.index !== index) {
3144
+ pattern_match = null;
3145
+ }
3146
+ }
3147
+
3148
+ return pattern_match;
3149
+ };
3150
+
3109
3151
  InputScanner.prototype.test = function(pattern, index) {
3110
3152
  index = index || 0;
3111
3153
  index += this.__position;
3112
- pattern.lastIndex = index;
3113
3154
 
3114
3155
  if (index >= 0 && index < this.__input_length) {
3115
- var pattern_match = pattern.exec(this.__input);
3116
- return pattern_match && pattern_match.index === index;
3156
+ return !!this.__match(pattern, index);
3117
3157
  } else {
3118
3158
  return false;
3119
3159
  }
@@ -3127,9 +3167,8 @@ InputScanner.prototype.testChar = function(pattern, index) {
3127
3167
  };
3128
3168
 
3129
3169
  InputScanner.prototype.match = function(pattern) {
3130
- pattern.lastIndex = this.__position;
3131
- var pattern_match = pattern.exec(this.__input);
3132
- if (pattern_match && pattern_match.index === this.__position) {
3170
+ var pattern_match = this.__match(pattern, this.__position);
3171
+ if (pattern_match) {
3133
3172
  this.__position += pattern_match[0].length;
3134
3173
  } else {
3135
3174
  pattern_match = null;
@@ -3137,28 +3176,30 @@ InputScanner.prototype.match = function(pattern) {
3137
3176
  return pattern_match;
3138
3177
  };
3139
3178
 
3140
- InputScanner.prototype.read = function(pattern, untilAfterPattern) {
3179
+ InputScanner.prototype.read = function(starting_pattern, until_pattern, until_after) {
3141
3180
  var val = '';
3142
- var match = this.match(pattern);
3143
- if (match) {
3144
- val = match[0];
3145
- if (untilAfterPattern) {
3146
- val += this.readUntilAfter(untilAfterPattern);
3181
+ var match;
3182
+ if (starting_pattern) {
3183
+ match = this.match(starting_pattern);
3184
+ if (match) {
3185
+ val += match[0];
3147
3186
  }
3148
3187
  }
3188
+ if (until_pattern && (match || !starting_pattern)) {
3189
+ val += this.readUntil(until_pattern, until_after);
3190
+ }
3149
3191
  return val;
3150
3192
  };
3151
3193
 
3152
- InputScanner.prototype.readUntil = function(pattern, include_match) {
3194
+ InputScanner.prototype.readUntil = function(pattern, until_after) {
3153
3195
  var val = '';
3154
3196
  var match_index = this.__position;
3155
3197
  pattern.lastIndex = this.__position;
3156
3198
  var pattern_match = pattern.exec(this.__input);
3157
3199
  if (pattern_match) {
3158
- if (include_match) {
3159
- match_index = pattern_match.index + pattern_match[0].length;
3160
- } else {
3161
- match_index = pattern_match.index;
3200
+ match_index = pattern_match.index;
3201
+ if (until_after) {
3202
+ match_index += pattern_match[0].length;
3162
3203
  }
3163
3204
  } else {
3164
3205
  match_index = this.__input_length;
@@ -3173,6 +3214,26 @@ InputScanner.prototype.readUntilAfter = function(pattern) {
3173
3214
  return this.readUntil(pattern, true);
3174
3215
  };
3175
3216
 
3217
+ InputScanner.prototype.get_regexp = function(pattern, match_from) {
3218
+ var result = null;
3219
+ var flags = 'g';
3220
+ if (match_from && regexp_has_sticky) {
3221
+ flags = 'y';
3222
+ }
3223
+ // strings are converted to regexp
3224
+ if (typeof pattern === "string" && pattern !== '') {
3225
+ // result = new RegExp(pattern.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), flags);
3226
+ result = new RegExp(pattern, flags);
3227
+ } else if (pattern) {
3228
+ result = new RegExp(pattern.source, flags);
3229
+ }
3230
+ return result;
3231
+ };
3232
+
3233
+ InputScanner.prototype.get_literal_regexp = function(literal_string) {
3234
+ return RegExp(literal_string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
3235
+ };
3236
+
3176
3237
  /* css beautifier legacy helpers */
3177
3238
  InputScanner.prototype.peekUntilAfter = function(pattern) {
3178
3239
  var start = this.__position;
@@ -3187,7 +3248,6 @@ InputScanner.prototype.lookBack = function(testVal) {
3187
3248
  .toLowerCase() === testVal;
3188
3249
  };
3189
3250
 
3190
-
3191
3251
  module.exports.InputScanner = InputScanner;
3192
3252
 
3193
3253
 
@@ -3229,6 +3289,7 @@ module.exports.InputScanner = InputScanner;
3229
3289
  var InputScanner = __webpack_require__(9).InputScanner;
3230
3290
  var Token = __webpack_require__(4).Token;
3231
3291
  var TokenStream = __webpack_require__(11).TokenStream;
3292
+ var WhitespacePattern = __webpack_require__(12).WhitespacePattern;
3232
3293
 
3233
3294
  var TOKEN = {
3234
3295
  START: 'TK_START',
@@ -3240,11 +3301,9 @@ var Tokenizer = function(input_string, options) {
3240
3301
  this._input = new InputScanner(input_string);
3241
3302
  this._options = options || {};
3242
3303
  this.__tokens = null;
3243
- this.__newline_count = 0;
3244
- this.__whitespace_before_token = '';
3245
3304
 
3246
- this._whitespace_pattern = /[\n\r\t ]+/g;
3247
- this._newline_pattern = /([^\n\r]*)(\r\n|[\n\r])?/g;
3305
+ this._patterns = {};
3306
+ this._patterns.whitespace = new WhitespacePattern(this._input);
3248
3307
  };
3249
3308
 
3250
3309
  Tokenizer.prototype.tokenize = function() {
@@ -3323,28 +3382,14 @@ Tokenizer.prototype._is_closing = function(current_token, open_token) { // jshin
3323
3382
  };
3324
3383
 
3325
3384
  Tokenizer.prototype._create_token = function(type, text) {
3326
- var token = new Token(type, text, this.__newline_count, this.__whitespace_before_token);
3327
- this.__newline_count = 0;
3328
- this.__whitespace_before_token = '';
3385
+ var token = new Token(type, text,
3386
+ this._patterns.whitespace.newline_count,
3387
+ this._patterns.whitespace.whitespace_before_token);
3329
3388
  return token;
3330
3389
  };
3331
3390
 
3332
3391
  Tokenizer.prototype._readWhitespace = function() {
3333
- if (!this._input.testChar(this._whitespace_pattern)) {
3334
- return;
3335
- }
3336
- var resulting_string = this._input.read(this._whitespace_pattern);
3337
- if (resulting_string === ' ') {
3338
- this.__whitespace_before_token = resulting_string;
3339
- } else if (resulting_string !== '') {
3340
- this._newline_pattern.lastIndex = 0;
3341
- var nextMatch = this._newline_pattern.exec(resulting_string);
3342
- while (nextMatch[2]) {
3343
- this.__newline_count += 1;
3344
- nextMatch = this._newline_pattern.exec(resulting_string);
3345
- }
3346
- this.__whitespace_before_token = nextMatch[1];
3347
- }
3392
+ return this._patterns.whitespace.read();
3348
3393
  };
3349
3394
 
3350
3395
 
@@ -3473,13 +3518,226 @@ module.exports.TokenStream = TokenStream;
3473
3518
 
3474
3519
 
3475
3520
 
3521
+ var Pattern = __webpack_require__(13).Pattern;
3522
+
3523
+ function WhitespacePattern(input_scanner, parent) {
3524
+ Pattern.call(this, input_scanner, parent);
3525
+ if (parent) {
3526
+ this._line_regexp = this._input.get_regexp(parent._line_regexp);
3527
+ } else {
3528
+ this.__set_whitespace_patterns('', '');
3529
+ }
3530
+
3531
+ this.newline_count = 0;
3532
+ this.whitespace_before_token = '';
3533
+ }
3534
+ WhitespacePattern.prototype = new Pattern();
3535
+
3536
+ WhitespacePattern.prototype.__set_whitespace_patterns = function(whitespace_chars, newline_chars) {
3537
+ whitespace_chars += '\\t ';
3538
+ newline_chars += '\\n\\r';
3539
+
3540
+ this._match_pattern = this._input.get_regexp(
3541
+ '[' + whitespace_chars + newline_chars + ']+', true);
3542
+ this._newline_regexp = this._input.get_regexp(
3543
+ '\\r\\n|[' + newline_chars + ']');
3544
+ };
3545
+
3546
+ WhitespacePattern.prototype.read = function() {
3547
+ this.newline_count = 0;
3548
+ this.whitespace_before_token = '';
3549
+
3550
+ var resulting_string = this._input.read(this._match_pattern);
3551
+ if (resulting_string === ' ') {
3552
+ this.whitespace_before_token = ' ';
3553
+ } else if (resulting_string) {
3554
+ var matches = this.__split(this._newline_regexp, resulting_string);
3555
+ this.newline_count = matches.length - 1;
3556
+ this.whitespace_before_token = matches[this.newline_count];
3557
+ }
3558
+
3559
+ return resulting_string;
3560
+ };
3561
+
3562
+ WhitespacePattern.prototype.matching = function(whitespace_chars, newline_chars) {
3563
+ var result = this._create();
3564
+ result.__set_whitespace_patterns(whitespace_chars, newline_chars);
3565
+ result._update();
3566
+ return result;
3567
+ };
3568
+
3569
+ WhitespacePattern.prototype._create = function() {
3570
+ return new WhitespacePattern(this._input, this);
3571
+ };
3572
+
3573
+ WhitespacePattern.prototype.__split = function(regexp, input_string) {
3574
+ regexp.lastIndex = 0;
3575
+ var start_index = 0;
3576
+ var result = [];
3577
+ var next_match = regexp.exec(input_string);
3578
+ while (next_match) {
3579
+ result.push(input_string.substring(start_index, next_match.index));
3580
+ start_index = next_match.index + next_match[0].length;
3581
+ next_match = regexp.exec(input_string);
3582
+ }
3583
+
3584
+ if (start_index < input_string.length) {
3585
+ result.push(input_string.substring(start_index, input_string.length));
3586
+ } else {
3587
+ result.push('');
3588
+ }
3589
+
3590
+ return result;
3591
+ };
3592
+
3593
+
3594
+
3595
+ module.exports.WhitespacePattern = WhitespacePattern;
3596
+
3597
+
3598
+ /***/ }),
3599
+ /* 13 */
3600
+ /***/ (function(module, exports, __webpack_require__) {
3601
+
3602
+ "use strict";
3603
+ /*jshint node:true */
3604
+ /*
3605
+
3606
+ The MIT License (MIT)
3607
+
3608
+ Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
3609
+
3610
+ Permission is hereby granted, free of charge, to any person
3611
+ obtaining a copy of this software and associated documentation files
3612
+ (the "Software"), to deal in the Software without restriction,
3613
+ including without limitation the rights to use, copy, modify, merge,
3614
+ publish, distribute, sublicense, and/or sell copies of the Software,
3615
+ and to permit persons to whom the Software is furnished to do so,
3616
+ subject to the following conditions:
3617
+
3618
+ The above copyright notice and this permission notice shall be
3619
+ included in all copies or substantial portions of the Software.
3620
+
3621
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3622
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3623
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3624
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3625
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3626
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3627
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3628
+ SOFTWARE.
3629
+ */
3630
+
3631
+
3632
+
3633
+ function Pattern(input_scanner, parent) {
3634
+ this._input = input_scanner;
3635
+ this._starting_pattern = null;
3636
+ this._match_pattern = null;
3637
+ this._until_pattern = null;
3638
+ this._until_after = false;
3639
+
3640
+ if (parent) {
3641
+ this._starting_pattern = this._input.get_regexp(parent._starting_pattern, true);
3642
+ this._match_pattern = this._input.get_regexp(parent._match_pattern, true);
3643
+ this._until_pattern = this._input.get_regexp(parent._until_pattern);
3644
+ this._until_after = parent._until_after;
3645
+ }
3646
+ }
3647
+
3648
+ Pattern.prototype.read = function() {
3649
+ var result = this._input.read(this._starting_pattern);
3650
+ if (!this._starting_pattern || result) {
3651
+ result += this._input.read(this._match_pattern, this._until_pattern, this._until_after);
3652
+ }
3653
+ return result;
3654
+ };
3655
+
3656
+ Pattern.prototype.read_match = function() {
3657
+ return this._input.match(this._match_pattern);
3658
+ };
3659
+
3660
+ Pattern.prototype.until_after = function(pattern) {
3661
+ var result = this._create();
3662
+ result._until_after = true;
3663
+ result._until_pattern = this._input.get_regexp(pattern);
3664
+ result._update();
3665
+ return result;
3666
+ };
3667
+
3668
+ Pattern.prototype.until = function(pattern) {
3669
+ var result = this._create();
3670
+ result._until_after = false;
3671
+ result._until_pattern = this._input.get_regexp(pattern);
3672
+ result._update();
3673
+ return result;
3674
+ };
3675
+
3676
+ Pattern.prototype.starting_with = function(pattern) {
3677
+ var result = this._create();
3678
+ result._starting_pattern = this._input.get_regexp(pattern, true);
3679
+ result._update();
3680
+ return result;
3681
+ };
3682
+
3683
+ Pattern.prototype.matching = function(pattern) {
3684
+ var result = this._create();
3685
+ result._match_pattern = this._input.get_regexp(pattern, true);
3686
+ result._update();
3687
+ return result;
3688
+ };
3689
+
3690
+ Pattern.prototype._create = function() {
3691
+ return new Pattern(this._input, this);
3692
+ };
3693
+
3694
+ Pattern.prototype._update = function() {};
3695
+
3696
+ module.exports.Pattern = Pattern;
3697
+
3698
+
3699
+ /***/ }),
3700
+ /* 14 */
3701
+ /***/ (function(module, exports, __webpack_require__) {
3702
+
3703
+ "use strict";
3704
+ /*jshint node:true */
3705
+ /*
3706
+
3707
+ The MIT License (MIT)
3708
+
3709
+ Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
3710
+
3711
+ Permission is hereby granted, free of charge, to any person
3712
+ obtaining a copy of this software and associated documentation files
3713
+ (the "Software"), to deal in the Software without restriction,
3714
+ including without limitation the rights to use, copy, modify, merge,
3715
+ publish, distribute, sublicense, and/or sell copies of the Software,
3716
+ and to permit persons to whom the Software is furnished to do so,
3717
+ subject to the following conditions:
3718
+
3719
+ The above copyright notice and this permission notice shall be
3720
+ included in all copies or substantial portions of the Software.
3721
+
3722
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3723
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3724
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3725
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3726
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3727
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3728
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3729
+ SOFTWARE.
3730
+ */
3731
+
3732
+
3733
+
3476
3734
  function Directives(start_block_pattern, end_block_pattern) {
3477
3735
  start_block_pattern = typeof start_block_pattern === 'string' ? start_block_pattern : start_block_pattern.source;
3478
3736
  end_block_pattern = typeof end_block_pattern === 'string' ? end_block_pattern : end_block_pattern.source;
3479
3737
  this.__directives_block_pattern = new RegExp(start_block_pattern + / beautify( \w+[:]\w+)+ /.source + end_block_pattern, 'g');
3480
3738
  this.__directive_pattern = / (\w+)[:](\w+)/g;
3481
3739
 
3482
- this.__directives_end_ignore_pattern = new RegExp('(?:[\\s\\S]*?)((?:' + start_block_pattern + /\sbeautify\signore:end\s/.source + end_block_pattern + ')|$)', 'g');
3740
+ this.__directives_end_ignore_pattern = new RegExp(start_block_pattern + /\sbeautify\signore:end\s/.source + end_block_pattern, 'g');
3483
3741
  }
3484
3742
 
3485
3743
  Directives.prototype.get_directives = function(text) {
@@ -3500,7 +3758,7 @@ Directives.prototype.get_directives = function(text) {
3500
3758
  };
3501
3759
 
3502
3760
  Directives.prototype.readIgnored = function(input) {
3503
- return input.read(this.__directives_end_ignore_pattern);
3761
+ return input.readUntilAfter(this.__directives_end_ignore_pattern);
3504
3762
  };
3505
3763
 
3506
3764
 
@@ -3508,7 +3766,193 @@ module.exports.Directives = Directives;
3508
3766
 
3509
3767
 
3510
3768
  /***/ }),
3511
- /* 13 */
3769
+ /* 15 */
3770
+ /***/ (function(module, exports, __webpack_require__) {
3771
+
3772
+ "use strict";
3773
+ /*jshint node:true */
3774
+ /*
3775
+
3776
+ The MIT License (MIT)
3777
+
3778
+ Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
3779
+
3780
+ Permission is hereby granted, free of charge, to any person
3781
+ obtaining a copy of this software and associated documentation files
3782
+ (the "Software"), to deal in the Software without restriction,
3783
+ including without limitation the rights to use, copy, modify, merge,
3784
+ publish, distribute, sublicense, and/or sell copies of the Software,
3785
+ and to permit persons to whom the Software is furnished to do so,
3786
+ subject to the following conditions:
3787
+
3788
+ The above copyright notice and this permission notice shall be
3789
+ included in all copies or substantial portions of the Software.
3790
+
3791
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3792
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3793
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3794
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3795
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3796
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3797
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3798
+ SOFTWARE.
3799
+ */
3800
+
3801
+
3802
+
3803
+ var Pattern = __webpack_require__(13).Pattern;
3804
+
3805
+
3806
+ var template_names = {
3807
+ django: false,
3808
+ erb: false,
3809
+ handlebars: false,
3810
+ php: false
3811
+ };
3812
+
3813
+ // This lets templates appear anywhere we would do a readUntil
3814
+ // The cost is higher but it is pay to play.
3815
+ function TemplatablePattern(input_scanner, parent) {
3816
+ Pattern.call(this, input_scanner, parent);
3817
+ this.__template_pattern = null;
3818
+ this._disabled = Object.assign({}, template_names);
3819
+ this._excluded = Object.assign({}, template_names);
3820
+
3821
+ if (parent) {
3822
+ this.__template_pattern = this._input.get_regexp(parent.__template_pattern);
3823
+ this._excluded = Object.assign(this._excluded, parent._excluded);
3824
+ this._disabled = Object.assign(this._disabled, parent._disabled);
3825
+ }
3826
+ var pattern = new Pattern(input_scanner);
3827
+ this.__patterns = {
3828
+ handlebars_comment: pattern.starting_with(/{{!--/).until_after(/--}}/),
3829
+ handlebars: pattern.starting_with(/{{/).until_after(/}}/),
3830
+ php: pattern.starting_with(/<\?(?:[=]|php)/).until_after(/\?>/),
3831
+ erb: pattern.starting_with(/<%[^%]/).until_after(/[^%]%>/),
3832
+ // django coflicts with handlebars a bit.
3833
+ django: pattern.starting_with(/{%/).until_after(/%}/),
3834
+ django_value: pattern.starting_with(/{{/).until_after(/}}/),
3835
+ django_comment: pattern.starting_with(/{#/).until_after(/#}/)
3836
+ };
3837
+ }
3838
+ TemplatablePattern.prototype = new Pattern();
3839
+
3840
+ TemplatablePattern.prototype._create = function() {
3841
+ return new TemplatablePattern(this._input, this);
3842
+ };
3843
+
3844
+ TemplatablePattern.prototype._update = function() {
3845
+ this.__set_templated_pattern();
3846
+ };
3847
+
3848
+ TemplatablePattern.prototype.disable = function(language) {
3849
+ var result = this._create();
3850
+ result._disabled[language] = true;
3851
+ result._update();
3852
+ return result;
3853
+ };
3854
+
3855
+ TemplatablePattern.prototype.exclude = function(language) {
3856
+ var result = this._create();
3857
+ result._excluded[language] = true;
3858
+ result._update();
3859
+ return result;
3860
+ };
3861
+
3862
+ TemplatablePattern.prototype.read = function() {
3863
+ var result = '';
3864
+ if (this._match_pattern) {
3865
+ result = this._input.read(this._starting_pattern);
3866
+ } else {
3867
+ result = this._input.read(this._starting_pattern, this.__template_pattern);
3868
+ }
3869
+ var next = this._read_template();
3870
+ while (next) {
3871
+ if (this._match_pattern) {
3872
+ next += this._input.read(this._match_pattern);
3873
+ } else {
3874
+ next += this._input.readUntil(this.__template_pattern);
3875
+ }
3876
+ result += next;
3877
+ next = this._read_template();
3878
+ }
3879
+
3880
+ if (this._until_after) {
3881
+ result += this._input.readUntilAfter(this._until_pattern);
3882
+ }
3883
+ return result;
3884
+ };
3885
+
3886
+ TemplatablePattern.prototype.__set_templated_pattern = function() {
3887
+ var items = [];
3888
+
3889
+ if (!this._disabled.php) {
3890
+ items.push(this.__patterns.php._starting_pattern.source);
3891
+ }
3892
+ if (!this._disabled.handlebars) {
3893
+ items.push(this.__patterns.handlebars._starting_pattern.source);
3894
+ }
3895
+ if (!this._disabled.erb) {
3896
+ items.push(this.__patterns.erb._starting_pattern.source);
3897
+ }
3898
+ if (!this._disabled.django) {
3899
+ items.push(this.__patterns.django._starting_pattern.source);
3900
+ items.push(this.__patterns.django_value._starting_pattern.source);
3901
+ items.push(this.__patterns.django_comment._starting_pattern.source);
3902
+ }
3903
+
3904
+ if (this._until_pattern) {
3905
+ items.push(this._until_pattern.source);
3906
+ }
3907
+ this.__template_pattern = this._input.get_regexp('(?:' + items.join('|') + ')');
3908
+ };
3909
+
3910
+ TemplatablePattern.prototype._read_template = function() {
3911
+ var resulting_string = '';
3912
+ var c = this._input.peek();
3913
+ if (c === '<') {
3914
+ var peek1 = this._input.peek(1);
3915
+ //if we're in a comment, do something special
3916
+ // We treat all comments as literals, even more than preformatted tags
3917
+ // we just look for the appropriate close tag
3918
+ if (!this._disabled.php && !this._excluded.php && peek1 === '?') {
3919
+ resulting_string = resulting_string ||
3920
+ this.__patterns.php.read();
3921
+ }
3922
+ if (!this._disabled.erb && !this._excluded.erb && peek1 === '%') {
3923
+ resulting_string = resulting_string ||
3924
+ this.__patterns.erb.read();
3925
+ }
3926
+ } else if (c === '{') {
3927
+ if (!this._disabled.handlebars && !this._excluded.handlebars) {
3928
+ resulting_string = resulting_string ||
3929
+ this.__patterns.handlebars_comment.read();
3930
+ resulting_string = resulting_string ||
3931
+ this.__patterns.handlebars.read();
3932
+ }
3933
+ if (!this._disabled.django) {
3934
+ // django coflicts with handlebars a bit.
3935
+ if (!this._excluded.django && !this._excluded.handlebars) {
3936
+ resulting_string = resulting_string ||
3937
+ this.__patterns.django_value.read();
3938
+ }
3939
+ if (!this._excluded.django) {
3940
+ resulting_string = resulting_string ||
3941
+ this.__patterns.django_comment.read();
3942
+ resulting_string = resulting_string ||
3943
+ this.__patterns.django.read();
3944
+ }
3945
+ }
3946
+ }
3947
+ return resulting_string;
3948
+ };
3949
+
3950
+
3951
+ module.exports.TemplatablePattern = TemplatablePattern;
3952
+
3953
+
3954
+ /***/ }),
3955
+ /* 16 */
3512
3956
  /***/ (function(module, exports, __webpack_require__) {
3513
3957
 
3514
3958
  "use strict";
@@ -3542,8 +3986,8 @@ module.exports.Directives = Directives;
3542
3986
 
3543
3987
 
3544
3988
 
3545
- var Beautifier = __webpack_require__(14).Beautifier,
3546
- Options = __webpack_require__(15).Options;
3989
+ var Beautifier = __webpack_require__(17).Beautifier,
3990
+ Options = __webpack_require__(18).Options;
3547
3991
 
3548
3992
  function css_beautify(source_text, options) {
3549
3993
  var beautifier = new Beautifier(source_text, options);
@@ -3557,7 +4001,7 @@ module.exports.defaultOptions = function() {
3557
4001
 
3558
4002
 
3559
4003
  /***/ }),
3560
- /* 14 */
4004
+ /* 17 */
3561
4005
  /***/ (function(module, exports, __webpack_require__) {
3562
4006
 
3563
4007
  "use strict";
@@ -3591,10 +4035,10 @@ module.exports.defaultOptions = function() {
3591
4035
 
3592
4036
 
3593
4037
 
3594
- var Options = __webpack_require__(15).Options;
4038
+ var Options = __webpack_require__(18).Options;
3595
4039
  var Output = __webpack_require__(3).Output;
3596
4040
  var InputScanner = __webpack_require__(9).InputScanner;
3597
- var Directives = __webpack_require__(12).Directives;
4041
+ var Directives = __webpack_require__(14).Directives;
3598
4042
 
3599
4043
  var directives_core = new Directives(/\/\*/, /\*\//);
3600
4044
 
@@ -4016,7 +4460,7 @@ module.exports.Beautifier = Beautifier;
4016
4460
 
4017
4461
 
4018
4462
  /***/ }),
4019
- /* 15 */
4463
+ /* 18 */
4020
4464
  /***/ (function(module, exports, __webpack_require__) {
4021
4465
 
4022
4466
  "use strict";
@@ -4069,7 +4513,7 @@ module.exports.Options = Options;
4069
4513
 
4070
4514
 
4071
4515
  /***/ }),
4072
- /* 16 */
4516
+ /* 19 */
4073
4517
  /***/ (function(module, exports, __webpack_require__) {
4074
4518
 
4075
4519
  "use strict";
@@ -4103,8 +4547,8 @@ module.exports.Options = Options;
4103
4547
 
4104
4548
 
4105
4549
 
4106
- var Beautifier = __webpack_require__(17).Beautifier,
4107
- Options = __webpack_require__(18).Options;
4550
+ var Beautifier = __webpack_require__(20).Beautifier,
4551
+ Options = __webpack_require__(21).Options;
4108
4552
 
4109
4553
  function style_html(html_source, options, js_beautify, css_beautify) {
4110
4554
  var beautifier = new Beautifier(html_source, options, js_beautify, css_beautify);
@@ -4118,7 +4562,7 @@ module.exports.defaultOptions = function() {
4118
4562
 
4119
4563
 
4120
4564
  /***/ }),
4121
- /* 17 */
4565
+ /* 20 */
4122
4566
  /***/ (function(module, exports, __webpack_require__) {
4123
4567
 
4124
4568
  "use strict";
@@ -4152,10 +4596,10 @@ module.exports.defaultOptions = function() {
4152
4596
 
4153
4597
 
4154
4598
 
4155
- var Options = __webpack_require__(18).Options;
4599
+ var Options = __webpack_require__(21).Options;
4156
4600
  var Output = __webpack_require__(3).Output;
4157
- var Tokenizer = __webpack_require__(19).Tokenizer;
4158
- var TOKEN = __webpack_require__(19).TOKEN;
4601
+ var Tokenizer = __webpack_require__(22).Tokenizer;
4602
+ var TOKEN = __webpack_require__(22).TOKEN;
4159
4603
 
4160
4604
  var lineBreak = /\r\n|[\r\n]/;
4161
4605
  var allLineBreaks = /\r\n|[\r\n]/g;
@@ -4685,7 +5129,7 @@ var TagOpenParserToken = function(parent, raw_token) {
4685
5129
  tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
4686
5130
  this.tag_check = tag_check_match ? tag_check_match[1] : '';
4687
5131
  } else {
4688
- tag_check_match = raw_token.text.match(/^{{\#?([^\s}]+)/);
5132
+ tag_check_match = raw_token.text.match(/^{{[#\^]?([^\s}]+)/);
4689
5133
  this.tag_check = tag_check_match ? tag_check_match[1] : '';
4690
5134
  }
4691
5135
  this.tag_check = this.tag_check.toLowerCase();
@@ -4731,7 +5175,15 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok
4731
5175
  } else { // it's a start-tag
4732
5176
  // check if this tag is starting an element that has optional end element
4733
5177
  // and do an ending needed
4734
- this._do_optional_end_element(parser_token);
5178
+ if (this._do_optional_end_element(parser_token)) {
5179
+ if (!parser_token.is_inline_element) {
5180
+ if (parser_token.parent) {
5181
+ parser_token.parent.multiline_content = true;
5182
+ }
5183
+ printer.print_newline(false);
5184
+ }
5185
+
5186
+ }
4735
5187
 
4736
5188
  this._tag_stack.record_tag(parser_token); //push it on the tag stack
4737
5189
 
@@ -4810,6 +5262,7 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok
4810
5262
  //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'];
4811
5263
 
4812
5264
  Beautifier.prototype._do_optional_end_element = function(parser_token) {
5265
+ var result = null;
4813
5266
  // NOTE: cases of "if there is no more content in the parent element"
4814
5267
  // are handled automatically by the beautifier.
4815
5268
  // It assumes parent or ancestor close tag closes all children.
@@ -4819,52 +5272,52 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
4819
5272
 
4820
5273
  } else if (parser_token.tag_name === 'body') {
4821
5274
  // A head element’s end tag may be omitted if the head element is not immediately followed by a space character or a comment.
4822
- this._tag_stack.try_pop('head');
5275
+ result = result || this._tag_stack.try_pop('head');
4823
5276
 
4824
5277
  //} else if (parser_token.tag_name === 'body') {
4825
5278
  // DONE: A body element’s end tag may be omitted if the body element is not immediately followed by a comment.
4826
5279
 
4827
5280
  } else if (parser_token.tag_name === 'li') {
4828
5281
  // 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.
4829
- this._tag_stack.try_pop('li', ['ol', 'ul']);
5282
+ result = result || this._tag_stack.try_pop('li', ['ol', 'ul']);
4830
5283
 
4831
5284
  } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') {
4832
5285
  // 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.
4833
5286
  // A dt element’s end tag may be omitted if the dt element is immediately followed by another dt element or a dd element.
4834
- this._tag_stack.try_pop('dt', ['dl']);
4835
- this._tag_stack.try_pop('dd', ['dl']);
5287
+ result = result || this._tag_stack.try_pop('dt', ['dl']);
5288
+ result = result || this._tag_stack.try_pop('dd', ['dl']);
4836
5289
 
4837
5290
  //} else if (p_closers.indexOf(parser_token.tag_name) !== -1) {
4838
5291
  //TODO: THIS IS A BUG FARM. We are not putting this into 1.8.0 as it is likely to blow up.
4839
5292
  //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.
4840
- //this._tag_stack.try_pop('p', ['body']);
5293
+ //result = result || this._tag_stack.try_pop('p', ['body']);
4841
5294
 
4842
5295
  } else if (parser_token.tag_name === 'rp' || parser_token.tag_name === 'rt') {
4843
5296
  // 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.
4844
5297
  // 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.
4845
- this._tag_stack.try_pop('rt', ['ruby', 'rtc']);
4846
- this._tag_stack.try_pop('rp', ['ruby', 'rtc']);
5298
+ result = result || this._tag_stack.try_pop('rt', ['ruby', 'rtc']);
5299
+ result = result || this._tag_stack.try_pop('rp', ['ruby', 'rtc']);
4847
5300
 
4848
5301
  } else if (parser_token.tag_name === 'optgroup') {
4849
5302
  // An optgroup element’s end tag may be omitted if the optgroup element is immediately followed by another optgroup element, or if there is no more content in the parent element.
4850
5303
  // An option element’s end tag may be omitted if the option element is immediately followed by another option element, or if it is immediately followed by an optgroup element, or if there is no more content in the parent element.
4851
- this._tag_stack.try_pop('optgroup', ['select']);
4852
- //this._tag_stack.try_pop('option', ['select']);
5304
+ result = result || this._tag_stack.try_pop('optgroup', ['select']);
5305
+ //result = result || this._tag_stack.try_pop('option', ['select']);
4853
5306
 
4854
5307
  } else if (parser_token.tag_name === 'option') {
4855
5308
  // An option element’s end tag may be omitted if the option element is immediately followed by another option element, or if it is immediately followed by an optgroup element, or if there is no more content in the parent element.
4856
- this._tag_stack.try_pop('option', ['select', 'datalist', 'optgroup']);
5309
+ result = result || this._tag_stack.try_pop('option', ['select', 'datalist', 'optgroup']);
4857
5310
 
4858
5311
  } else if (parser_token.tag_name === 'colgroup') {
4859
5312
  // DONE: A colgroup element’s end tag may be omitted if the colgroup element is not immediately followed by a space character or a comment.
4860
5313
  // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
4861
- this._tag_stack.try_pop('caption', ['table']);
5314
+ result = result || this._tag_stack.try_pop('caption', ['table']);
4862
5315
 
4863
5316
  } else if (parser_token.tag_name === 'thead') {
4864
5317
  // A colgroup element's end tag may be ommitted if a thead, tfoot, tbody, or tr element is started.
4865
5318
  // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
4866
- this._tag_stack.try_pop('caption', ['table']);
4867
- this._tag_stack.try_pop('colgroup', ['table']);
5319
+ result = result || this._tag_stack.try_pop('caption', ['table']);
5320
+ result = result || this._tag_stack.try_pop('colgroup', ['table']);
4868
5321
 
4869
5322
  //} else if (parser_token.tag_name === 'caption') {
4870
5323
  // DONE: A caption element’s end tag may be omitted if the caption element is not immediately followed by a space character or a comment.
@@ -4874,10 +5327,10 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
4874
5327
  // A tbody element’s end tag may be omitted if the tbody element is immediately followed by a tbody or tfoot element, or if there is no more content in the parent element.
4875
5328
  // A colgroup element's end tag may be ommitted if a thead, tfoot, tbody, or tr element is started.
4876
5329
  // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
4877
- this._tag_stack.try_pop('caption', ['table']);
4878
- this._tag_stack.try_pop('colgroup', ['table']);
4879
- this._tag_stack.try_pop('thead', ['table']);
4880
- this._tag_stack.try_pop('tbody', ['table']);
5330
+ result = result || this._tag_stack.try_pop('caption', ['table']);
5331
+ result = result || this._tag_stack.try_pop('colgroup', ['table']);
5332
+ result = result || this._tag_stack.try_pop('thead', ['table']);
5333
+ result = result || this._tag_stack.try_pop('tbody', ['table']);
4881
5334
 
4882
5335
  //} else if (parser_token.tag_name === 'tfoot') {
4883
5336
  // DONE: A tfoot element’s end tag may be omitted if there is no more content in the parent element.
@@ -4886,15 +5339,15 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
4886
5339
  // A tr element’s end tag may be omitted if the tr element is immediately followed by another tr element, or if there is no more content in the parent element.
4887
5340
  // A colgroup element's end tag may be ommitted if a thead, tfoot, tbody, or tr element is started.
4888
5341
  // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
4889
- this._tag_stack.try_pop('caption', ['table']);
4890
- this._tag_stack.try_pop('colgroup', ['table']);
4891
- this._tag_stack.try_pop('tr', ['table', 'thead', 'tbody', 'tfoot']);
5342
+ result = result || this._tag_stack.try_pop('caption', ['table']);
5343
+ result = result || this._tag_stack.try_pop('colgroup', ['table']);
5344
+ result = result || this._tag_stack.try_pop('tr', ['table', 'thead', 'tbody', 'tfoot']);
4892
5345
 
4893
5346
  } else if (parser_token.tag_name === 'th' || parser_token.tag_name === 'td') {
4894
5347
  // A td element’s end tag may be omitted if the td element is immediately followed by a td or th element, or if there is no more content in the parent element.
4895
5348
  // A th element’s end tag may be omitted if the th element is immediately followed by a td or th element, or if there is no more content in the parent element.
4896
- this._tag_stack.try_pop('td', ['tr']);
4897
- this._tag_stack.try_pop('th', ['tr']);
5349
+ result = result || this._tag_stack.try_pop('td', ['tr']);
5350
+ result = result || this._tag_stack.try_pop('th', ['tr']);
4898
5351
  }
4899
5352
 
4900
5353
  // Start element omission not handled currently
@@ -4905,13 +5358,14 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) {
4905
5358
  // Fix up the parent of the parser token
4906
5359
  parser_token.parent = this._tag_stack.get_parser_token();
4907
5360
 
5361
+ return result;
4908
5362
  };
4909
5363
 
4910
5364
  module.exports.Beautifier = Beautifier;
4911
5365
 
4912
5366
 
4913
5367
  /***/ }),
4914
- /* 18 */
5368
+ /* 21 */
4915
5369
  /***/ (function(module, exports, __webpack_require__) {
4916
5370
 
4917
5371
  "use strict";
@@ -5005,7 +5459,7 @@ module.exports.Options = Options;
5005
5459
 
5006
5460
 
5007
5461
  /***/ }),
5008
- /* 19 */
5462
+ /* 22 */
5009
5463
  /***/ (function(module, exports, __webpack_require__) {
5010
5464
 
5011
5465
  "use strict";
@@ -5041,8 +5495,9 @@ module.exports.Options = Options;
5041
5495
 
5042
5496
  var BaseTokenizer = __webpack_require__(10).Tokenizer;
5043
5497
  var BASETOKEN = __webpack_require__(10).TOKEN;
5044
- var Directives = __webpack_require__(12).Directives;
5045
- var TemplatableReader = __webpack_require__(20).TemplatableReader;
5498
+ var Directives = __webpack_require__(14).Directives;
5499
+ var TemplatablePattern = __webpack_require__(15).TemplatablePattern;
5500
+ var Pattern = __webpack_require__(13).Pattern;
5046
5501
 
5047
5502
  var TOKEN = {
5048
5503
  TAG_OPEN: 'TK_TAG_OPEN',
@@ -5066,18 +5521,38 @@ var Tokenizer = function(input_string, options) {
5066
5521
 
5067
5522
  // Words end at whitespace or when a tag starts
5068
5523
  // if we are indenting handlebars, they are considered tags
5069
- this._word = new TemplatableReader(this._input).until(/[\n\r\t <]/g).with_templates();
5070
- this._word.handlebars = false; // Detect only
5071
- this._single_quote = new TemplatableReader(this._input).until_after(/'/g).with_templates();
5072
- this._double_quote = new TemplatableReader(this._input).until_after(/"/g).with_templates();
5073
- this._attribute = new TemplatableReader(this._input).until(/[\n\r\t =\/>]/g).with_templates();
5074
- this._element_name = new TemplatableReader(this._input).until(/[\n\r\t >\/]/g).with_templates();
5524
+ var templatable_reader = new TemplatablePattern(this._input);
5525
+ var pattern_reader = new Pattern(this._input);
5526
+
5527
+ this.__patterns = {
5528
+ word: templatable_reader.until(/[\n\r\t <]/),
5529
+ single_quote: templatable_reader.until_after(/'/),
5530
+ double_quote: templatable_reader.until_after(/"/),
5531
+ attribute: templatable_reader.until(/[\n\r\t =\/>]/),
5532
+ element_name: templatable_reader.until(/[\n\r\t >\/]/),
5533
+
5534
+ handlebars_comment: pattern_reader.starting_with(/{{!--/).until_after(/--}}/),
5535
+ handlebars: pattern_reader.starting_with(/{{/).until_after(/}}/),
5536
+ handlebars_open: pattern_reader.until(/[\n\r\t }]/),
5537
+ handlebars_raw_close: pattern_reader.until(/}}/),
5538
+ comment: pattern_reader.starting_with(/<!--/).until_after(/-->/),
5539
+ cdata: pattern_reader.starting_with(/<!\[cdata\[/).until_after(/]]>/),
5540
+ // https://en.wikipedia.org/wiki/Conditional_comment
5541
+ conditional_comment: pattern_reader.starting_with(/<!\[/).until_after(/]>/),
5542
+ processing: pattern_reader.starting_with(/<\?/).until_after(/\?>/)
5543
+ };
5544
+
5545
+ if (this._options.indent_handlebars) {
5546
+ this.__patterns.word = this.__patterns.word.exclude('handlebars');
5547
+ }
5548
+
5075
5549
  this._unformatted_content_delimiter = null;
5076
5550
 
5077
5551
  if (this._options.unformatted_content_delimiter) {
5078
- this._unformatted_content_delimiter =
5079
- new RegExp(this._options.unformatted_content_delimiter
5080
- .replace(/([[\\^$.|?*+()])/g, '\\$1'), 'g');
5552
+ var literal_regexp = this._input.get_literal_regexp(this._options.unformatted_content_delimiter);
5553
+ this.__patterns.unformatted_content_delimiter =
5554
+ pattern_reader.matching(literal_regexp)
5555
+ .until_after(literal_regexp);
5081
5556
  }
5082
5557
  };
5083
5558
  Tokenizer.prototype = new BaseTokenizer();
@@ -5102,8 +5577,8 @@ Tokenizer.prototype._reset = function() {
5102
5577
  };
5103
5578
 
5104
5579
  Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false
5105
- this._readWhitespace();
5106
5580
  var token = null;
5581
+ this._readWhitespace();
5107
5582
  var c = this._input.peek();
5108
5583
 
5109
5584
  if (c === null) {
@@ -5133,7 +5608,7 @@ Tokenizer.prototype._read_comment = function(c) { // jshint unused:false
5133
5608
  // We treat all comments as literals, even more than preformatted tags
5134
5609
  // we just look for the appropriate close tag
5135
5610
  if (c === '<' && (peek1 === '!' || peek1 === '?')) {
5136
- resulting_string = this._input.read(/<!--/g, /-->/g);
5611
+ resulting_string = this.__patterns.comment.read();
5137
5612
 
5138
5613
  // only process directive on html comments
5139
5614
  if (resulting_string) {
@@ -5142,9 +5617,9 @@ Tokenizer.prototype._read_comment = function(c) { // jshint unused:false
5142
5617
  resulting_string += directives_core.readIgnored(this._input);
5143
5618
  }
5144
5619
  } else {
5145
- resulting_string = this._input.read(/<!\[cdata\[/g, /]]>/g);
5146
- resulting_string = resulting_string || this._input.read(/<!\[/g, /]>/g);
5147
- resulting_string = resulting_string || this._input.read(/<\?/g, /\?>/g);
5620
+ resulting_string = this.__patterns.cdata.read();
5621
+ resulting_string = resulting_string || this.__patterns.conditional_comment.read();
5622
+ resulting_string = resulting_string || this.__patterns.processing.read();
5148
5623
  }
5149
5624
  }
5150
5625
 
@@ -5167,7 +5642,7 @@ Tokenizer.prototype._read_open = function(c, open_token) {
5167
5642
  if (this._input.peek() === '/') {
5168
5643
  resulting_string += this._input.next();
5169
5644
  }
5170
- resulting_string += this._element_name.read();
5645
+ resulting_string += this.__patterns.element_name.read();
5171
5646
  token = this._create_token(TOKEN.TAG_OPEN, resulting_string);
5172
5647
  }
5173
5648
  }
@@ -5180,11 +5655,11 @@ Tokenizer.prototype._read_open_handlebars = function(c, open_token) {
5180
5655
  if (!open_token) {
5181
5656
  if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') {
5182
5657
  if (this._input.peek(2) === '!') {
5183
- resulting_string = this._input.read(/{{!--/g, /--}}/g);
5184
- resulting_string = resulting_string || this._input.read(/{{/g, /}}/g);
5658
+ resulting_string = this.__patterns.handlebars_comment.read();
5659
+ resulting_string = resulting_string || this.__patterns.handlebars.read();
5185
5660
  token = this._create_token(TOKEN.COMMENT, resulting_string);
5186
5661
  } else {
5187
- resulting_string = this._input.readUntil(/[\n\r\t }]/g);
5662
+ resulting_string = this.__patterns.handlebars_open.read();
5188
5663
  token = this._create_token(TOKEN.TAG_OPEN, resulting_string);
5189
5664
  }
5190
5665
  }
@@ -5223,13 +5698,13 @@ Tokenizer.prototype._read_attribute = function(c, previous_token, open_token) {
5223
5698
  } else if (c === '"' || c === "'") {
5224
5699
  var content = this._input.next();
5225
5700
  if (c === '"') {
5226
- content += this._double_quote.read();
5701
+ content += this.__patterns.double_quote.read();
5227
5702
  } else {
5228
- content += this._single_quote.read();
5703
+ content += this.__patterns.single_quote.read();
5229
5704
  }
5230
5705
  token = this._create_token(TOKEN.VALUE, content);
5231
5706
  } else {
5232
- resulting_string = this._attribute.read();
5707
+ resulting_string = this.__patterns.attribute.read();
5233
5708
 
5234
5709
  if (resulting_string) {
5235
5710
  if (previous_token.type === TOKEN.EQUALS) {
@@ -5257,7 +5732,7 @@ Tokenizer.prototype._is_content_unformatted = function(tag_name) {
5257
5732
  Tokenizer.prototype._read_raw_content = function(previous_token, open_token) { // jshint unused:false
5258
5733
  var resulting_string = '';
5259
5734
  if (open_token && open_token.text[0] === '{') {
5260
- resulting_string = this._input.readUntil(/}}/g);
5735
+ resulting_string = this.__patterns.handlebars_raw_close.read();
5261
5736
  } else if (previous_token.type === TOKEN.TAG_CLOSE && (previous_token.opened.text[0] === '<')) {
5262
5737
  var tag_name = previous_token.opened.text.substr(1).toLowerCase();
5263
5738
  if (this._is_content_unformatted(tag_name)) {
@@ -5274,19 +5749,14 @@ Tokenizer.prototype._read_raw_content = function(previous_token, open_token) { /
5274
5749
 
5275
5750
  Tokenizer.prototype._read_content_word = function(c) {
5276
5751
  var resulting_string = '';
5277
- if (this._unformatted_content_delimiter) {
5752
+ if (this._options.unformatted_content_delimiter) {
5278
5753
  if (c === this._options.unformatted_content_delimiter[0]) {
5279
- resulting_string = this._input.read(this._unformatted_content_delimiter);
5754
+ resulting_string = this.__patterns.unformatted_content_delimiter.read();
5280
5755
  }
5281
5756
  }
5282
5757
 
5283
- if (resulting_string) {
5284
- resulting_string += this._input.readUntilAfter(this._unformatted_content_delimiter);
5285
- } else {
5286
- if (c === '{' && !this._options.indent_handlebars) {
5287
- resulting_string += this._input.next();
5288
- }
5289
- resulting_string += this._word.read();
5758
+ if (!resulting_string) {
5759
+ resulting_string = this.__patterns.word.read();
5290
5760
  }
5291
5761
  if (resulting_string) {
5292
5762
  return this._create_token(TOKEN.TEXT, resulting_string);
@@ -5297,173 +5767,6 @@ module.exports.Tokenizer = Tokenizer;
5297
5767
  module.exports.TOKEN = TOKEN;
5298
5768
 
5299
5769
 
5300
- /***/ }),
5301
- /* 20 */
5302
- /***/ (function(module, exports, __webpack_require__) {
5303
-
5304
- "use strict";
5305
- /*jshint node:true */
5306
- /*
5307
-
5308
- The MIT License (MIT)
5309
-
5310
- Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
5311
-
5312
- Permission is hereby granted, free of charge, to any person
5313
- obtaining a copy of this software and associated documentation files
5314
- (the "Software"), to deal in the Software without restriction,
5315
- including without limitation the rights to use, copy, modify, merge,
5316
- publish, distribute, sublicense, and/or sell copies of the Software,
5317
- and to permit persons to whom the Software is furnished to do so,
5318
- subject to the following conditions:
5319
-
5320
- The above copyright notice and this permission notice shall be
5321
- included in all copies or substantial portions of the Software.
5322
-
5323
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
5324
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
5325
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
5326
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
5327
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5328
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
5329
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5330
- SOFTWARE.
5331
- */
5332
-
5333
-
5334
-
5335
- function PatternReader(input_scanner) {
5336
- this._input = input_scanner;
5337
- this._until_pattern = null;
5338
- this._from_pattern = null;
5339
- this._include_match = false;
5340
- }
5341
-
5342
- PatternReader.prototype.read = function() {
5343
- var result = '';
5344
- if (this._from_pattern) {
5345
- result = this._input.read(this._from_pattern, this._until_pattern, this._include_match);
5346
- } else {
5347
- result = this._input.readUntil(this._until_pattern, this._include_match);
5348
- }
5349
- return result;
5350
- };
5351
-
5352
- PatternReader.prototype.until_after = function(pattern) {
5353
- this.include_match = true;
5354
- this._until_pattern = pattern;
5355
- return this;
5356
- };
5357
-
5358
- PatternReader.prototype.until = function(pattern) {
5359
- this.include_match = false;
5360
- this._until_pattern = pattern;
5361
- return this;
5362
- };
5363
-
5364
- PatternReader.prototype.from = function(pattern) {
5365
- this._from_pattern = pattern;
5366
- return this;
5367
- };
5368
-
5369
- function TemplatableReader(input_scanner) {
5370
- PatternReader.call(this, input_scanner);
5371
- this.__template_pattern = null;
5372
- this.handlebars = true;
5373
- this.php = true;
5374
- this.asp = true;
5375
- this.__language = {
5376
- handlebars_comment: new PatternReader(input_scanner).from(/{{!--/g).until_after(/--}}/g),
5377
- handlebars: new PatternReader(input_scanner).from(/{{/g).until_after(/}}/g),
5378
- php: new PatternReader(input_scanner).from(/<\?(?:[=]|php)/g).until_after(/\?>/g),
5379
- asp: new PatternReader(input_scanner).from(/<%/g).until_after(/%>/g)
5380
- };
5381
- }
5382
- TemplatableReader.prototype = new PatternReader();
5383
-
5384
- // This lets templates appear anywhere we would do a readUntil
5385
- // The cost is higher but it is pay to play.
5386
- TemplatableReader.prototype.with_templates = function() {
5387
- this.__set_templated_pattern();
5388
- return this;
5389
- };
5390
-
5391
- TemplatableReader.prototype.read = function() {
5392
- var result;
5393
- if (this._from_pattern) {
5394
- result = this._input.read(this._from_pattern, this.__template_pattern);
5395
- } else {
5396
- result = this._input.readUntil(this.__template_pattern);
5397
- }
5398
- var next = '';
5399
- do {
5400
- result += next;
5401
- next = this.read_template();
5402
- if (next !== '') {
5403
- next += this._input.readUntil(this.__template_pattern);
5404
- }
5405
- } while (this._input.hasNext() && next !== '');
5406
- result += next;
5407
-
5408
- if (this.include_match) {
5409
- result += this._input.readUntilAfter(this._until_pattern);
5410
- }
5411
- return result;
5412
- };
5413
-
5414
- TemplatableReader.prototype.__set_templated_pattern = function() {
5415
- var items = [];
5416
-
5417
- if (this._until_pattern) {
5418
- items.push(this._until_pattern.source);
5419
- }
5420
-
5421
- if (this.php) {
5422
- items.push(this.__language.php._from_pattern.source);
5423
- }
5424
-
5425
- if (this.handlebars) {
5426
- items.push(this.__language.handlebars._from_pattern.source);
5427
- }
5428
-
5429
- if (this.asp) {
5430
- items.push(this.__language.asp._from_pattern.source);
5431
- }
5432
-
5433
- this.__template_pattern = new RegExp('(?:' + items.join('|') + ')', 'g');
5434
- };
5435
-
5436
- TemplatableReader.prototype.read_template = function() {
5437
- var resulting_string = '';
5438
- var c = this._input.peek();
5439
- if (c === '<') {
5440
- var peek1 = this._input.peek(1);
5441
- //if we're in a comment, do something special
5442
- // We treat all comments as literals, even more than preformatted tags
5443
- // we just look for the appropriate close tag
5444
- if (this.php && peek1 === '?') {
5445
- resulting_string = resulting_string ||
5446
- this.__language.php.read();
5447
- }
5448
- if (this.asp && peek1 === '%') {
5449
- resulting_string = resulting_string ||
5450
- this.__language.asp.read();
5451
- }
5452
- } else if (c === '{') {
5453
- if (this.handlebars) {
5454
- resulting_string = resulting_string ||
5455
- this.__language.handlebars_comment.read();
5456
- resulting_string = resulting_string ||
5457
- this.__language.handlebars.read();
5458
- }
5459
- }
5460
- return resulting_string;
5461
- };
5462
-
5463
-
5464
- module.exports.TemplatableReader = TemplatableReader;
5465
-
5466
-
5467
5770
  /***/ })
5468
5771
  /******/ ]);
5469
5772
  });