From 033d8a6a634e0c1c878bf5333bbaadaadfe5fc77 Mon Sep 17 00:00:00 2001 From: scil Date: Mon, 28 Sep 2020 10:07:49 +0800 Subject: [PATCH 01/37] fix bug in node require --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97b5ce877..f07e588a7 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ To use `js-beautify` as a `node` library (after install locally), import and cal The configuration option names are the same as the CLI names but with underscores instead of dashes. For example, `--indent-size 2 --space-in-empty-paren` would be `{ indent_size: 2, space_in_empty_paren: true }`. ```js -var beautify = require('js-beautify').js, +var beautify = require('js-beautify/js').js, fs = require('fs'); fs.readFile('foo.js', 'utf8', function (err, data) { From 6edbfb5450b2894d83a5aace472ed3945bed4824 Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Tue, 20 Apr 2021 12:48:37 +0800 Subject: [PATCH 02/37] Add minimum attributes option for html attribute wrap --- README.md | 1 + js/src/cli.js | 3 ++ js/src/html/beautifier.js | 56 ++++++++++++++++----------------- js/src/html/options.js | 1 + test/data/html/tests.js | 65 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 7b22a42c1..c619176d8 100644 --- a/README.md +++ b/README.md @@ -340,6 +340,7 @@ HTML Beautifier Options: -S, --indent-scripts [keep|separate|normal] ["normal"] -w, --wrap-line-length Maximum characters per line (0 disables) [250] -A, --wrap-attributes Wrap attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple|preserve|preserve-aligned] ["auto"] + -M, --wrap-attributes-min-attrs Minimum number of html tag attributes for force wrapping attributes -i, --wrap-attributes-indent-size Indent wrapped attributes to after N characters [indent-size] (ignored if wrap-attributes is "aligned") -d, --inline List of tags to be considered inline tags -U, --unformatted List of tags (defaults to inline) that should not be reformatted diff --git a/js/src/cli.js b/js/src/cli.js index eb5c4f4c6..7008ace4e 100755 --- a/js/src/cli.js +++ b/js/src/cli.js @@ -87,6 +87,7 @@ var path = require('path'), "unescape_strings": Boolean, "wrap_line_length": Number, "wrap_attributes": ["auto", "force", "force-aligned", "force-expand-multiline", "aligned-multiple", "preserve", "preserve-aligned"], + "wrap_attributes_min_attrs": Number, "wrap_attributes_indent_size": Number, "e4x": Boolean, "end_with_newline": Boolean, @@ -151,6 +152,7 @@ var path = require('path'), "N": ["--newline_between_rules"], // HTML-only "A": ["--wrap_attributes"], + "M": ["--wrap_attributes_min_attrs"], "i": ["--wrap_attributes_indent_size"], "W": ["--max_char"], // obsolete since 1.3.5 "d": ["--inline"], @@ -383,6 +385,7 @@ function usage(err) { msg.push(' -S, --indent-scripts [keep|separate|normal] ["normal"]'); msg.push(' -w, --wrap-line-length Wrap lines that exceed N characters [0]'); msg.push(' -A, --wrap-attributes Wrap html tag attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple|preserve|preserve-aligned] ["auto"]'); + msg.push(' -M, --wrap-attributes-min-attrs Minimum number of html tag attributes for force wrapping attributes [2]'); msg.push(' -i, --wrap-attributes-indent-size Indent wrapped tags to after N characters [indent-level]'); msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)'); msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]'); diff --git a/js/src/html/beautifier.js b/js/src/html/beautifier.js index 82361b139..714cfc930 100644 --- a/js/src/html/beautifier.js +++ b/js/src/html/beautifier.js @@ -296,11 +296,11 @@ Beautifier.prototype.beautify = function() { while (raw_token.type !== TOKEN.EOF) { if (raw_token.type === TOKEN.TAG_OPEN || raw_token.type === TOKEN.COMMENT) { - parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token); + parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token, tokens); last_tag_token = parser_token; } else if ((raw_token.type === TOKEN.ATTRIBUTE || raw_token.type === TOKEN.EQUALS || raw_token.type === TOKEN.VALUE) || (raw_token.type === TOKEN.TEXT && !last_tag_token.tag_complete)) { - parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, tokens); + parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, last_token); } else if (raw_token.type === TOKEN.TAG_CLOSE) { parser_token = this._handle_tag_close(printer, raw_token, last_tag_token); } else if (raw_token.type === TOKEN.TEXT) { @@ -357,7 +357,7 @@ Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_t return parser_token; }; -Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, tokens) { +Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, last_token) { var wrapped = last_tag_token.has_wrapped_attrs; var parser_token = { text: raw_token.text, @@ -378,7 +378,6 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ } else { if (raw_token.type === TOKEN.ATTRIBUTE) { printer.set_space_before_token(true); - last_tag_token.attr_count += 1; } else if (raw_token.type === TOKEN.EQUALS) { //no space before = printer.set_space_before_token(false); } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value @@ -391,29 +390,15 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ wrapped = wrapped || raw_token.newlines !== 0; } - - if (this._is_wrap_attributes_force) { - var force_attr_wrap = last_tag_token.attr_count > 1; - if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count === 1) { - var is_only_attribute = true; - var peek_index = 0; - var peek_token; - do { - peek_token = tokens.peek(peek_index); - if (peek_token.type === TOKEN.ATTRIBUTE) { - is_only_attribute = false; - break; - } - peek_index += 1; - } while (peek_index < 4 && peek_token.type !== TOKEN.EOF && peek_token.type !== TOKEN.TAG_CLOSE); - - force_attr_wrap = !is_only_attribute; - } - - if (force_attr_wrap) { - printer.print_newline(false); - wrapped = true; - } + // Wrap for 'force' options, and if the number of attributes is at least that specified in 'wrap_attributes_min_attrs': + // 1. always wrap the second and beyond attributes + // 2. wrap the first attribute only if 'force-expand-multiline' is used and there are more than 1 attributes + if (this._is_wrap_attributes_force && + last_tag_token.attr_count >= this._options.wrap_attributes_min_attrs && + (last_token.type !== TOKEN.TAG_OPEN || // ie. second attribute and beyond + (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count > 1))) { + printer.print_newline(false); + wrapped = true; } } printer.print_token(raw_token); @@ -542,12 +527,12 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, } }; -Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token) { +Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token, tokens) { var parser_token = this._get_tag_open_token(raw_token); if ((last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) && !last_tag_token.is_empty_element && - raw_token.type === TOKEN.TAG_OPEN && raw_token.text.indexOf('' ] }] + }, { + name: "Test wrap_attributes_min_attrs with force/force-xx options", + description: "", + matrix: [{ + options: [ + { name: "wrap_attributes", value: "'force'" }, + { name: "wrap_attributes_min_attrs", value: "4" } + ], + indent_attr: ' ', + indent_attr_first: ' ', + indent_end: ' ', + newline_end: '' + }, { + options: [ + { name: "wrap_attributes", value: "'force-aligned'" }, + { name: "wrap_attributes_min_attrs", value: "4" } + ], + indent_attr: ' ', + indent_attr_first: ' ', + indent_end: ' ', + newline_end: '' + }, { + options: [ + { name: "wrap_attributes", value: "'force-expand-multiline'" }, + { name: "wrap_attributes_min_attrs", value: "4" } + ], + indent_attr: ' ', + indent_attr_first: '\n ', + indent_end: '\n', + newline_end: '\n' + }], + tests: [{ + input: [ + '' + ], + output: [ + '' + ] + }, { + input: [ + '' + ], + output: '' + }, { + input: [ + '', + '', + '' + ], + output: [ + '', + ' ', + '' + ] + }] }, { name: "Handlebars Indenting Off", description: "Test handlebar behavior when indenting is off", From d8bcf29f682e6a9d084c5d8c9ba00b8bb60e38b6 Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Tue, 20 Apr 2021 14:18:45 +0800 Subject: [PATCH 03/37] Allow min_attrs=1 for force-expand-multiline --- js/src/html/beautifier.js | 2 +- test/data/html/tests.js | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/js/src/html/beautifier.js b/js/src/html/beautifier.js index 714cfc930..b6bcb8346 100644 --- a/js/src/html/beautifier.js +++ b/js/src/html/beautifier.js @@ -396,7 +396,7 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ if (this._is_wrap_attributes_force && last_tag_token.attr_count >= this._options.wrap_attributes_min_attrs && (last_token.type !== TOKEN.TAG_OPEN || // ie. second attribute and beyond - (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count > 1))) { + this._is_wrap_attributes_force_expand_multiline)) { printer.print_newline(false); wrapped = true; } diff --git a/test/data/html/tests.js b/test/data/html/tests.js index ae83739a3..23cfc4c9f 100644 --- a/test/data/html/tests.js +++ b/test/data/html/tests.js @@ -1258,6 +1258,40 @@ exports.test_data = { '' ] }] + }, { + name: "Test wrap_attributes_min_attrs = 1 with force/force-xx options", + description: "", + matrix: [{ + // Should not wrap, by design + options: [ + { name: "wrap_attributes", value: "'force'" }, + { name: "wrap_attributes_min_attrs", value: "1" } + ], + indent_attr: ' ', + newline_end: ' ' + }, { + // Should not wrap, by design + options: [ + { name: "wrap_attributes", value: "'force-aligned'" }, + { name: "wrap_attributes_min_attrs", value: "1" } + ], + indent_attr: ' ', + newline_end: ' ' + }, { + // Should wrap + options: [ + { name: "wrap_attributes", value: "'force-expand-multiline'" }, + { name: "wrap_attributes_min_attrs", value: "1" } + ], + indent_attr: '\n ', + newline_end: '\n' + }], + tests: [{ + input: [ + '' + ], + output: '' + }] }, { name: "Handlebars Indenting Off", description: "Test handlebar behavior when indenting is off", From 3686180ce79f85ecee4ef77b4f38c0a1349e532b Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Tue, 20 Apr 2021 14:18:55 +0800 Subject: [PATCH 04/37] Polish up some tests --- test/data/html/tests.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/data/html/tests.js b/test/data/html/tests.js index 23cfc4c9f..0d2031237 100644 --- a/test/data/html/tests.js +++ b/test/data/html/tests.js @@ -1226,31 +1226,31 @@ exports.test_data = { }], tests: [{ input: [ - '' ], output: [ - '' ] }, { input: [ - '' ], - output: '' + output: '' }, { input: [ - '', '', '' ], output: [ - '', From 9b6344393f86a69f511ace1be78ce2414db95817 Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Tue, 20 Apr 2021 15:22:19 +0800 Subject: [PATCH 05/37] Update comment --- js/src/html/beautifier.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/html/beautifier.js b/js/src/html/beautifier.js index b6bcb8346..e814370f7 100644 --- a/js/src/html/beautifier.js +++ b/js/src/html/beautifier.js @@ -392,7 +392,7 @@ Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_ // Wrap for 'force' options, and if the number of attributes is at least that specified in 'wrap_attributes_min_attrs': // 1. always wrap the second and beyond attributes - // 2. wrap the first attribute only if 'force-expand-multiline' is used and there are more than 1 attributes + // 2. wrap the first attribute only if 'force-expand-multiline' is specified if (this._is_wrap_attributes_force && last_tag_token.attr_count >= this._options.wrap_attributes_min_attrs && (last_token.type !== TOKEN.TAG_OPEN || // ie. second attribute and beyond From 0983909c4b66810a32e936067579e38e6557b88b Mon Sep 17 00:00:00 2001 From: Ze Yu Date: Tue, 20 Apr 2021 15:29:27 +0800 Subject: [PATCH 06/37] Update documentation wording --- README.md | 2 +- js/src/cli.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c619176d8..35e963838 100644 --- a/README.md +++ b/README.md @@ -340,7 +340,7 @@ HTML Beautifier Options: -S, --indent-scripts [keep|separate|normal] ["normal"] -w, --wrap-line-length Maximum characters per line (0 disables) [250] -A, --wrap-attributes Wrap attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple|preserve|preserve-aligned] ["auto"] - -M, --wrap-attributes-min-attrs Minimum number of html tag attributes for force wrapping attributes + -M, --wrap-attributes-min-attrs Minimum number of html tag attributes for force wrap attribute options [2] -i, --wrap-attributes-indent-size Indent wrapped attributes to after N characters [indent-size] (ignored if wrap-attributes is "aligned") -d, --inline List of tags to be considered inline tags -U, --unformatted List of tags (defaults to inline) that should not be reformatted diff --git a/js/src/cli.js b/js/src/cli.js index 7008ace4e..1e21eb02a 100755 --- a/js/src/cli.js +++ b/js/src/cli.js @@ -385,7 +385,7 @@ function usage(err) { msg.push(' -S, --indent-scripts [keep|separate|normal] ["normal"]'); msg.push(' -w, --wrap-line-length Wrap lines that exceed N characters [0]'); msg.push(' -A, --wrap-attributes Wrap html tag attributes to new lines [auto|force|force-aligned|force-expand-multiline|aligned-multiple|preserve|preserve-aligned] ["auto"]'); - msg.push(' -M, --wrap-attributes-min-attrs Minimum number of html tag attributes for force wrapping attributes [2]'); + msg.push(' -M, --wrap-attributes-min-attrs Minimum number of html tag attributes for force wrap attribute options [2]'); msg.push(' -i, --wrap-attributes-indent-size Indent wrapped tags to after N characters [indent-level]'); msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)'); msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]'); From ada9f66ea1eb5d90324748641a4d4b9e5893c2db Mon Sep 17 00:00:00 2001 From: cw100dev Date: Thu, 8 Sep 2022 17:14:37 -0700 Subject: [PATCH 07/37] changes to both js and python jsbeautifiers for issue #2062 to accoutn for new record types --- .DS_Store | Bin 8196 -> 0 bytes .github/PULL_REQUEST_TEMPLATE.md | 12 ++++++------ js/src/javascript/beautifier.js | 5 ++++- python/jsbeautifier/javascript/beautifier.py | 6 +++++- test/data/javascript/tests.js | 1 + 5 files changed, 16 insertions(+), 8 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 9a98638419cc3072aab942ae3e81d7cf393056b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1(QeZ)7=@3!Zj@00LtN|zDK9`J-XN4_tP*SzE7zlGyACJ~f>yA*-0vND1)he7 z;R?=gTUG3&7u+BweoyvEod4MIm$a@u0H(j5J^>B^beKi&-(k^^=J<5X0=T`<~qQ760fP((y6twO}Bb5-fH|3!#F#yClXFgy_Qa$9md&Ve9y+OP>k)J zzQl&Zq)xR|0!pAxK-TX2$hl(wf?0L_K3o)&d{N}QE+46<%)MVW@d((ZXN|X5U>Ze! zk0QHxhGY6q@EjRl;FQ|KhuCKxMZO30onk=GIrWI8oS(4fHIGJ(ZCpof-1D9hUSWtn zog=E;Nz)ztjNJPi-x5=D`O5f9ta#UpaI~!-k*6j5A7PAT_pQRNYxhWUwmT-n6??hB z71>WBpOCEjZjs)QBg!~}Gh|`3}iZS;~&#i*z?U^P}p;89<|VoTG-|j*43W(=({4nOZK-6`w-^l zZiV@6z5y9)2c(iUJ$;aN;Mil!V?Grb(<*FTSO>9f#*$Pmj*Nr2UB(ssTQpG(B6sZP zF%SC{azWIAi`ww(k-O}@$rGP*l(lzJ-q)Z7BHfx~s!foP*8kb|{r?*@BE3~5palMufN2lT27S8htlr?3Sw3NY!z@YSN~hMsBKRS| e^UXgDd7Lm*JgL{xDQlQ?Bfw(NLJ9m;0>1%>f*@A_ diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 46cbfa90f..95b6143af 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ # Description -- [ ] Source branch in your fork has meaningful name (not `main`) +- [ Iss2062_records ] Source branch in your fork has meaningful name (not `main`) Fixes Issue: @@ -11,9 +11,9 @@ These items can be completed after PR is created. (Check any items that are not applicable (NA) for this PR) -- [ ] JavaScript implementation -- [ ] Python implementation (NA if HTML beautifier) -- [ ] Added Tests to data file(s) -- [ ] Added command-line option(s) (NA if -- [ ] README.md documents new feature/option(s) +- [X] JavaScript implementation +- [X] Python implementation (NA if HTML beautifier) +- [X] Added Tests to data file(s) +- [NA] Added command-line option(s) (NA if +- [NA] README.md documents new feature/option(s) diff --git a/js/src/javascript/beautifier.js b/js/src/javascript/beautifier.js index 51cd10d8e..730080a32 100644 --- a/js/src/javascript/beautifier.js +++ b/js/src/javascript/beautifier.js @@ -720,6 +720,9 @@ Beautifier.prototype.handle_start_block = function(current_token) { } } + // Issue #2062 check to see if defining a new Record type - #{} + // Conditional on line 774 uses this variable + var is_record = this._flags.last_word === '#'; var empty_braces = !next_token.comments_before && next_token.text === '}'; var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' && this._flags.last_token.type === TOKEN.END_EXPR; @@ -768,7 +771,7 @@ Beautifier.prototype.handle_start_block = function(current_token) { if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) { this.print_newline(); } else { - this._output.space_before_token = true; + this._output.space_before_token = !is_record; } } } diff --git a/python/jsbeautifier/javascript/beautifier.py b/python/jsbeautifier/javascript/beautifier.py index efeb584b4..381d18f8b 100644 --- a/python/jsbeautifier/javascript/beautifier.py +++ b/python/jsbeautifier/javascript/beautifier.py @@ -766,6 +766,10 @@ def handle_start_block(self, current_token): if reserved_array(self._flags.last_token.previous, ["class", "extends"]): self._flags.class_start_block = True + # Issue #2062 check to see if defining a new Record type - #{} + # Conditional on line 843 uses this variable + is_record = self._flags.last_token.text == "#" + empty_braces = ( (next_token is not None) and next_token.comments_before is None @@ -836,7 +840,7 @@ def handle_start_block(self, current_token): ): self.print_newline() else: - self._output.space_before_token = True + self._output.space_before_token = not is_record self.print_token(current_token) self.indent() diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index 367c3e231..cfe9606cf 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -5368,6 +5368,7 @@ exports.test_data = { { fragment: true, unchanged: ' < div' }, { input: 'a = 1', output: 'a = 1' }, { input: 'a=1', output: 'a = 1' }, + { input: '#{ hello: "world" }', output: '#{\n hello: "world"\n}' }, { unchanged: '(3) / 2' }, { unchanged: '["a", "b"].join("")' }, { unchanged: 'a();\n\nb();' }, From 38f41676f0e354bf8f7ae83bbcfc644ca209ac64 Mon Sep 17 00:00:00 2001 From: abuco <52994294+abu-co@users.noreply.github.com> Date: Tue, 8 Nov 2022 12:10:34 +1100 Subject: [PATCH 08/37] Fix formatting related to - Fix formatting for `
  • ` tags inside `` tags inside `
  • ` tags - Allow unclosed `

    ` tags if followed by a `

    ` tag --- js/src/html/beautifier.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/html/beautifier.js b/js/src/html/beautifier.js index 4e2f7552b..f6decd381 100644 --- a/js/src/html/beautifier.js +++ b/js/src/html/beautifier.js @@ -765,7 +765,7 @@ Beautifier.prototype._calcluate_parent_multiline = function(printer, parser_toke }; //To be used for

    tag special case: -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']; +var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul']; var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video']; Beautifier.prototype._do_optional_end_element = function(parser_token) { @@ -788,7 +788,7 @@ Beautifier.prototype._do_optional_end_element = function(parser_token) { } else if (parser_token.tag_name === 'li') { // 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. - result = result || this._tag_stack.try_pop('li', ['ol', 'ul']); + result = result || this._tag_stack.try_pop('li', ['ol', 'ul', 'menu']); } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') { // 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. From a5d627a47c13d02e1f93b6629afa6639c16bff82 Mon Sep 17 00:00:00 2001 From: abuco <52994294+abu-co@users.noreply.github.com> Date: Tue, 8 Nov 2022 12:11:13 +1100 Subject: [PATCH 09/37] Add tests related to

    --- test/data/html/tests.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/data/html/tests.js b/test/data/html/tests.js index f78f2696c..1bfdc8aff 100644 --- a/test/data/html/tests.js +++ b/test/data/html/tests.js @@ -1758,6 +1758,14 @@ exports.test_data = { '
  • test content', '' ] + }, { + unchanged: [ + '', + '
  • test content', + '
  • test content', + '
  • test content', + '
  • ' + ] }, { unchanged: [ '
      ', @@ -1773,6 +1781,30 @@ exports.test_data = { ' test content', '
    ' ] + }, { + unchanged: [ + '', + '
  • ', + ' test content', + '
  • ', + '
      ', + '
    1. level 1 check', + '
    2. ', + ' ', + '
    3. level 2 check', + '
    4. ', + '
        ', + '
      • level 3 check', + '
      ', + '
    5. ', + ' test content', + '
    6. ', + '
    ', + '
  • test content', + '
  • ', + ' test content', + '
  • ' + ] }, { unchanged: [ '
    ', From c90470061c775a42b9c7a99840d2a5d436a89407 Mon Sep 17 00:00:00 2001 From: Muhammad Hammad Date: Thu, 17 Nov 2022 18:43:39 -0500 Subject: [PATCH 10/37] fix - semicolon followed by block statement doesnt have new line This change makes sure that a new line is added everytime a semicolon is followed by a block statement fixes #1852 --- js/src/javascript/beautifier.js | 2 +- python/jsbeautifier/javascript/beautifier.py | 2 +- test/data/javascript/node.mustache | 2 +- test/data/javascript/tests.js | 27 ++++++++++++++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/js/src/javascript/beautifier.js b/js/src/javascript/beautifier.js index 51cd10d8e..dfec38351 100644 --- a/js/src/javascript/beautifier.js +++ b/js/src/javascript/beautifier.js @@ -765,7 +765,7 @@ Beautifier.prototype.handle_start_block = function(current_token) { } } if (this._flags.last_token.type !== TOKEN.OPERATOR && this._flags.last_token.type !== TOKEN.START_EXPR) { - if (this._flags.last_token.type === TOKEN.START_BLOCK && !this._flags.inline_frame) { + if (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.SEMICOLON]) && !this._flags.inline_frame) { this.print_newline(); } else { this._output.space_before_token = true; diff --git a/python/jsbeautifier/javascript/beautifier.py b/python/jsbeautifier/javascript/beautifier.py index efeb584b4..69f2dbdaf 100644 --- a/python/jsbeautifier/javascript/beautifier.py +++ b/python/jsbeautifier/javascript/beautifier.py @@ -831,7 +831,7 @@ def handle_start_block(self, current_token): elif self._flags.last_token.type not in [TOKEN.OPERATOR, TOKEN.START_EXPR]: if ( - self._flags.last_token.type == TOKEN.START_BLOCK + self._flags.last_token.type in [TOKEN.START_BLOCK, TOKEN.SEMICOLON] and not self._flags.inline_frame ): self.print_newline() diff --git a/test/data/javascript/node.mustache b/test/data/javascript/node.mustache index 0681e91f2..775d849f3 100644 --- a/test/data/javascript/node.mustache +++ b/test/data/javascript/node.mustache @@ -192,7 +192,7 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, 'if (foo)' + eo + '{}' + ec + 'else /regex/.test();'); test_fragment('if (foo)' + to + '{', 'if (foo)' + eo + '{'); test_fragment('foo' + to + '{', 'foo' + eo + '{'); - test_fragment('return;' + to + '{', 'return;' + eo + '{'); + test_fragment('return;' + to + '{', 'return;\n{'); bt( 'function x()' + to + '{\n foo();\n}zzz', 'function x()' + eo +'{\n foo();\n}\nzzz'); bt( 'var a = new function a()' + to + '{};', 'var a = new function a()' + eo + '{};'); bt( 'var a = new function a()' + to + ' {},\n b = new function b()' + to + ' {};', diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index 367c3e231..d9e6c41f2 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -3367,6 +3367,33 @@ exports.test_data = { ' });', 'var test = 1;' ] + }, { + comment: "Issue #1852 - semicolon followed by block statement", + unchanged: [ + '(function() {', + ' some_code_here();', + ' {', + ' /* IE11 let bug bypass */', + ' let index;', + ' for (index in a) {', + ' a[index];', + ' }', + ' }', + '})();' + ] + }, { + comment: "Issue #1852 - semicolon followed by block statement 2", + input: [ + 'let x = { A: 1 }; { console.log("hello"); }' + ], + output: [ + 'let x = {', + ' A: 1', + '};', + '{', + ' console.log("hello");', + '}' + ] }, { comment: "Issue #772", input: [ From 1430b97c842939ecff185bd1673653a31cbb0084 Mon Sep 17 00:00:00 2001 From: Antonius Anggito Arissaputro Date: Fri, 18 Nov 2022 18:24:27 +0700 Subject: [PATCH 11/37] Revert PULL_REQUEST_TEMPLATE.md changes --- .github/PULL_REQUEST_TEMPLATE.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 95b6143af..46cbfa90f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ # Description -- [ Iss2062_records ] Source branch in your fork has meaningful name (not `main`) +- [ ] Source branch in your fork has meaningful name (not `main`) Fixes Issue: @@ -11,9 +11,9 @@ These items can be completed after PR is created. (Check any items that are not applicable (NA) for this PR) -- [X] JavaScript implementation -- [X] Python implementation (NA if HTML beautifier) -- [X] Added Tests to data file(s) -- [NA] Added command-line option(s) (NA if -- [NA] README.md documents new feature/option(s) +- [ ] JavaScript implementation +- [ ] Python implementation (NA if HTML beautifier) +- [ ] Added Tests to data file(s) +- [ ] Added command-line option(s) (NA if +- [ ] README.md documents new feature/option(s) From 7c050207859d2eea7ffc30ebb3bf62aa6b34586c Mon Sep 17 00:00:00 2001 From: Antonius Anggito Arissaputro Date: Fri, 25 Nov 2022 02:54:44 +0700 Subject: [PATCH 12/37] Change js and py jsbeautifier for record as START_BLOCK token --- js/src/javascript/beautifier.js | 5 +---- js/src/javascript/tokenizer.js | 14 ++++++++++++++ python/jsbeautifier/javascript/beautifier.py | 6 +----- python/jsbeautifier/javascript/tokenizer.py | 13 +++++++++++++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/js/src/javascript/beautifier.js b/js/src/javascript/beautifier.js index 333ec617f..dfec38351 100644 --- a/js/src/javascript/beautifier.js +++ b/js/src/javascript/beautifier.js @@ -720,9 +720,6 @@ Beautifier.prototype.handle_start_block = function(current_token) { } } - // Issue #2062 check to see if defining a new Record type - #{} - // Conditional on line 774 uses this variable - var is_record = this._flags.last_word === '#'; var empty_braces = !next_token.comments_before && next_token.text === '}'; var empty_anonymous_function = empty_braces && this._flags.last_word === 'function' && this._flags.last_token.type === TOKEN.END_EXPR; @@ -771,7 +768,7 @@ Beautifier.prototype.handle_start_block = function(current_token) { if (in_array(this._flags.last_token.type, [TOKEN.START_BLOCK, TOKEN.SEMICOLON]) && !this._flags.inline_frame) { this.print_newline(); } else { - this._output.space_before_token = !is_record; + this._output.space_before_token = true; } } } diff --git a/js/src/javascript/tokenizer.js b/js/src/javascript/tokenizer.js index 18d3cfc6a..80e74a88f 100644 --- a/js/src/javascript/tokenizer.js +++ b/js/src/javascript/tokenizer.js @@ -167,6 +167,7 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // token = token || this._read_non_javascript(c); token = token || this._read_string(c); + token = token || this._read_pair(c, this._input.peek(1)); // Issue #2062 hack for record type '#{' token = token || this._read_word(previous_token); token = token || this._read_singles(c); token = token || this._read_comment(c); @@ -225,6 +226,19 @@ Tokenizer.prototype._read_singles = function(c) { return token; }; +Tokenizer.prototype._read_pair = function(c, d) { + var token = null; + if (c === '#' && d === '{') { + token = this._create_token(TOKEN.START_BLOCK, c+d); + } + + if (token) { + this._input.next(); + this._input.next(); + } + return token; +}; + Tokenizer.prototype._read_punctuation = function() { var resulting_string = this.__patterns.punct.read(); diff --git a/python/jsbeautifier/javascript/beautifier.py b/python/jsbeautifier/javascript/beautifier.py index 9ab1343cf..69f2dbdaf 100644 --- a/python/jsbeautifier/javascript/beautifier.py +++ b/python/jsbeautifier/javascript/beautifier.py @@ -766,10 +766,6 @@ def handle_start_block(self, current_token): if reserved_array(self._flags.last_token.previous, ["class", "extends"]): self._flags.class_start_block = True - # Issue #2062 check to see if defining a new Record type - #{} - # Conditional on line 843 uses this variable - is_record = self._flags.last_token.text == "#" - empty_braces = ( (next_token is not None) and next_token.comments_before is None @@ -840,7 +836,7 @@ def handle_start_block(self, current_token): ): self.print_newline() else: - self._output.space_before_token = not is_record + self._output.space_before_token = True self.print_token(current_token) self.indent() diff --git a/python/jsbeautifier/javascript/tokenizer.py b/python/jsbeautifier/javascript/tokenizer.py index e53e910f8..fb5ae45ec 100644 --- a/python/jsbeautifier/javascript/tokenizer.py +++ b/python/jsbeautifier/javascript/tokenizer.py @@ -220,6 +220,7 @@ def _get_next_token(self, previous_token, open_token): token = token or self._read_non_javascript(c) token = token or self._read_string(c) + token = token or self._read_pair(c, self._input.peek(1)) # Issue #2062 hack for record type '#{' token = token or self._read_word(previous_token) token = token or self._read_singles(c) token = token or self._read_comment(c) @@ -257,6 +258,18 @@ def _read_singles(self, c): return token + def _read_pair(self, c, d): + token = None + + if c == "#" and d == "{": + token = self._create_token(TOKEN.START_BLOCK, c+d) + + if token is not None: + self._input.next() + self._input.next() + + return token + def _read_word(self, previous_token): resulting_string = self._patterns.identifier.read() From 9f8042edc7503c2708c57862fbcca7f09d08cdc2 Mon Sep 17 00:00:00 2001 From: Antonius Anggito Arissaputro Date: Fri, 25 Nov 2022 04:18:45 +0700 Subject: [PATCH 13/37] Update jsbeautifier record data type tests --- test/data/javascript/tests.js | 47 ++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index 411691696..8599a3231 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -5377,6 +5377,52 @@ exports.test_data = { ] } ] + }, { + name: "Record data type", + description: "", + tests: [{ + comment: 'regular record with primitive', + input: 'a = #{ b:"c", d:1, e:true };', + output: [ + 'a = #{', + ' b: "c",', + ' d: 1,', + ' e: true', + '};' + ] + }, + { + comment: 'nested record', + input: 'a = #{b:#{ c:1,d:2,}, e:"f"};', + output: [ + 'a = #{', + ' b: #{', + ' c: 1,', + ' d: 2,', + ' },', + ' e: "f"', + '};' + ] + }, + { + comment: '# not directly followed by { is not handled as record', + unchanged: [ + 'a = # {', + ' b: 1,', + ' d: true', + '};' + ] + }, + { + comment: 'example of already valid and beautified record', + unchanged: [ + 'a = #{', + ' b: 1,', + ' d: true', + '};' + ] + }, + ] }, { // ======================================================= // New tests groups should be added above this line. @@ -5395,7 +5441,6 @@ exports.test_data = { { fragment: true, unchanged: ' < div' }, { input: 'a = 1', output: 'a = 1' }, { input: 'a=1', output: 'a = 1' }, - { input: '#{ hello: "world" }', output: '#{\n hello: "world"\n}' }, { unchanged: '(3) / 2' }, { unchanged: '["a", "b"].join("")' }, { unchanged: 'a();\n\nb();' }, From 93927c78b757722aea9770a284064eaabd65c80a Mon Sep 17 00:00:00 2001 From: Antonius Anggito Arissaputro Date: Fri, 25 Nov 2022 14:11:37 +0700 Subject: [PATCH 14/37] Fix typo on record test --- test/data/javascript/tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index 8599a3231..25967eea8 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -5421,7 +5421,7 @@ exports.test_data = { ' d: true', '};' ] - }, + } ] }, { // ======================================================= From a7003210571d8fe0597a4f4267d87e08517607a0 Mon Sep 17 00:00:00 2001 From: Antonius Anggito Arissaputro Date: Fri, 25 Nov 2022 14:50:28 +0700 Subject: [PATCH 15/37] Minor style check --- js/src/javascript/tokenizer.js | 2 +- python/jsbeautifier/javascript/tokenizer.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/js/src/javascript/tokenizer.js b/js/src/javascript/tokenizer.js index 80e74a88f..ee35c571f 100644 --- a/js/src/javascript/tokenizer.js +++ b/js/src/javascript/tokenizer.js @@ -229,7 +229,7 @@ Tokenizer.prototype._read_singles = function(c) { Tokenizer.prototype._read_pair = function(c, d) { var token = null; if (c === '#' && d === '{') { - token = this._create_token(TOKEN.START_BLOCK, c+d); + token = this._create_token(TOKEN.START_BLOCK, c + d); } if (token) { diff --git a/python/jsbeautifier/javascript/tokenizer.py b/python/jsbeautifier/javascript/tokenizer.py index fb5ae45ec..a121a31ac 100644 --- a/python/jsbeautifier/javascript/tokenizer.py +++ b/python/jsbeautifier/javascript/tokenizer.py @@ -220,7 +220,9 @@ def _get_next_token(self, previous_token, open_token): token = token or self._read_non_javascript(c) token = token or self._read_string(c) - token = token or self._read_pair(c, self._input.peek(1)) # Issue #2062 hack for record type '#{' + token = token or self._read_pair( + c, self._input.peek(1) + ) # Issue #2062 hack for record type '#{' token = token or self._read_word(previous_token) token = token or self._read_singles(c) token = token or self._read_comment(c) @@ -262,7 +264,7 @@ def _read_pair(self, c, d): token = None if c == "#" and d == "{": - token = self._create_token(TOKEN.START_BLOCK, c+d) + token = self._create_token(TOKEN.START_BLOCK, c + d) if token is not None: self._input.next() From 40020a4b73850b8c3e7dc4f31f03cf1fd79a3a05 Mon Sep 17 00:00:00 2001 From: Antonius Anggito Arissaputro Date: Sun, 27 Nov 2022 23:40:09 +0700 Subject: [PATCH 16/37] Bring back .DS_Store from main --- .DS_Store | Bin 0 -> 8196 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9a98638419cc3072aab942ae3e81d7cf393056b6 GIT binary patch literal 8196 zcmeI1(QeZ)7=@3!Zj@00LtN|zDK9`J-XN4_tP*SzE7zlGyACJ~f>yA*-0vND1)he7 z;R?=gTUG3&7u+BweoyvEod4MIm$a@u0H(j5J^>B^beKi&-(k^^=J<5X0=T`<~qQ760fP((y6twO}Bb5-fH|3!#F#yClXFgy_Qa$9md&Ve9y+OP>k)J zzQl&Zq)xR|0!pAxK-TX2$hl(wf?0L_K3o)&d{N}QE+46<%)MVW@d((ZXN|X5U>Ze! zk0QHxhGY6q@EjRl;FQ|KhuCKxMZO30onk=GIrWI8oS(4fHIGJ(ZCpof-1D9hUSWtn zog=E;Nz)ztjNJPi-x5=D`O5f9ta#UpaI~!-k*6j5A7PAT_pQRNYxhWUwmT-n6??hB z71>WBpOCEjZjs)QBg!~}Gh|`3}iZS;~&#i*z?U^P}p;89<|VoTG-|j*43W(=({4nOZK-6`w-^l zZiV@6z5y9)2c(iUJ$;aN;Mil!V?Grb(<*FTSO>9f#*$Pmj*Nr2UB(ssTQpG(B6sZP zF%SC{azWIAi`ww(k-O}@$rGP*l(lzJ-q)Z7BHfx~s!foP*8kb|{r?*@BE3~5palMufN2lT27S8htlr?3Sw3NY!z@YSN~hMsBKRS| e^UXgDd7Lm*JgL{xDQlQ?Bfw(NLJ9m;0>1%>f*@A_ literal 0 HcmV?d00001 From 6d032d373971bd68b1df88932690239f7cd5b123 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Sun, 25 Dec 2022 12:53:00 +1100 Subject: [PATCH 17/37] docs: Fix a few typos There are small typos in: - python/jsbeautifier/javascript/beautifier.py - tools/template/beautify.wrapper.js Fixes: - Should read `conditional` rather than `conditionial`. - Should read `overridden` rather than `overriden`. Signed-off-by: Tim Gates --- python/jsbeautifier/javascript/beautifier.py | 2 +- tools/template/beautify.wrapper.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/jsbeautifier/javascript/beautifier.py b/python/jsbeautifier/javascript/beautifier.py index 69f2dbdaf..647a2df98 100644 --- a/python/jsbeautifier/javascript/beautifier.py +++ b/python/jsbeautifier/javascript/beautifier.py @@ -1208,7 +1208,7 @@ def handle_string(self, current_token): or current_token.previous.text == ")" ) ): - # This conditionial checks backtick strings and makes no changes + # This conditional checks backtick strings and makes no changes pass elif self.start_of_statement(current_token): # The conditional starts the statement if appropriate. diff --git a/tools/template/beautify.wrapper.js b/tools/template/beautify.wrapper.js index 696ab560f..049bc0bd5 100644 --- a/tools/template/beautify.wrapper.js +++ b/tools/template/beautify.wrapper.js @@ -59,7 +59,7 @@ } } space_after_anon_function (default false) - should the space before an anonymous function's parens be added, "function()" vs "function ()", - NOTE: This option is overriden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) + NOTE: This option is overridden by jslint_happy (i.e. if jslint_happy is true, space_after_anon_function is true by design) brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none" | any of the former + ",preserve-inline" put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are. From fd8c8f700762a9dcec037a8683fc570cbede1a54 Mon Sep 17 00:00:00 2001 From: Mogyuchi Date: Tue, 29 Nov 2022 11:33:05 +0000 Subject: [PATCH 18/37] Delete .DS_Store --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 9a98638419cc3072aab942ae3e81d7cf393056b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1(QeZ)7=@3!Zj@00LtN|zDK9`J-XN4_tP*SzE7zlGyACJ~f>yA*-0vND1)he7 z;R?=gTUG3&7u+BweoyvEod4MIm$a@u0H(j5J^>B^beKi&-(k^^=J<5X0=T`<~qQ760fP((y6twO}Bb5-fH|3!#F#yClXFgy_Qa$9md&Ve9y+OP>k)J zzQl&Zq)xR|0!pAxK-TX2$hl(wf?0L_K3o)&d{N}QE+46<%)MVW@d((ZXN|X5U>Ze! zk0QHxhGY6q@EjRl;FQ|KhuCKxMZO30onk=GIrWI8oS(4fHIGJ(ZCpof-1D9hUSWtn zog=E;Nz)ztjNJPi-x5=D`O5f9ta#UpaI~!-k*6j5A7PAT_pQRNYxhWUwmT-n6??hB z71>WBpOCEjZjs)QBg!~}Gh|`3}iZS;~&#i*z?U^P}p;89<|VoTG-|j*43W(=({4nOZK-6`w-^l zZiV@6z5y9)2c(iUJ$;aN;Mil!V?Grb(<*FTSO>9f#*$Pmj*Nr2UB(ssTQpG(B6sZP zF%SC{azWIAi`ww(k-O}@$rGP*l(lzJ-q)Z7BHfx~s!foP*8kb|{r?*@BE3~5palMufN2lT27S8htlr?3Sw3NY!z@YSN~hMsBKRS| e^UXgDd7Lm*JgL{xDQlQ?Bfw(NLJ9m;0>1%>f*@A_ From 88033caeab7b6e3d09e0325b72bca2ed6784abe4 Mon Sep 17 00:00:00 2001 From: Knoxell <85034894+knoxell@users.noreply.github.com> Date: Fri, 17 Feb 2023 14:40:40 +0100 Subject: [PATCH 19/37] use correct variable name --- python/cssbeautifier/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/cssbeautifier/__init__.py b/python/cssbeautifier/__init__.py index 97efd86e0..edbbcfbaf 100644 --- a/python/cssbeautifier/__init__.py +++ b/python/cssbeautifier/__init__.py @@ -38,7 +38,7 @@ def beautify(string, opts=None): def beautify_file(file_name, opts=None): _main = __import__("cssbeautifier", globals(), locals(), ["_main"])._main - return _main.beautify_file(file, opts) + return _main.beautify_file(file_name, opts) def usage(stream=sys.stdout): From 9f8086613b9d2cf83f0e89d1a863dc4e4dcdf0cb Mon Sep 17 00:00:00 2001 From: Rouak-stha Date: Sat, 4 Mar 2023 16:34:19 +0545 Subject: [PATCH 20/37] Fixed #2133 Theme Toggle on without_codemirror Mode --- web/onload.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/onload.js b/web/onload.js index 208f38563..56d470311 100644 --- a/web/onload.js +++ b/web/onload.js @@ -16,7 +16,7 @@ $(function() { the.editor = CodeMirror.fromTextArea(textArea, { lineNumbers: true }); - setPreferredColorScheme(); + set_editor_mode(); the.editor.focus(); @@ -36,7 +36,8 @@ $(function() { } }); } - + + setPreferredColorScheme(); $(window).bind('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.keyCode === 13) { From 7032cbd4253c60ee11a63f74d26d2d398c7cb1bd Mon Sep 17 00:00:00 2001 From: MHO <17177411+Itemshopp@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:40:46 +0200 Subject: [PATCH 21/37] Implementation of a insideAtApply variable Implementation of a insideAtApply variable to determine if it is a Tailwind ruleset and avoid whitespace after variant [ currently thinking it is a property ] --- js/src/css/beautifier.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/js/src/css/beautifier.js b/js/src/css/beautifier.js index a0fa2bd64..0ff17b8db 100644 --- a/js/src/css/beautifier.js +++ b/js/src/css/beautifier.js @@ -195,6 +195,7 @@ Beautifier.prototype.beautify = function() { var enteringConditionalGroup = false; var insideAtExtend = false; var insideAtImport = false; + var insideAtApply = false; var insideScssMap = false; var topCharacter = this._ch; var insideNonSemiColonValues = false; @@ -276,6 +277,11 @@ Beautifier.prototype.beautify = function() { insideAtImport = true; } + // might be a tailwindcss ruleset + if (variableOrRule === 'apply') { + insideAtApply = true; + } + // might be a nesting at-rule if (variableOrRule in this.NESTED_AT_RULE) { this._nestedLevel += 1; @@ -339,6 +345,7 @@ Beautifier.prototype.beautify = function() { } insideAtImport = false; insideAtExtend = false; + insideAtApply = false; if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -372,9 +379,10 @@ Beautifier.prototype.beautify = function() { } } - if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && parenLevel === 0) { + if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && !insideAtApply && parenLevel === 0) { // 'property: value' delimiter // which could be in a conditional group query + this.print_string(':'); if (!insidePropertyValue) { insidePropertyValue = true; From 39632ea63380a0e304ec76f75626815a2b010bdd Mon Sep 17 00:00:00 2001 From: MHO <17177411+Itemshopp@users.noreply.github.com> Date: Tue, 18 Apr 2023 09:54:18 +0200 Subject: [PATCH 22/37] moved insideAtApply boolean set to false --- js/src/css/beautifier.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/css/beautifier.js b/js/src/css/beautifier.js index 0ff17b8db..06d6fdd68 100644 --- a/js/src/css/beautifier.js +++ b/js/src/css/beautifier.js @@ -345,7 +345,6 @@ Beautifier.prototype.beautify = function() { } insideAtImport = false; insideAtExtend = false; - insideAtApply = false; if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -421,6 +420,7 @@ Beautifier.prototype.beautify = function() { } insideAtExtend = false; insideAtImport = false; + insideAtApply = false; this.print_string(this._ch); this.eatWhitespace(true); From 40e55812c2f6c632c7808eef5799ad628ff24299 Mon Sep 17 00:00:00 2001 From: MHO <17177411+Itemshopp@users.noreply.github.com> Date: Wed, 19 Apr 2023 09:35:16 +0200 Subject: [PATCH 23/37] Replaced insideAtApply with insideNonNestedAtRule --- js/src/css/beautifier.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/js/src/css/beautifier.js b/js/src/css/beautifier.js index 06d6fdd68..5f189e5cc 100644 --- a/js/src/css/beautifier.js +++ b/js/src/css/beautifier.js @@ -195,7 +195,7 @@ Beautifier.prototype.beautify = function() { var enteringConditionalGroup = false; var insideAtExtend = false; var insideAtImport = false; - var insideAtApply = false; + var insideNonNestedAtRule = false; var insideScssMap = false; var topCharacter = this._ch; var insideNonSemiColonValues = false; @@ -277,11 +277,6 @@ Beautifier.prototype.beautify = function() { insideAtImport = true; } - // might be a tailwindcss ruleset - if (variableOrRule === 'apply') { - insideAtApply = true; - } - // might be a nesting at-rule if (variableOrRule in this.NESTED_AT_RULE) { this._nestedLevel += 1; @@ -293,6 +288,10 @@ Beautifier.prototype.beautify = function() { insidePropertyValue = true; this.indent(); } + // might be a non-nested at-rule + } else if( ! ( variableOrRule in this.NESTED_AT_RULE ) ) { + insideNonNestedAtRule = true; + } } } else if (this._ch === '#' && this._input.peek() === '{') { this.preserveSingleSpace(isAfterSpace); @@ -345,6 +344,7 @@ Beautifier.prototype.beautify = function() { } insideAtImport = false; insideAtExtend = false; + insideNonNestedAtRule = false; if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -378,7 +378,7 @@ Beautifier.prototype.beautify = function() { } } - if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && !insideAtApply && parenLevel === 0) { + if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && !insideNonNestedAtRule && parenLevel === 0) { // 'property: value' delimiter // which could be in a conditional group query @@ -420,7 +420,7 @@ Beautifier.prototype.beautify = function() { } insideAtExtend = false; insideAtImport = false; - insideAtApply = false; + insideNonNestedAtRule = false; this.print_string(this._ch); this.eatWhitespace(true); @@ -485,7 +485,7 @@ Beautifier.prototype.beautify = function() { } else if (this._ch === ',') { this.print_string(this._ch); this.eatWhitespace(true); - if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) { + if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend && !insideNonNestedAtRule) { this._output.add_new_line(); } else { this._output.space_before_token = true; From 863916c1a634601c84e3ea48a151706fa4b5144c Mon Sep 17 00:00:00 2001 From: MHO <17177411+Itemshopp@users.noreply.github.com> Date: Sun, 23 Apr 2023 13:11:53 +0200 Subject: [PATCH 24/37] Update test file --- test/data/css/tests.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/data/css/tests.js b/test/data/css/tests.js index 34703a0ec..d4874ec88 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -1995,6 +1995,17 @@ exports.test_data = { unchanged: 'p {\n color: blue;\n}' }] }, { + name: "Issue #2012, #2142", + description: "Avoid whitespace between first colon and next character in non nested at-rules", + options: [], + tests: [{ + unchanged: '@extend .btn-blue:hover;' + }, { + unchanged: '@import url("chrome://communicator/skin/");' + }, { + unchanged: '@apply w-4 lg:w-10 space-y-3 lg:space-x-12;', + }] + }, { } ] From bda9e958fa509b95a6e9d5c3bdcec4bcd49a4a2a Mon Sep 17 00:00:00 2001 From: MHO Date: Sun, 23 Apr 2023 13:24:48 +0200 Subject: [PATCH 25/37] corrected error after test --- js/src/css/beautifier.js | 2 +- test/data/css/tests.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/css/beautifier.js b/js/src/css/beautifier.js index 5f189e5cc..615162ec9 100644 --- a/js/src/css/beautifier.js +++ b/js/src/css/beautifier.js @@ -287,7 +287,7 @@ Beautifier.prototype.beautify = function() { } else if (!insideRule && parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { insidePropertyValue = true; this.indent(); - } + // might be a non-nested at-rule } else if( ! ( variableOrRule in this.NESTED_AT_RULE ) ) { insideNonNestedAtRule = true; diff --git a/test/data/css/tests.js b/test/data/css/tests.js index d4874ec88..e7d41c0ae 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -2003,7 +2003,7 @@ exports.test_data = { }, { unchanged: '@import url("chrome://communicator/skin/");' }, { - unchanged: '@apply w-4 lg:w-10 space-y-3 lg:space-x-12;', + unchanged: '@apply w-4 lg:w-10 space-y-3 lg:space-x-12;' }] }, { From d754bd3114b6814311818425ad16a8b17f45eab6 Mon Sep 17 00:00:00 2001 From: MHO Date: Sun, 23 Apr 2023 15:13:44 +0200 Subject: [PATCH 26/37] Improved less and sass variable identification with at rule pairing genericity --- js/src/css/beautifier.js | 78 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/js/src/css/beautifier.js b/js/src/css/beautifier.js index 615162ec9..afbfc81a9 100644 --- a/js/src/css/beautifier.js +++ b/js/src/css/beautifier.js @@ -54,18 +54,18 @@ function Beautifier(source_text, options) { // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule this.NESTED_AT_RULE = { - "@page": true, - "@font-face": true, - "@keyframes": true, + "page": true, + "font-face": true, + "keyframes": true, // also in CONDITIONAL_GROUP_RULE below - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.CONDITIONAL_GROUP_RULE = { - "@media": true, - "@supports": true, - "@document": true + "media": true, + "supports": true, + "document": true }; this.NON_SEMICOLON_NEWLINE_PROPERTY = [ "grid-template-areas", @@ -193,8 +193,6 @@ Beautifier.prototype.beautify = function() { // label { content: blue } var insidePropertyValue = false; var enteringConditionalGroup = false; - var insideAtExtend = false; - var insideAtImport = false; var insideNonNestedAtRule = false; var insideScssMap = false; var topCharacter = this._ch; @@ -250,10 +248,32 @@ Beautifier.prototype.beautify = function() { // Ensures any new lines following the comment are preserved this.eatWhitespace(true); - } else if (this._ch === '@' || this._ch === '$') { + } else if (this._ch === '$') { this.preserveSingleSpace(isAfterSpace); - // deal with less propery mixins @{...} + this.print_string(this._ch); + + // strip trailing space, if present, for hash property checks + var variable = this._input.peekUntilAfter(/[: ,;{}()[\]\/='"]/g); + + if (variable.match(/[ :]$/)) { + // we have a variable or pseudo-class, add it and insert one space before continuing + variable = this.eatString(": ").replace(/\s$/, ''); + this.print_string(variable); + this._output.space_before_token = true; + } + + variable = variable.replace(/\s$/, ''); + + // might be sass variable + if(parenLevel === 0 && variable.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); + } + } else if (this._ch === '@') { + this.preserveSingleSpace(isAfterSpace); + + // deal with less property mixins @{...} if (this._input.peek() === '{') { this.print_string(this._ch + this.eatString('}')); } else { @@ -271,25 +291,20 @@ Beautifier.prototype.beautify = function() { variableOrRule = variableOrRule.replace(/\s$/, ''); - if (variableOrRule === 'extend') { - insideAtExtend = true; - } else if (variableOrRule === 'import') { - insideAtImport = true; - } + // might be less variable + if(parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { + insidePropertyValue = true; + this.indent(); - // might be a nesting at-rule - if (variableOrRule in this.NESTED_AT_RULE) { + // might be a nesting at-rule + } else if (variableOrRule in this.NESTED_AT_RULE) { this._nestedLevel += 1; if (variableOrRule in this.CONDITIONAL_GROUP_RULE) { enteringConditionalGroup = true; } - // might be less variable - } else if (!insideRule && parenLevel === 0 && variableOrRule.indexOf(':') !== -1) { - insidePropertyValue = true; - this.indent(); // might be a non-nested at-rule - } else if( ! ( variableOrRule in this.NESTED_AT_RULE ) ) { + } else if( parenLevel === 0 && !insidePropertyValue ) { insideNonNestedAtRule = true; } } @@ -302,6 +317,9 @@ Beautifier.prototype.beautify = function() { this.outdent(); } + // non nested at rule becomes nested + insideNonNestedAtRule = false; + // when entering conditional groups, only rulesets are allowed if (enteringConditionalGroup) { enteringConditionalGroup = false; @@ -342,9 +360,7 @@ Beautifier.prototype.beautify = function() { if (previous_ch === '{') { this._output.trim(true); } - insideAtImport = false; - insideAtExtend = false; - insideNonNestedAtRule = false; + if (insidePropertyValue) { this.outdent(); insidePropertyValue = false; @@ -378,7 +394,7 @@ Beautifier.prototype.beautify = function() { } } - if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideAtExtend && !insideNonNestedAtRule && parenLevel === 0) { + if ((insideRule || enteringConditionalGroup) && !(this._input.lookBack("&") || this.foundNestedPseudoClass()) && !this._input.lookBack("(") && !insideNonNestedAtRule && parenLevel === 0) { // 'property: value' delimiter // which could be in a conditional group query @@ -418,8 +434,6 @@ Beautifier.prototype.beautify = function() { this.outdent(); insidePropertyValue = false; } - insideAtExtend = false; - insideAtImport = false; insideNonNestedAtRule = false; this.print_string(this._ch); this.eatWhitespace(true); @@ -485,7 +499,7 @@ Beautifier.prototype.beautify = function() { } else if (this._ch === ',') { this.print_string(this._ch); this.eatWhitespace(true); - if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend && !insideNonNestedAtRule) { + if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideNonNestedAtRule) { this._output.add_new_line(); } else { this._output.space_before_token = true; From c6b813bd1fde6e79a56d2c0ae880b65b9030c058 Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Wed, 26 Apr 2023 18:23:32 -0700 Subject: [PATCH 27/37] Remove node 12 --- .github/workflows/main.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 78a185bfc..58847f299 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,16 +20,13 @@ jobs: python-version: [3.7, 3.8, 3.9, '3.10'] include: - python-version: 3.7 - node-version: 12 + node-version: 14 - python-version: 3.8 node-version: 14 - python-version: 3.9 node-version: 16 - python-version: '3.10' - node-version: 16 - exclude: - - os: windows - python-version: 2.7 + node-version: 18 steps: - uses: actions/checkout@v2 - name: Set up Node ${{ matrix.node-version }} From 4a3ea270b53e8558dca79059365d4fbfc7c7364a Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Wed, 26 Apr 2023 18:26:52 -0700 Subject: [PATCH 28/37] Clean up python formatting --- python/cssbeautifier/_main.py | 2 -- python/cssbeautifier/css/beautifier.py | 2 -- python/jsbeautifier/__init__.py | 2 -- python/jsbeautifier/core/directives.py | 1 - python/jsbeautifier/core/output.py | 1 - python/jsbeautifier/core/templatablepattern.py | 1 - python/jsbeautifier/javascript/beautifier.py | 1 - python/jsbeautifier/javascript/tokenizer.py | 3 --- 8 files changed, 13 deletions(-) diff --git a/python/cssbeautifier/_main.py b/python/cssbeautifier/_main.py index 88b9bf7a0..7af497c61 100644 --- a/python/cssbeautifier/_main.py +++ b/python/cssbeautifier/_main.py @@ -52,7 +52,6 @@ def beautify_file(file_name, opts=None): def usage(stream=sys.stdout): - print( "cssbeautifier.py@" + __version__ @@ -102,7 +101,6 @@ def usage(stream=sys.stdout): def main(): - argv = sys.argv[1:] try: diff --git a/python/cssbeautifier/css/beautifier.py b/python/cssbeautifier/css/beautifier.py index 1164d9ce4..caae0b126 100644 --- a/python/cssbeautifier/css/beautifier.py +++ b/python/cssbeautifier/css/beautifier.py @@ -67,7 +67,6 @@ def beautify_file(file_name, opts=default_options()): def usage(stream=sys.stdout): - print( "cssbeautifier.py@" + __version__ @@ -384,7 +383,6 @@ def beautify(self): if self._options.brace_style == "expand": self._output.add_new_line(True) elif self._ch == ":": - for i in range(0, len(self.NON_SEMICOLON_NEWLINE_PROPERTY)): if self._input.lookBack(self.NON_SEMICOLON_NEWLINE_PROPERTY[i]): insideNonSemiColonValues = True diff --git a/python/jsbeautifier/__init__.py b/python/jsbeautifier/__init__.py index 45e2248ab..36920ff65 100644 --- a/python/jsbeautifier/__init__.py +++ b/python/jsbeautifier/__init__.py @@ -87,7 +87,6 @@ def beautify_file(file_name, opts=default_options()): def usage(stream=sys.stdout): - print( "jsbeautifier.py@" + __version__ @@ -156,7 +155,6 @@ def usage(stream=sys.stdout): def main(): - argv = sys.argv[1:] try: diff --git a/python/jsbeautifier/core/directives.py b/python/jsbeautifier/core/directives.py index f8b28ae62..566a2db7c 100644 --- a/python/jsbeautifier/core/directives.py +++ b/python/jsbeautifier/core/directives.py @@ -27,7 +27,6 @@ class Directives: def __init__(self, start_block_pattern, end_block_pattern): - self.__directives_block_pattern = re.compile( start_block_pattern + r" beautify( \w+[:]\w+)+ " + end_block_pattern ) diff --git a/python/jsbeautifier/core/output.py b/python/jsbeautifier/core/output.py index e63fda1d9..d4d49e40c 100644 --- a/python/jsbeautifier/core/output.py +++ b/python/jsbeautifier/core/output.py @@ -204,7 +204,6 @@ def __add_column(self): class Output: def __init__(self, options, baseIndentString=""): - self.__indent_cache = IndentStringCache(options, baseIndentString) self.raw = False self._end_with_newline = options.end_with_newline diff --git a/python/jsbeautifier/core/templatablepattern.py b/python/jsbeautifier/core/templatablepattern.py index 33d6c51b7..995462824 100644 --- a/python/jsbeautifier/core/templatablepattern.py +++ b/python/jsbeautifier/core/templatablepattern.py @@ -171,7 +171,6 @@ def _read_template(self): resulting_string or self.__patterns.django_value.read() ) if not self._excluded.django: - resulting_string = ( resulting_string or self.__patterns.django_comment.read() ) diff --git a/python/jsbeautifier/javascript/beautifier.py b/python/jsbeautifier/javascript/beautifier.py index 647a2df98..217507c42 100644 --- a/python/jsbeautifier/javascript/beautifier.py +++ b/python/jsbeautifier/javascript/beautifier.py @@ -1369,7 +1369,6 @@ def handle_operator(self, current_token): and self._options.preserve_newlines and current_token.text in Tokenizer.positionable_operators ): - isColon = current_token.text == ":" isTernaryColon = isColon and in_ternary isOtherColon = isColon and not in_ternary diff --git a/python/jsbeautifier/javascript/tokenizer.py b/python/jsbeautifier/javascript/tokenizer.py index a121a31ac..0eeb8a074 100644 --- a/python/jsbeautifier/javascript/tokenizer.py +++ b/python/jsbeautifier/javascript/tokenizer.py @@ -342,7 +342,6 @@ def _read_string(self, c): return None def _read_regexp(self, c, previous_token): - if c == "/" and self.allowRegExOrXML(previous_token): # handle regexp resulting_string = self._input.next() @@ -425,7 +424,6 @@ def _read_non_javascript(self, c): resulting_string = "" if c == "#": - # she-bang if self._is_first_token(): resulting_string = self._patterns.shebang.read() @@ -471,7 +469,6 @@ def _read_non_javascript(self, c): self._input.back() elif c == "<" and self._is_first_token(): - if self._patterns.html_comment_start.read(): c = "