mirror of
https://github.com/beautifier/js-beautify.git
synced 2024-11-23 12:49:40 +00:00
Fixed #2260 - <style> and <script> tags indentation if also indenting angular control flows
This commit is contained in:
parent
40c535662b
commit
d5176ef294
@ -132,7 +132,8 @@ TemplatablePattern.prototype.__set_templated_pattern = function() {
|
|||||||
if (!this._disabled.php) {
|
if (!this._disabled.php) {
|
||||||
items.push(this.__patterns.php._starting_pattern.source);
|
items.push(this.__patterns.php._starting_pattern.source);
|
||||||
}
|
}
|
||||||
if (!this._disabled.handlebars) {
|
// Handlebars ('{{' and '}}') are also special tokens in Angular)
|
||||||
|
if (!this._disabled.handlebars || !this._disabled.angular) {
|
||||||
items.push(this.__patterns.handlebars._starting_pattern.source);
|
items.push(this.__patterns.handlebars._starting_pattern.source);
|
||||||
}
|
}
|
||||||
if (!this._disabled.erb) {
|
if (!this._disabled.erb) {
|
||||||
|
@ -291,7 +291,7 @@ Beautifier.prototype.beautify = function() {
|
|||||||
type: ''
|
type: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
var last_tag_token = new TagOpenParserToken();
|
var last_tag_token = new TagOpenParserToken(this._options);
|
||||||
|
|
||||||
var printer = new Printer(this._options, baseIndentString);
|
var printer = new Printer(this._options, baseIndentString);
|
||||||
var tokens = new Tokenizer(source_text, this._options).tokenize();
|
var tokens = new Tokenizer(source_text, this._options).tokenize();
|
||||||
@ -614,7 +614,7 @@ Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_to
|
|||||||
return parser_token;
|
return parser_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
var TagOpenParserToken = function(parent, raw_token) {
|
var TagOpenParserToken = function(options, parent, raw_token) {
|
||||||
this.parent = parent || null;
|
this.parent = parent || null;
|
||||||
this.text = '';
|
this.text = '';
|
||||||
this.type = 'TK_TAG_OPEN';
|
this.type = 'TK_TAG_OPEN';
|
||||||
@ -681,13 +681,14 @@ var TagOpenParserToken = function(parent, raw_token) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
|
// handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
|
||||||
|
// if they start with # or ^, they are still considered single tags if indenting of handlebars is set to false
|
||||||
this.is_end_tag = this.is_end_tag ||
|
this.is_end_tag = this.is_end_tag ||
|
||||||
(this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
|
(this.tag_start_char === '{' && (!options.indent_handlebars || this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(handlebar_starts)))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Beautifier.prototype._get_tag_open_token = function(raw_token) { //function to get a full tag and parse its type
|
Beautifier.prototype._get_tag_open_token = function(raw_token) { //function to get a full tag and parse its type
|
||||||
var parser_token = new TagOpenParserToken(this._tag_stack.get_parser_token(), raw_token);
|
var parser_token = new TagOpenParserToken(this._options, this._tag_stack.get_parser_token(), raw_token);
|
||||||
|
|
||||||
parser_token.alignment_size = this._options.wrap_attributes_indent_size;
|
parser_token.alignment_size = this._options.wrap_attributes_indent_size;
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ Tokenizer.prototype._get_next_token = function(previous_token, open_token) { //
|
|||||||
token = token || this._read_open_handlebars(c, open_token);
|
token = token || this._read_open_handlebars(c, open_token);
|
||||||
token = token || this._read_attribute(c, previous_token, open_token);
|
token = token || this._read_attribute(c, previous_token, open_token);
|
||||||
token = token || this._read_close(c, open_token);
|
token = token || this._read_close(c, open_token);
|
||||||
|
token = token || this._read_script_and_style(c, previous_token);
|
||||||
token = token || this._read_control_flows(c, open_token);
|
token = token || this._read_control_flows(c, open_token);
|
||||||
token = token || this._read_raw_content(c, previous_token, open_token);
|
token = token || this._read_raw_content(c, previous_token, open_token);
|
||||||
token = token || this._read_content_word(c, open_token);
|
token = token || this._read_content_word(c, open_token);
|
||||||
@ -215,8 +216,8 @@ Tokenizer.prototype._read_open_handlebars = function(c, open_token) {
|
|||||||
var resulting_string = null;
|
var resulting_string = null;
|
||||||
var token = null;
|
var token = null;
|
||||||
if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) {
|
if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) {
|
||||||
if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') {
|
if ((this._options.templating.includes('angular') || this._options.indent_handlebars) && c === '{' && this._input.peek(1) === '{') {
|
||||||
if (this._input.peek(2) === '!') {
|
if (this._options.indent_handlebars && this._input.peek(2) === '!') {
|
||||||
resulting_string = this.__patterns.handlebars_comment.read();
|
resulting_string = this.__patterns.handlebars_comment.read();
|
||||||
resulting_string = resulting_string || this.__patterns.handlebars.read();
|
resulting_string = resulting_string || this.__patterns.handlebars.read();
|
||||||
token = this._create_token(TOKEN.COMMENT, resulting_string);
|
token = this._create_token(TOKEN.COMMENT, resulting_string);
|
||||||
@ -232,8 +233,8 @@ Tokenizer.prototype._read_open_handlebars = function(c, open_token) {
|
|||||||
Tokenizer.prototype._read_control_flows = function(c, open_token) {
|
Tokenizer.prototype._read_control_flows = function(c, open_token) {
|
||||||
var resulting_string = '';
|
var resulting_string = '';
|
||||||
var token = null;
|
var token = null;
|
||||||
// Only check for control flows if angular templating is set AND indenting is set
|
// Only check for control flows if angular templating is set
|
||||||
if (!this._options.templating.includes('angular') || !this._options.indent_handlebars) {
|
if (!this._options.templating.includes('angular')) {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,13 +328,8 @@ Tokenizer.prototype._is_content_unformatted = function(tag_name) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) { // jshint unused:false
|
Tokenizer.prototype._read_script_and_style = function(c, previous_token) { // jshint unused:false
|
||||||
var resulting_string = '';
|
if (previous_token.type === TOKEN.TAG_CLOSE && previous_token.opened.text[0] === '<' && previous_token.text[0] !== '/') {
|
||||||
if (open_token && open_token.text[0] === '{') {
|
|
||||||
resulting_string = this.__patterns.handlebars_raw_close.read();
|
|
||||||
} else if (previous_token.type === TOKEN.TAG_CLOSE &&
|
|
||||||
previous_token.opened.text[0] === '<' && previous_token.text[0] !== '/') {
|
|
||||||
// ^^ empty tag has no content
|
|
||||||
var tag_name = previous_token.opened.text.substr(1).toLowerCase();
|
var tag_name = previous_token.opened.text.substr(1).toLowerCase();
|
||||||
if (tag_name === 'script' || tag_name === 'style') {
|
if (tag_name === 'script' || tag_name === 'style') {
|
||||||
// Script and style tags are allowed to have comments wrapping their content
|
// Script and style tags are allowed to have comments wrapping their content
|
||||||
@ -343,8 +339,24 @@ Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token)
|
|||||||
token.type = TOKEN.TEXT;
|
token.type = TOKEN.TEXT;
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
var resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
||||||
} else if (this._is_content_unformatted(tag_name)) {
|
if (resulting_string) {
|
||||||
|
return this._create_token(TOKEN.TEXT, resulting_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) { // jshint unused:false
|
||||||
|
var resulting_string = '';
|
||||||
|
if (open_token && open_token.text[0] === '{') {
|
||||||
|
resulting_string = this.__patterns.handlebars_raw_close.read();
|
||||||
|
} else if (previous_token.type === TOKEN.TAG_CLOSE &&
|
||||||
|
previous_token.opened.text[0] === '<' && previous_token.text[0] !== '/') {
|
||||||
|
// ^^ empty tag has no content
|
||||||
|
var tag_name = previous_token.opened.text.substr(1).toLowerCase();
|
||||||
|
if (this._is_content_unformatted(tag_name)) {
|
||||||
|
|
||||||
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
||||||
}
|
}
|
||||||
@ -371,6 +383,7 @@ Tokenizer.prototype._read_content_word = function(c, open_token) {
|
|||||||
if (resulting_string) {
|
if (resulting_string) {
|
||||||
return this._create_token(TOKEN.TEXT, resulting_string);
|
return this._create_token(TOKEN.TEXT, resulting_string);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.Tokenizer = Tokenizer;
|
module.exports.Tokenizer = Tokenizer;
|
||||||
|
@ -3916,7 +3916,7 @@ exports.test_data = {
|
|||||||
description: "https://github.com/beautify-web/js-beautify/issues/2219",
|
description: "https://github.com/beautify-web/js-beautify/issues/2219",
|
||||||
template: "^^^ $$$",
|
template: "^^^ $$$",
|
||||||
options: [
|
options: [
|
||||||
{ name: "templating", value: "'angular, handlebars'" }
|
{ name: "templating", value: "'angular'" }
|
||||||
],
|
],
|
||||||
tests: [{
|
tests: [{
|
||||||
input: [
|
input: [
|
||||||
@ -4240,18 +4240,7 @@ exports.test_data = {
|
|||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
comment: 'CSS @media should remain unchanged',
|
comment: 'CSS @media should remain unchanged',
|
||||||
// This behavior is currently incorrect. This codifies the way it fails.
|
unchanged: [
|
||||||
// unchanged: [
|
|
||||||
// '<style type="text/css">',
|
|
||||||
// ' @media only screen and (min-width:480px) {',
|
|
||||||
// ' .mj-column-per-100 {',
|
|
||||||
// ' width: 100% !important;',
|
|
||||||
// ' max-width: 100%;',
|
|
||||||
// ' }',
|
|
||||||
// ' }',
|
|
||||||
// '</style>'
|
|
||||||
// ]
|
|
||||||
input: [
|
|
||||||
'<style type="text/css">',
|
'<style type="text/css">',
|
||||||
' @media only screen and (min-width:480px) {',
|
' @media only screen and (min-width:480px) {',
|
||||||
' .mj-column-per-100 {',
|
' .mj-column-per-100 {',
|
||||||
@ -4260,30 +4249,63 @@ exports.test_data = {
|
|||||||
' }',
|
' }',
|
||||||
' }',
|
' }',
|
||||||
'</style>'
|
'</style>'
|
||||||
],
|
]
|
||||||
output: [
|
}, {
|
||||||
|
comment: 'CSS @media, the inside of <script> tag and control flows should be indented correctly',
|
||||||
|
fragment: true,
|
||||||
|
input: [
|
||||||
|
'<head>',
|
||||||
'<style type="text/css">',
|
'<style type="text/css">',
|
||||||
'@media only screen and (min-width:480px) {',
|
'@media only screen and (min-width:480px) {',
|
||||||
' .mj-column-per-100',
|
'.mj-column-per-100 {',
|
||||||
' {',
|
'width: 100% !important;',
|
||||||
' width:',
|
'max-width: 100%;',
|
||||||
' 100%',
|
|
||||||
' !important;',
|
|
||||||
' max-width:',
|
|
||||||
' 100%;',
|
|
||||||
'}',
|
'}',
|
||||||
' }',
|
'}',
|
||||||
'</style>'
|
'</style>',
|
||||||
|
'<script>',
|
||||||
|
'if(someExpression) {',
|
||||||
|
'callFunc();',
|
||||||
|
'}',
|
||||||
|
'</script>',
|
||||||
|
'</head>',
|
||||||
|
'<body>',
|
||||||
|
'<div>',
|
||||||
|
'@if(someOtherExpression) {',
|
||||||
|
'Text',
|
||||||
|
'}',
|
||||||
|
'</div>',
|
||||||
|
'</body>'
|
||||||
|
],
|
||||||
|
output: [
|
||||||
|
'<head>',
|
||||||
|
' <style type="text/css">',
|
||||||
|
' @media only screen and (min-width:480px) {',
|
||||||
|
' .mj-column-per-100 {',
|
||||||
|
' width: 100% !important;',
|
||||||
|
' max-width: 100%;',
|
||||||
|
' }',
|
||||||
|
' }',
|
||||||
|
' </style>',
|
||||||
|
' <script>',
|
||||||
|
' if (someExpression) {',
|
||||||
|
' callFunc();',
|
||||||
|
' }',
|
||||||
|
' </script>',
|
||||||
|
'</head>',
|
||||||
|
'<body>',
|
||||||
|
' <div>',
|
||||||
|
' @if(someOtherExpression) {',
|
||||||
|
' Text',
|
||||||
|
' }',
|
||||||
|
' </div>',
|
||||||
|
'</body>'
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
name: "No indenting for angular control flow should be done if indent_handlebars is false",
|
name: "No indenting for angular control flow should be done if angular templating is not set",
|
||||||
description: "https://github.com/beautify-web/js-beautify/issues/2219",
|
description: "https://github.com/beautify-web/js-beautify/issues/2219",
|
||||||
template: "^^^ $$$",
|
template: "^^^ $$$",
|
||||||
options: [
|
|
||||||
{ name: "templating", value: "'angular, handlebars'" },
|
|
||||||
{ name: "indent_handlebars", value: "false" }
|
|
||||||
],
|
|
||||||
tests: [{
|
tests: [{
|
||||||
unchanged: [
|
unchanged: [
|
||||||
'@if (a > b) {',
|
'@if (a > b) {',
|
||||||
|
Loading…
Reference in New Issue
Block a user