mirror of
https://github.com/beautifier/js-beautify.git
synced 2024-11-23 04:40:06 +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) {
|
||||
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);
|
||||
}
|
||||
if (!this._disabled.erb) {
|
||||
|
@ -291,7 +291,7 @@ Beautifier.prototype.beautify = function() {
|
||||
type: ''
|
||||
};
|
||||
|
||||
var last_tag_token = new TagOpenParserToken();
|
||||
var last_tag_token = new TagOpenParserToken(this._options);
|
||||
|
||||
var printer = new Printer(this._options, baseIndentString);
|
||||
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;
|
||||
};
|
||||
|
||||
var TagOpenParserToken = function(parent, raw_token) {
|
||||
var TagOpenParserToken = function(options, parent, raw_token) {
|
||||
this.parent = parent || null;
|
||||
this.text = '';
|
||||
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.
|
||||
// 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.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
|
||||
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;
|
||||
|
||||
|
@ -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_attribute(c, previous_token, 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_raw_content(c, previous_token, 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 token = null;
|
||||
if (!open_token || open_token.type === TOKEN.CONTROL_FLOW_OPEN) {
|
||||
if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') {
|
||||
if (this._input.peek(2) === '!') {
|
||||
if ((this._options.templating.includes('angular') || this._options.indent_handlebars) && c === '{' && this._input.peek(1) === '{') {
|
||||
if (this._options.indent_handlebars && this._input.peek(2) === '!') {
|
||||
resulting_string = this.__patterns.handlebars_comment.read();
|
||||
resulting_string = resulting_string || this.__patterns.handlebars.read();
|
||||
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) {
|
||||
var resulting_string = '';
|
||||
var token = null;
|
||||
// Only check for control flows if angular templating is set AND indenting is set
|
||||
if (!this._options.templating.includes('angular') || !this._options.indent_handlebars) {
|
||||
// Only check for control flows if angular templating is set
|
||||
if (!this._options.templating.includes('angular')) {
|
||||
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
|
||||
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
|
||||
Tokenizer.prototype._read_script_and_style = function(c, previous_token) { // jshint unused:false
|
||||
if (previous_token.type === TOKEN.TAG_CLOSE && previous_token.opened.text[0] === '<' && previous_token.text[0] !== '/') {
|
||||
var tag_name = previous_token.opened.text.substr(1).toLowerCase();
|
||||
if (tag_name === 'script' || tag_name === 'style') {
|
||||
// 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;
|
||||
return token;
|
||||
}
|
||||
resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
||||
} else if (this._is_content_unformatted(tag_name)) {
|
||||
var resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
|
||||
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'));
|
||||
}
|
||||
@ -371,6 +383,7 @@ Tokenizer.prototype._read_content_word = function(c, open_token) {
|
||||
if (resulting_string) {
|
||||
return this._create_token(TOKEN.TEXT, resulting_string);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports.Tokenizer = Tokenizer;
|
||||
|
@ -3916,7 +3916,7 @@ exports.test_data = {
|
||||
description: "https://github.com/beautify-web/js-beautify/issues/2219",
|
||||
template: "^^^ $$$",
|
||||
options: [
|
||||
{ name: "templating", value: "'angular, handlebars'" }
|
||||
{ name: "templating", value: "'angular'" }
|
||||
],
|
||||
tests: [{
|
||||
input: [
|
||||
@ -4240,18 +4240,7 @@ exports.test_data = {
|
||||
]
|
||||
}, {
|
||||
comment: 'CSS @media should remain unchanged',
|
||||
// This behavior is currently incorrect. This codifies the way it fails.
|
||||
// unchanged: [
|
||||
// '<style type="text/css">',
|
||||
// ' @media only screen and (min-width:480px) {',
|
||||
// ' .mj-column-per-100 {',
|
||||
// ' width: 100% !important;',
|
||||
// ' max-width: 100%;',
|
||||
// ' }',
|
||||
// ' }',
|
||||
// '</style>'
|
||||
// ]
|
||||
input: [
|
||||
unchanged: [
|
||||
'<style type="text/css">',
|
||||
' @media only screen and (min-width:480px) {',
|
||||
' .mj-column-per-100 {',
|
||||
@ -4260,30 +4249,63 @@ exports.test_data = {
|
||||
' }',
|
||||
' }',
|
||||
'</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">',
|
||||
'@media only screen and (min-width:480px) {',
|
||||
' .mj-column-per-100',
|
||||
' {',
|
||||
' width:',
|
||||
' 100%',
|
||||
' !important;',
|
||||
' max-width:',
|
||||
' 100%;',
|
||||
'.mj-column-per-100 {',
|
||||
'width: 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",
|
||||
template: "^^^ $$$",
|
||||
options: [
|
||||
{ name: "templating", value: "'angular, handlebars'" },
|
||||
{ name: "indent_handlebars", value: "false" }
|
||||
],
|
||||
tests: [{
|
||||
unchanged: [
|
||||
'@if (a > b) {',
|
||||
|
Loading…
Reference in New Issue
Block a user