Skip to content

Commit

Permalink
Add html/text support to script tag
Browse files Browse the repository at this point in the history
Fixes #1591

NOTE: This is a potentially breaking change to existing behavior.
Whitespace at the start of html used to be ignored.
Now it will be used as the base indent for the rest of the input.
This makes it consistent with the other beautifiers but may change
the behaviors of libraries that use the beautifier.
  • Loading branch information
bitwiseman committed Dec 9, 2018
1 parent d95fd00 commit f79082e
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 61 deletions.
64 changes: 42 additions & 22 deletions js/src/html/beautifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,28 +136,43 @@ Printer.prototype.get_full_indent = function(level) {
return this._output.get_indent_string(level);
};


var uses_beautifier = function(tag_check, start_token) {
var get_custom_beautifier_name = function(tag_check, start_token) {
var raw_token = start_token.next;
var typeAttribute = null;

if (!start_token.closed) {
return false;
return null;
}

if (tag_check === 'script') {
typeAttribute = 'text/javascript';
} else if (tag_check === 'style') {
typeAttribute = 'text/css';
}

// Search attributes for a type attribute
while (raw_token.type !== TOKEN.EOF && raw_token.closed !== start_token) {
if (raw_token.type === TOKEN.ATTRIBUTE && raw_token.text === 'type') {
// For script and style tags that have a type attribute, only enable custom beautifiers for matching values
var peekEquals = raw_token.next ? raw_token.next : raw_token;
var peekValue = peekEquals.next ? peekEquals.next : peekEquals;
if (peekEquals.type === TOKEN.EQUALS && peekValue.type === TOKEN.VALUE) {
return (tag_check === 'style' && peekValue.text.search('text/css') > -1) ||
(tag_check === 'script' && peekValue.text.search(/(text|application|dojo)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json|method|aspect)/) > -1);
if (raw_token.next && raw_token.next.type === TOKEN.EQUALS &&
raw_token.next.next && raw_token.next.next.type === TOKEN.VALUE) {
typeAttribute = raw_token.next.next.text;
}
return false;
break;
}
raw_token = raw_token.next;
}

return true;
// For script and style tags that have a type attribute, only enable custom beautifiers for matching values
// For those without a type attribute use default;
if (typeAttribute.search('text/css') > -1) {
return 'css';
} else if (typeAttribute.search(/(text|application|dojo)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json|method|aspect)/) > -1) {
return 'javascript';
} else if (typeAttribute.search(/(text|application|dojo)\/(x-)?(html)/) > -1) {
return 'html';
}

return null;
};

function in_array(what, arr) {
Expand Down Expand Up @@ -265,10 +280,8 @@ Beautifier.prototype.beautify = function() {

// HACK: newline parsing inconsistent. This brute force normalizes the input.
source_text = source_text.replace(allLineBreaks, '\n');
var baseIndentString = '';

// Including commented out text would change existing html beautifier behavior to autodetect base indent.
// baseIndentString = source_text.match(/^[\t ]*/)[0];
var baseIndentString = source_text.match(/^[\t ]*/)[0];

var last_token = {
text: '',
Expand Down Expand Up @@ -413,7 +426,7 @@ Beautifier.prototype._handle_text = function(printer, raw_token, last_tag_token)
text: raw_token.text,
type: 'TK_CONTENT'
};
if (last_tag_token.custom_beautifier) { //check if we need to format javascript
if (last_tag_token.custom_beautifier_name) { //check if we need to format javascript
this._print_custom_beatifier_text(printer, raw_token, last_tag_token);
} else if (last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) {
printer.add_raw_token(raw_token);
Expand All @@ -425,17 +438,24 @@ Beautifier.prototype._handle_text = function(printer, raw_token, last_tag_token)
};

Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, last_tag_token) {
var local = this;
if (raw_token.text !== '') {
printer.print_newline(false);
var text = raw_token.text,
_beautifier,
script_indent_level = 1;
if (last_tag_token.tag_name === 'script') {
_beautifier = typeof this._js_beautify === 'function' && this._js_beautify;
} else if (last_tag_token.tag_name === 'style') {
_beautifier = typeof this._css_beautify === 'function' && this._css_beautify;
if (last_tag_token.custom_beautifier_name === 'javascript' && typeof this._js_beautify === 'function') {
_beautifier = this._js_beautify;
} else if (last_tag_token.custom_beautifier_name === 'css' && typeof this._css_beautify === 'function') {
_beautifier = this._css_beautify;
} else if (last_tag_token.custom_beautifier_name === 'html') {
_beautifier = function(html_source, options) {
var beautifier = new Beautifier(html_source, options, local._js_beautify, local._css_beautify);
return beautifier.beautify();
};
}


if (this._options.indent_scripts === "keep") {
script_indent_level = 0;
} else if (this._options.indent_scripts === "separate") {
Expand Down Expand Up @@ -511,7 +531,7 @@ var TagOpenParserToken = function(parent, raw_token) {
this.is_end_tag = false;
this.indent_content = false;
this.multiline_content = false;
this.custom_beautifier = false;
this.custom_beautifier_name = null;
this.start_tag_token = null;
this.attr_count = 0;
this.has_wrapped_attrs = false;
Expand Down Expand Up @@ -584,7 +604,7 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok

if ((parser_token.tag_name === 'script' || parser_token.tag_name === 'style') &&
!(parser_token.is_unformatted || parser_token.is_content_unformatted)) {
parser_token.custom_beautifier = uses_beautifier(parser_token.tag_check, raw_token);
parser_token.custom_beautifier_name = get_custom_beautifier_name(parser_token.tag_check, raw_token);
}
}
}
Expand Down Expand Up @@ -632,7 +652,7 @@ Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_tok
printer.print_newline(false);
}
} else { // it's a start-tag
parser_token.indent_content = !parser_token.custom_beautifier;
parser_token.indent_content = !parser_token.custom_beautifier_name;

if (parser_token.tag_start_char === '<') {
if (parser_token.tag_name === 'html') {
Expand Down
73 changes: 43 additions & 30 deletions js/test/generated/beautify-html-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,49 +187,49 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
// Support Indent Level Options and Base Indent Autodetection - ()
reset_options();
set_name('Support Indent Level Options and Base Indent Autodetection - ()');
test_fragment(' a', 'a');
test_fragment(' a');
test_fragment(
' <div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>',
// -- output --
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>');
' <div>\n' +
' <p>This is my sentence.</p>\n' +
' </div>');
test_fragment(
' // This is a random comment\n' +
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>',
// -- output --
'// This is a random comment\n' +
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>');
' // This is a random comment\n' +
' <div>\n' +
' <p>This is my sentence.</p>\n' +
' </div>');

// Support Indent Level Options and Base Indent Autodetection - (indent_level = "0")
reset_options();
set_name('Support Indent Level Options and Base Indent Autodetection - (indent_level = "0")');
opts.indent_level = 0;
test_fragment(' a', 'a');
test_fragment(' a');
test_fragment(
' <div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>',
// -- output --
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>');
' <div>\n' +
' <p>This is my sentence.</p>\n' +
' </div>');
test_fragment(
' // This is a random comment\n' +
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>',
// -- output --
'// This is a random comment\n' +
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>');
' // This is a random comment\n' +
' <div>\n' +
' <p>This is my sentence.</p>\n' +
' </div>');

// Support Indent Level Options and Base Indent Autodetection - (indent_level = "1")
reset_options();
Expand Down Expand Up @@ -308,25 +308,25 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
reset_options();
set_name('Support Indent Level Options and Base Indent Autodetection - (indent_level = "0")');
opts.indent_level = 0;
test_fragment('\t a', 'a');
test_fragment('\t a');
test_fragment(
'\t <div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>',
// -- output --
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>');
'\t <div>\n' +
'\t <p>This is my sentence.</p>\n' +
'\t </div>');
test_fragment(
'\t // This is a random comment\n' +
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>',
// -- output --
'// This is a random comment\n' +
'<div>\n' +
' <p>This is my sentence.</p>\n' +
'</div>');
'\t // This is a random comment\n' +
'\t <div>\n' +
'\t <p>This is my sentence.</p>\n' +
'\t </div>');


//============================================================
Expand Down Expand Up @@ -431,6 +431,19 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
'<script>\n' +
' < div > < /div>\n' +
'</script>');

// text/html should beautify as html
bth(
'<script type="text/html">\n' +
'<div>\n' +
'<div></div><div></div></div></script>',
// -- output --
'<script type="text/html">\n' +
' <div>\n' +
' <div></div>\n' +
' <div></div>\n' +
' </div>\n' +
'</script>');
bth(
'<script>var foo = "bar";</script>',
// -- output --
Expand Down Expand Up @@ -7311,10 +7324,10 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
' </div>',
'<div>\n' +
'</div>');
bth(' <div>\n' +
test_fragment(' <div>\n' +
' </div>',
'<div>\n' +
'</div>');
' <div>\n' +
' </div>');
bth('<div>\n' +
'</div>\n' +
' <div>\n' +
Expand All @@ -7323,10 +7336,10 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
'</div>\n' +
'<div>\n' +
'</div>');
bth(' <div>\n' +
test_fragment(' <div>\n' +
'</div>',
'<div>\n' +
'</div>');
' <div>\n' +
' </div>');
bth('<div >content</div>',
'<div>content</div>');
bth('<div thinger="preserve space here" ></div >',
Expand Down
12 changes: 6 additions & 6 deletions test/data/html/node.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
' </div>',
'<div>\n' +
'</div>');
bth(' <div>\n' +
test_fragment(' <div>\n' +
' </div>',
'<div>\n' +
'</div>');
' <div>\n' +
' </div>');
bth('<div>\n' +
'</div>\n' +
' <div>\n' +
Expand All @@ -247,10 +247,10 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
'</div>\n' +
'<div>\n' +
'</div>');
bth(' <div>\n' +
test_fragment(' <div>\n' +
'</div>',
'<div>\n' +
'</div>');
' <div>\n' +
' </div>');
bth('<div >content</div>',
'<div>content</div>');
bth('<div thinger="preserve space here" ></div >',
Expand Down
17 changes: 14 additions & 3 deletions test/data/html/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ exports.test_data = {
matrix: [{
options: [],
input_start_indent: ' ',
output_start_of_base: '',
output_start_of_base: ' ',
i: ' '
}, {
options: [
{ name: "indent_level", value: "0" }
],
input_start_indent: ' ',
output_start_of_base: '',
output_start_of_base: ' ',
i: ' '
}, {
options: [
Expand Down Expand Up @@ -121,7 +121,7 @@ exports.test_data = {
{ name: "indent_level", value: "0" }
],
input_start_indent: '\t ',
output_start_of_base: '',
output_start_of_base: '\t ',
i: ' '
}],
tests: [
Expand Down Expand Up @@ -238,6 +238,17 @@ exports.test_data = {
' < div > < /div>',
'</script>'
]
}, {
comment: 'text/html should beautify as html',
input: '<script type="text/html">\n<div>\n<div></div><div></div></div></script>',
output: [
'<script type="text/html">',
' <div>',
' <div></div>',
' <div></div>',
' </div>',
'</script>'
]
}, {
input: '<script>var foo = "bar";</script>',
output: [
Expand Down

0 comments on commit f79082e

Please sign in to comment.