Add core Options class

This commit is contained in:
Liam Newman 2018-08-24 13:35:15 -07:00
parent d210b6381e
commit 81d3177bff
21 changed files with 1033 additions and 571 deletions

View File

@ -28,13 +28,110 @@
'use strict';
function Options(options, merge_child_field) {
options = _mergeOpts(options, merge_child_field);
this.raw_options = _normalizeOpts(options);
// Support passing the source text back with no change
this.disabled = this._get_boolean('disabled');
this.eol = this._get_characters('eol', 'auto');
this.end_with_newline = this._get_boolean('end_with_newline');
this.indent_size = this._get_number('indent_size', 4);
this.indent_char = this._get_characters('indent_char', ' ');
this.preserve_newlines = this._get_boolean('preserve_newlines', true);
this.max_preserve_newlines = this.max_preserve_newlines = this._get_number('max_preserve_newlines', 32786);
if (!this.preserve_newlines) {
this.max_preserve_newlines = 0;
}
this.indent_with_tabs = this._get_boolean('indent_with_tabs');
if (this.indent_with_tabs) {
this.indent_char = '\t';
this.indent_size = 1;
}
this.indent_string = this.indent_char;
if (this.indent_size > 1) {
this.indent_string = new Array(this.indent_size + 1).join(this.indent_char);
}
// Backwards compat with 1.3.x
this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
}
Options.prototype._get_array = function(name, default_value) {
var option_value = this.raw_options[name];
var result = default_value || [];
if (typeof option_value === 'object') {
if (option_value !== null && typeof option_value.concat === 'function') {
result = option_value.concat();
}
} else if (typeof option_value === 'string') {
result = option_value.split(/[^a-zA-Z0-9_\/\-]+/);
}
return result;
};
Options.prototype._get_boolean = function(name, default_value) {
var option_value = this.raw_options[name];
var result = option_value === undefined ? !!default_value : !!option_value;
return result;
};
Options.prototype._get_characters = function(name, default_value) {
var option_value = this.raw_options[name];
var result = default_value || '';
if (typeof option_value === 'string') {
result = option_value.replace(/\\r/, '\r').replace(/\\n/, '\n').replace(/\\t/, '\t');
}
return result;
};
Options.prototype._get_number = function(name, default_value) {
var option_value = this.raw_options[name];
default_value = parseInt(default_value, 10);
if (isNaN(default_value)) {
default_value = 0;
}
var result = parseInt(option_value, 10);
if (isNaN(result)) {
result = default_value;
}
return result;
};
Options.prototype._get_selection = function(name, selection_list, default_value) {
default_value = default_value || [selection_list[0]];
if (!this._is_valid_selection(default_value, selection_list)) {
throw new Error("Invalid Default Value!");
}
var result = this._get_array(name, default_value);
if (!this._is_valid_selection(result, selection_list)) {
throw new Error(
"Invalid Option Value: The option '" + name + "' must be one of the following values\n" + selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
}
return result;
};
Options.prototype._is_valid_selection = function(result, selection_list) {
return result.length && selection_list.length &&
!result.some(function(item) { return selection_list.indexOf(item) === -1; });
};
// merges child options up with the parent options object
// Example: obj = {a: 1, b: {a: 2}}
// mergeOpts(obj, 'b')
//
// Returns: {a: 2, b: {a: 2}}
function mergeOpts(allOptions, childFieldName) {
function _mergeOpts(allOptions, childFieldName) {
var finalOpts = {};
allOptions = allOptions || {};
var name;
for (name in allOptions) {
@ -44,7 +141,7 @@ function mergeOpts(allOptions, childFieldName) {
}
//merge in the per type settings for the childFieldName
if (childFieldName in allOptions) {
if (childFieldName && allOptions[childFieldName]) {
for (name in allOptions[childFieldName]) {
finalOpts[name] = allOptions[childFieldName][name];
}
@ -52,7 +149,7 @@ function mergeOpts(allOptions, childFieldName) {
return finalOpts;
}
function normalizeOpts(options) {
function _normalizeOpts(options) {
var convertedOpts = {};
var key;
@ -63,5 +160,6 @@ function normalizeOpts(options) {
return convertedOpts;
}
module.exports.mergeOpts = mergeOpts;
module.exports.normalizeOpts = normalizeOpts;
module.exports.Options = Options;
module.exports.normalizeOpts = _normalizeOpts;
module.exports.mergeOpts = _mergeOpts;

View File

@ -28,8 +28,7 @@
'use strict';
var mergeOpts = require('../core/options').mergeOpts;
var normalizeOpts = require('../core/options').normalizeOpts;
var Options = require('./options').Options;
var acorn = require('../core/acorn');
var Output = require('../core/output').Output;
var InputScanner = require('../core/inputscanner').InputScanner;
@ -39,33 +38,9 @@ var allLineBreaks = acorn.allLineBreaks;
function Beautifier(source_text, options) {
this._source_text = source_text || '';
options = options || {};
// Allow the setting of language/file-type specific options
// with inheritance of overall settings
options = mergeOpts(options, 'css');
options = normalizeOpts(options);
this._options = {};
var indentSize = options.indent_size ? parseInt(options.indent_size, 10) : 4;
var indentCharacter = options.indent_char || ' ';
var preserve_newlines = (options.preserve_newlines === undefined) ? false : options.preserve_newlines;
var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
var space_around_combinator = (options.space_around_combinator === undefined) ? false : options.space_around_combinator;
space_around_combinator = space_around_combinator || ((options.space_around_selector_separator === undefined) ? false : options.space_around_selector_separator);
var eol = options.eol ? options.eol : 'auto';
// Support passing the source text back with no change
this._options.disabled = (options.disabled === undefined) ? false : options.disabled;
if (options.indent_with_tabs) {
indentCharacter = '\t';
indentSize = 1;
}
eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
this._options = new Options(options);
// tokenizer
var whitespaceChar = /\s/;
@ -96,21 +71,21 @@ function Beautifier(source_text, options) {
// When allowAtLeastOneNewLine is true, will output new lines for each
// newline character found; if the user has preserve_newlines off, only
// the first newline will be output
function eatWhitespace(allowAtLeastOneNewLine) {
this.eatWhitespace = function(allowAtLeastOneNewLine) {
var result = whitespaceChar.test(input.peek());
var isFirstNewLine = true;
while (whitespaceChar.test(input.peek())) {
ch = input.next();
if (allowAtLeastOneNewLine && ch === '\n') {
if (preserve_newlines || isFirstNewLine) {
if (this._options.preserve_newlines || isFirstNewLine) {
isFirstNewLine = false;
output.add_new_line(true);
}
}
}
return result;
}
};
// Nested pseudo-class if we are insideRule
// and the next special character found opens
@ -174,6 +149,7 @@ function Beautifier(source_text, options) {
}
var source_text = this._source_text;
var eol = this._options.eol;
if (eol === 'auto') {
eol = '\n';
if (source_text && lineBreak.test(source_text || '')) {
@ -186,19 +162,17 @@ function Beautifier(source_text, options) {
source_text = source_text.replace(allLineBreaks, '\n');
// reset
var singleIndent = new Array(indentSize + 1).join(indentCharacter);
var baseIndentString = '';
var preindent_index = 0;
if (source_text && source_text.length) {
while ((source_text.charAt(preindent_index) === ' ' ||
source_text.charAt(preindent_index) === '\t')) {
while ((source_text.charAt(preindent_index) === ' ' || source_text.charAt(preindent_index) === '\t')) {
preindent_index += 1;
}
baseIndentString = source_text.substring(0, preindent_index);
source_text = source_text.substring(preindent_index);
}
output = new Output(singleIndent, baseIndentString);
output = new Output(this._options.indent_string, baseIndentString);
input = new InputScanner(source_text);
indentLevel = 0;
nestedLevel = 0;
@ -235,7 +209,7 @@ function Beautifier(source_text, options) {
print_string(input.read(block_comment_pattern));
// Ensures any new lines following the comment are preserved
eatWhitespace(true);
this.eatWhitespace(true);
// Block comments are followed by a new line so they don't
// share a line with other properties
@ -249,7 +223,7 @@ function Beautifier(source_text, options) {
print_string(input.read(comment_pattern));
// Ensures any new lines following the comment are preserved
eatWhitespace(true);
this.eatWhitespace(true);
} else if (ch === '@') {
preserveSingleSpace(isAfterSpace);
@ -309,12 +283,12 @@ function Beautifier(source_text, options) {
// otherwise, declarations are also allowed
insideRule = (indentLevel >= nestedLevel);
}
if (newline_between_rules && insideRule) {
if (this._options.newline_between_rules && insideRule) {
if (output.previous_line && output.previous_line.item(-1) !== '{') {
output.ensure_empty_line_above('/', ',');
}
}
eatWhitespace(true);
this.eatWhitespace(true);
output.add_new_line();
} else if (ch === '}') {
outdent();
@ -334,25 +308,23 @@ function Beautifier(source_text, options) {
nestedLevel--;
}
eatWhitespace(true);
this.eatWhitespace(true);
output.add_new_line();
if (newline_between_rules && !output.just_added_blankline()) {
if (this._options.newline_between_rules && !output.just_added_blankline()) {
if (input.peek() !== '}') {
output.add_new_line(true);
}
}
} else if (ch === ":") {
if ((insideRule || enteringConditionalGroup) &&
!(input.lookBack("&") || foundNestedPseudoClass()) &&
!input.lookBack("(") && !insideAtExtend) {
if ((insideRule || enteringConditionalGroup) && !(input.lookBack("&") || foundNestedPseudoClass()) && !input.lookBack("(") && !insideAtExtend) {
// 'property: value' delimiter
// which could be in a conditional group query
print_string(':');
if (!insidePropertyValue) {
insidePropertyValue = true;
output.space_before_token = true;
eatWhitespace(true);
this.eatWhitespace(true);
indent();
}
} else {
@ -375,7 +347,7 @@ function Beautifier(source_text, options) {
} else if (ch === '"' || ch === '\'') {
preserveSingleSpace(isAfterSpace);
print_string(ch + eatString(ch));
eatWhitespace(true);
this.eatWhitespace(true);
} else if (ch === ';') {
if (insidePropertyValue) {
outdent();
@ -384,7 +356,7 @@ function Beautifier(source_text, options) {
insideAtExtend = false;
insideAtImport = false;
print_string(ch);
eatWhitespace(true);
this.eatWhitespace(true);
// This maintains single line comments on the same
// line. Block comments are also affected, but
@ -396,7 +368,7 @@ function Beautifier(source_text, options) {
} else if (ch === '(') { // may be a url
if (input.lookBack("url")) {
print_string(ch);
eatWhitespace();
this.eatWhitespace();
ch = input.next();
if (ch === ')' || ch === '"' || ch !== '\'') {
input.back();
@ -408,29 +380,28 @@ function Beautifier(source_text, options) {
parenLevel++;
preserveSingleSpace(isAfterSpace);
print_string(ch);
eatWhitespace();
this.eatWhitespace();
}
} else if (ch === ')') {
print_string(ch);
parenLevel--;
} else if (ch === ',') {
print_string(ch);
eatWhitespace(true);
if (selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1 && !insideAtImport) {
this.eatWhitespace(true);
if (this._options.selector_separator_newline && !insidePropertyValue && parenLevel < 1 && !insideAtImport) {
output.add_new_line();
} else {
output.space_before_token = true;
}
} else if ((ch === '>' || ch === '+' || ch === '~') &&
!insidePropertyValue && parenLevel < 1) {
} else if ((ch === '>' || ch === '+' || ch === '~') && !insidePropertyValue && parenLevel < 1) {
//handle combinator spacing
if (space_around_combinator) {
if (this._options.space_around_combinator) {
output.space_before_token = true;
print_string(ch);
output.space_before_token = true;
} else {
print_string(ch);
eatWhitespace();
this.eatWhitespace();
// squash extra whitespace
if (ch && whitespaceChar.test(ch)) {
ch = '';
@ -442,7 +413,7 @@ function Beautifier(source_text, options) {
preserveSingleSpace(isAfterSpace);
print_string(ch);
} else if (ch === '=') { // no whitespace before or after
eatWhitespace();
this.eatWhitespace();
print_string('=');
if (whitespaceChar.test(ch)) {
ch = '';
@ -456,7 +427,7 @@ function Beautifier(source_text, options) {
}
}
var sweetCode = output.get_code(end_with_newline, eol);
var sweetCode = output.get_code(this._options.end_with_newline, eol);
return sweetCode;
};

46
js/src/css/options.js Normal file
View File

@ -0,0 +1,46 @@
/*jshint node:true */
/*
The MIT License (MIT)
Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
'use strict';
var BaseOptions = require('../core/options').Options;
function Options(options) {
BaseOptions.call(this, options, 'css');
this.selector_separator_newline = this._get_boolean('selector_separator_newline', true);
this.newline_between_rules = this._get_boolean('newline_between_rules', true);
var space_around_selector_separator = this._get_boolean('space_around_selector_separator');
this.space_around_combinator = this._get_boolean('space_around_combinator') || space_around_selector_separator;
}
Options.prototype = new BaseOptions();
module.exports.Options = Options;

View File

@ -28,8 +28,7 @@
'use strict';
var mergeOpts = require('../core/options').mergeOpts;
var normalizeOpts = require('../core/options').normalizeOpts;
var Options = require('../html/options').Options;
var acorn = require('../core/acorn');
var Output = require('../core/output').Output;
var Tokenizer = require('../html/tokenizer').Tokenizer;
@ -38,22 +37,15 @@ var TOKEN = require('../html/tokenizer').TOKEN;
var lineBreak = acorn.lineBreak;
var allLineBreaks = acorn.allLineBreaks;
var Printer = function(indent_character, indent_size, wrap_line_length, max_preserve_newlines, preserve_newlines) { //handles input/output and some other printing functions
var Printer = function(indent_string, wrap_line_length, max_preserve_newlines, preserve_newlines) { //handles input/output and some other printing functions
this.indent_character = indent_character;
this.indent_string = indent_character;
this.indent_size = indent_size;
this.indent_level = 0;
this.alignment_size = 0;
this.wrap_line_length = wrap_line_length;
this.max_preserve_newlines = max_preserve_newlines;
this.preserve_newlines = preserve_newlines;
if (this.indent_size > 1) {
this.indent_string = new Array(this.indent_size + 1).join(this.indent_character);
}
this._output = new Output(this.indent_string, '');
this._output = new Output(indent_string, '');
};
@ -98,9 +90,9 @@ Printer.prototype.traverse_whitespace = function(raw_token) {
// at the wrap_line_length, append a newline/indentation.
// return true if a newline was added, false if a space was added
Printer.prototype.print_space_or_wrap = function(text) {
if (this.wrap_line_length) {
if (this._output.current_line.get_character_count() + text.length + 1 >= this.wrap_line_length) { //insert a line when the wrap_line_length is reached
if (this._output.add_new_line()) {
return true;
return this._output.add_new_line();
}
}
return false;
@ -232,18 +224,6 @@ TagStack.prototype.indent_to_tag = function(tag_list) {
}
};
function get_array(input, default_list) {
var result = default_list || [];
if (typeof input === 'object') {
if (input !== null && typeof input.concat === 'function') {
result = input.concat();
}
} else if (typeof input === 'string') {
result = input.trim().replace(/\s*,\s*/g, ',').split(',');
}
return result;
}
function Beautifier(source_text, options, js_beautify, css_beautify) {
//Wrapper function to invoke all the necessary constructors and deal with the output.
this._source_text = source_text || '';
@ -254,75 +234,9 @@ function Beautifier(source_text, options, js_beautify, css_beautify) {
// Allow the setting of language/file-type specific options
// with inheritance of overall settings
options = mergeOpts(options, 'html');
options = normalizeOpts(options);
// backwards compatibility to 1.3.4
if ((options.wrap_line_length === undefined || parseInt(options.wrap_line_length, 10) === 0) &&
(options.max_char !== undefined && parseInt(options.max_char, 10) !== 0)) {
options.wrap_line_length = options.max_char;
}
this._options = Object.assign({}, options);
this._options.indent_inner_html = (options.indent_inner_html === undefined) ? false : options.indent_inner_html;
this._options.indent_body_inner_html = (options.indent_body_inner_html === undefined) ? true : options.indent_body_inner_html;
this._options.indent_head_inner_html = (options.indent_head_inner_html === undefined) ? true : options.indent_head_inner_html;
this._options.indent_size = (options.indent_size === undefined) ? 4 : parseInt(options.indent_size, 10);
this._options.indent_character = (options.indent_char === undefined) ? ' ' : options.indent_char;
this._options.wrap_line_length = parseInt(options.wrap_line_length, 10) === 0 ? 32786 : parseInt(options.wrap_line_length || 250, 10);
this._options.preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;
this._options.max_preserve_newlines = this._options.preserve_newlines ?
(isNaN(parseInt(options.max_preserve_newlines, 10)) ? 32786 : parseInt(options.max_preserve_newlines, 10)) :
0;
this._options.indent_handlebars = (options.indent_handlebars === undefined) ? false : options.indent_handlebars;
this._options.wrap_attributes = (options.wrap_attributes === undefined) ? 'auto' : options.wrap_attributes;
this._options.wrap_attributes_indent_size = (isNaN(parseInt(options.wrap_attributes_indent_size, 10))) ? this._options.indent_size : parseInt(options.wrap_attributes_indent_size, 10);
this._options.end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
this._options.extra_liners = get_array(options.extra_liners, ['head', 'body', '/html']);
this._options.eol = options.eol ? options.eol : 'auto';
if (options.indent_with_tabs) {
this._options.indent_character = '\t';
this._options.indent_size = 1;
}
// Support passing the source text back with no change
this._options.disabled = (options.disabled === undefined) ? false : options.disabled;
this._options.eol = this._options.eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
this._options.inline = get_array(options.inline, [
// https://www.w3.org/TR/html5/dom.html#phrasing-content
'a', 'abbr', 'area', 'audio', 'b', 'bdi', 'bdo', 'br', 'button', 'canvas', 'cite',
'code', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img',
'input', 'ins', 'kbd', 'keygen', 'label', 'map', 'mark', 'math', 'meter', 'noscript',
'object', 'output', 'progress', 'q', 'ruby', 's', 'samp', /* 'script', */ 'select', 'small',
'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', 'time', 'u', 'var',
'video', 'wbr', 'text',
// prexisting - not sure of full effect of removing, leaving in
'acronym', 'address', 'big', 'dt', 'ins', 'strike', 'tt'
]);
this._options.void_elements = get_array(options.void_elements, [
// HTLM void elements - aka self-closing tags - aka singletons
// https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr',
// NOTE: Optional tags are too complex for a simple list
// they are hard coded in _do_optional_end_element
// Doctype and xml elements
'!doctype', '?xml',
// ?php and ?= tags
'?php', '?=',
// other tags that were in this list, keeping just in case
'basefont', 'isindex'
]);
this._options.unformatted = get_array(options.unformatted, []);
this._options.content_unformatted = get_array(options.content_unformatted, [
'pre', 'textarea'
]);
var optionHtml = new Options(options, 'html');
this._options = optionHtml;
this._is_wrap_attributes_force = this._options.wrap_attributes.substr(0, 'force'.length) === 'force';
this._is_wrap_attributes_force_expand_multiline = (this._options.wrap_attributes === 'force-expand-multiline');
@ -356,7 +270,7 @@ Beautifier.prototype.beautify = function() {
var last_tag_token = new TagOpenParserToken();
var printer = new Printer(this._options.indent_character, this._options.indent_size,
var printer = new Printer(this._options.indent_string,
this._options.wrap_line_length, this._options.max_preserve_newlines, this._options.preserve_newlines);
var tokens = new Tokenizer(source_text, this._options).tokenize();
@ -410,7 +324,6 @@ Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_t
if (last_tag_token.indent_content &&
!(last_tag_token.is_unformatted || last_tag_token.is_content_unformatted)) {
printer.indent();
// only indent once per opened tag
@ -517,13 +430,13 @@ Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token,
var Child_options = function() {
this.eol = '\n';
};
Child_options.prototype = this._options;
Child_options.prototype = this._options.raw_options;
var child_options = new Child_options();
text = _beautifier(indentation + text, child_options);
} else {
// simply indent the string otherwise
var white = text.match(/^\s*/)[0];
var _level = white.match(/[^\n\r]*$/)[0].split(this._indent_string).length - 1;
var _level = white.match(/[^\n\r]*$/)[0].split(this._options.indent_string).length - 1;
var reindent = this._get_full_indent(script_indent_level - _level);
text = (indentation + text.trim())
.replace(/\r\n|\r|\n/g, '\n' + reindent);

81
js/src/html/options.js Normal file
View File

@ -0,0 +1,81 @@
/*jshint node:true */
/*
The MIT License (MIT)
Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
'use strict';
var BaseOptions = require('../core/options').Options;
function Options(options) {
BaseOptions.call(this, options, 'html');
this.indent_inner_html = this._get_boolean('indent_inner_html', true);
this.indent_body_inner_html = this._get_boolean('indent_body_inner_html', true);
this.indent_head_inner_html = this._get_boolean('indent_head_inner_html', true);
this.indent_handlebars = this._get_boolean('indent_handlebars', true);
this.wrap_attributes = this._get_selection('wrap_attributes',
['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple'])[0];
this.wrap_attributes_indent_size = this._get_number('wrap_attributes_indent_size', this.indent_size);
this.extra_liners = this._get_array('extra_liners', ['head', 'body', '/html']);
this.inline = this._get_array('inline', [
// https://www.w3.org/TR/html5/dom.html#phrasing-content
'a', 'abbr', 'area', 'audio', 'b', 'bdi', 'bdo', 'br', 'button', 'canvas', 'cite',
'code', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img',
'input', 'ins', 'kbd', 'keygen', 'label', 'map', 'mark', 'math', 'meter', 'noscript',
'object', 'output', 'progress', 'q', 'ruby', 's', 'samp', /* 'script', */ 'select', 'small',
'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', 'time', 'u', 'var',
'video', 'wbr', 'text',
// prexisting - not sure of full effect of removing, leaving in
'acronym', 'address', 'big', 'dt', 'ins', 'strike', 'tt'
]);
this.void_elements = this._get_array('void_elements', [
// HTLM void elements - aka self-closing tags - aka singletons
// https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr',
// NOTE: Optional tags are too complex for a simple list
// they are hard coded in _do_optional_end_element
// Doctype and xml elements
'!doctype', '?xml',
// ?php and ?= tags
'?php', '?=',
// other tags that were in this list, keeping just in case
'basefont', 'isindex'
]);
this.unformatted = this._get_array('unformatted', []);
this.content_unformatted = this._get_array('content_unformatted', [
'pre', 'textarea'
]);
}
Options.prototype = new BaseOptions();
module.exports.Options = Options;

View File

@ -28,10 +28,9 @@
'use strict';
var mergeOpts = require('../core/options').mergeOpts;
var normalizeOpts = require('../core/options').normalizeOpts;
var acorn = require('../core/acorn');
var Output = require('../core/output').Output;
var Options = require('./options').Options;
var Tokenizer = require('./tokenizer').Tokenizer;
var line_starters = require('./tokenizer').line_starters;
var positionable_operators = require('./tokenizer').positionable_operators;
@ -70,18 +69,6 @@ function generateMapFromStrings(list) {
return result;
}
function sanitizeOperatorPosition(opPosition) {
opPosition = opPosition || OPERATOR_POSITION.before_newline;
if (!in_array(opPosition, validPositionValues)) {
throw new Error("Invalid Option Value: The option 'operator_position' must be one of the following values\n" +
validPositionValues +
"\nYou passed in: '" + opPosition + "'");
}
return opPosition;
}
var validPositionValues = ['before-newline', 'after-newline', 'preserve-newline'];
// Generate map from array
@ -166,74 +153,7 @@ function Beautifier(source_text, options) {
this._previous_flags = null;
this._flag_store = null;
this._options = {};
// Allow the setting of language/file-type specific options
// with inheritance of overall settings
options = mergeOpts(options, 'js');
options = normalizeOpts(options);
// compatibility, re
if (options.brace_style === "expand-strict") { //graceful handling of deprecated option
options.brace_style = "expand";
} else if (options.brace_style === "collapse-preserve-inline") { //graceful handling of deprecated option
options.brace_style = "collapse,preserve-inline";
} else if (options.braces_on_own_line !== undefined) { //graceful handling of deprecated option
options.brace_style = options.braces_on_own_line ? "expand" : "collapse";
} else if (!options.brace_style) { //Nothing exists to set it
options.brace_style = "collapse";
}
//preserve-inline in delimited string will trigger brace_preserve_inline, everything
//else is considered a brace_style and the last one only will have an effect
var brace_style_split = options.brace_style.split(/[^a-zA-Z0-9_\-]+/);
this._options.brace_preserve_inline = false; //Defaults in case one or other was not specified in meta-option
this._options.brace_style = "collapse";
for (var bs = 0; bs < brace_style_split.length; bs++) {
if (brace_style_split[bs] === "preserve-inline") {
this._options.brace_preserve_inline = true;
} else {
this._options.brace_style = brace_style_split[bs];
}
}
this._options.indent_size = options.indent_size ? parseInt(options.indent_size, 10) : 4;
this._options.indent_char = options.indent_char ? options.indent_char : ' ';
this._options.eol = options.eol ? options.eol : 'auto';
this._options.preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;
this._options.unindent_chained_methods = (options.unindent_chained_methods === undefined) ? false : options.unindent_chained_methods;
this._options.break_chained_methods = (options.break_chained_methods === undefined) ? false : options.break_chained_methods;
this._options.max_preserve_newlines = (options.max_preserve_newlines === undefined) ? 0 : parseInt(options.max_preserve_newlines, 10);
this._options.space_in_paren = (options.space_in_paren === undefined) ? false : options.space_in_paren;
this._options.space_in_empty_paren = (options.space_in_empty_paren === undefined) ? false : options.space_in_empty_paren;
this._options.jslint_happy = (options.jslint_happy === undefined) ? false : options.jslint_happy;
this._options.space_after_anon_function = (options.space_after_anon_function === undefined) ? false : options.space_after_anon_function;
this._options.keep_array_indentation = (options.keep_array_indentation === undefined) ? false : options.keep_array_indentation;
this._options.space_before_conditional = (options.space_before_conditional === undefined) ? true : options.space_before_conditional;
this._options.unescape_strings = (options.unescape_strings === undefined) ? false : options.unescape_strings;
this._options.wrap_line_length = (options.wrap_line_length === undefined) ? 0 : parseInt(options.wrap_line_length, 10);
this._options.e4x = (options.e4x === undefined) ? false : options.e4x;
this._options.end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
this._options.comma_first = (options.comma_first === undefined) ? false : options.comma_first;
this._options.operator_position = sanitizeOperatorPosition(options.operator_position);
// Support passing the source text back with no change
this._options.disabled = (options.disabled === undefined) ? false : options.disabled;
// For testing of beautify preserve:start directive
this._options.test_output_raw = (options.test_output_raw === undefined) ? false : options.test_output_raw;
// force this._options.space_after_anon_function to true if this._options.jslint_happy
if (this._options.jslint_happy) {
this._options.space_after_anon_function = true;
}
if (options.indent_with_tabs) {
this._options.indent_char = '\t';
this._options.indent_size = 1;
}
this._options.eol = this._options.eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
this._options = new Options(options);
}
Beautifier.prototype.create_flags = function(flags_base, mode) {
@ -274,8 +194,6 @@ Beautifier.prototype.create_flags = function(flags_base, mode) {
Beautifier.prototype._reset = function(source_text) {
var baseIndentString = '';
var indent_string = new Array(this._options.indent_size + 1).join(this._options.indent_char);
var preindent_index = 0;
if (source_text && source_text.length) {
while ((source_text.charAt(preindent_index) === ' ' ||
@ -288,7 +206,7 @@ Beautifier.prototype._reset = function(source_text) {
this._last_type = TOKEN.START_BLOCK; // last token type
this._last_last_text = ''; // pre-last token text
this._output = new Output(indent_string, baseIndentString);
this._output = new Output(this._options.indent_string, baseIndentString);
// If testing the ignore directive, start with output disable set to true
this._output.raw = this._options.test_output_raw;
@ -306,7 +224,7 @@ Beautifier.prototype._reset = function(source_text) {
// MODE.BlockStatement and continues on.
this._flag_store = [];
this.set_mode(MODE.BlockStatement);
var tokenizer = new Tokenizer(source_text, this._options, indent_string);
var tokenizer = new Tokenizer(source_text, this._options);
this._tokens = tokenizer.tokenize();
return source_text;
};

View File

@ -0,0 +1,91 @@
/*jshint node:true */
/*
The MIT License (MIT)
Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
'use strict';
var BaseOptions = require('../core/options').Options;
var validPositionValues = ['before-newline', 'after-newline', 'preserve-newline'];
function Options(options) {
BaseOptions.call(this, options, 'js');
// compatibility, re
var raw_brace_style = this.raw_options.brace_style || null;
if (raw_brace_style === "expand-strict") { //graceful handling of deprecated option
this.raw_options.brace_style = "expand";
} else if (raw_brace_style === "collapse-preserve-inline") { //graceful handling of deprecated option
this.raw_options.brace_style = "collapse,preserve-inline";
} else if (this.raw_options.braces_on_own_line !== undefined) { //graceful handling of deprecated option
this.raw_options.brace_style = this.raw_options.braces_on_own_line ? "expand" : "collapse";
// } else if (!raw_brace_style) { //Nothing exists to set it
// raw_brace_style = "collapse";
}
//preserve-inline in delimited string will trigger brace_preserve_inline, everything
//else is considered a brace_style and the last one only will have an effect
var brace_style_split = this._get_selection('brace_style', ['collapse', 'expand', 'end-expand', 'none', 'preserve-inline']);
this.brace_preserve_inline = false; //Defaults in case one or other was not specified in meta-option
this.brace_style = "collapse";
for (var bs = 0; bs < brace_style_split.length; bs++) {
if (brace_style_split[bs] === "preserve-inline") {
this.brace_preserve_inline = true;
} else {
this.brace_style = brace_style_split[bs];
}
}
this.unindent_chained_methods = this._get_boolean('unindent_chained_methods');
this.break_chained_methods = this._get_boolean('break_chained_methods');
this.space_in_paren = this._get_boolean('space_in_paren');
this.space_in_empty_paren = this._get_boolean('space_in_empty_paren');
this.jslint_happy = this._get_boolean('jslint_happy');
this.space_after_anon_function = this._get_boolean('space_after_anon_function');
this.keep_array_indentation = this._get_boolean('keep_array_indentation');
this.space_before_conditional = this._get_boolean('space_before_conditional', true);
this.unescape_strings = this._get_boolean('unescape_strings');
this.e4x = this._get_boolean('e4x');
this.comma_first = this._get_boolean('comma_first');
this.operator_position = this._get_selection('operator_position', validPositionValues)[0];
// For testing of beautify preserve:start directive
this.test_output_raw = this._get_boolean('test_output_raw');
// force this._options.space_after_anon_function to true if this._options.jslint_happy
if (this.jslint_happy) {
this.space_after_anon_function = true;
}
}
Options.prototype = new BaseOptions();
module.exports.Options = Options;

View File

@ -39,8 +39,6 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
indent_char: ' ',
preserve_newlines: true,
jslint_happy: false,
keep_array_indentation: false,
brace_style: 'collapse',
space_before_conditional: true,
break_chained_methods: false,
selector_separator: '\n',
@ -52,9 +50,6 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
default_opts.indent_char = ' ';
default_opts.preserve_newlines = true;
default_opts.jslint_happy = false;
default_opts.keep_array_indentation = false;
default_opts.brace_style = 'collapse';
default_opts.operator_position = 'before-newline';
function reset_options()
{
@ -620,6 +615,48 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
' e();\n' +
'}');
// Brace style permutations - ()
reset_options();
set_name('Brace style permutations - ()');
bt(
'var a ={a: 2};\n' +
'var a ={a: 2};',
// -- output --
'var a = {\n' +
' a: 2\n' +
'};\n' +
'var a = {\n' +
' a: 2\n' +
'};');
bt(
'//case 1\n' +
'if (a == 1){}\n' +
'//case 2\n' +
'else if (a == 2){}',
// -- output --
'//case 1\n' +
'if (a == 1) {}\n' +
'//case 2\n' +
'else if (a == 2) {}');
bt(
'if(1){2}else{3}',
// -- output --
'if (1) {\n' +
' 2\n' +
'} else {\n' +
' 3\n' +
'}');
bt(
'try{a();}catch(b){c();}catch(d){}finally{e();}',
// -- output --
'try {\n' +
' a();\n' +
'} catch (b) {\n' +
' c();\n' +
'} catch (d) {} finally {\n' +
' e();\n' +
'}');
// Brace style permutations - (brace_style = ""collapse"")
reset_options();
set_name('Brace style permutations - (brace_style = ""collapse"")');
@ -1272,6 +1309,55 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
//============================================================
// operator_position option - ensure no neswlines if preserve_newlines is false - (preserve_newlines = "false")
reset_options();
set_name('operator_position option - ensure no neswlines if preserve_newlines is false - (preserve_newlines = "false")');
opts.preserve_newlines = false;
bt(
'var res = a + b - c / d * e % f;\n' +
'var res = g & h | i ^ j;\n' +
'var res = (k && l || m) ? n : o;\n' +
'var res = p >> q << r >>> s;\n' +
'var res = t === u !== v != w == x >= y <= z > aa < ab;\n' +
'ac + -ad');
bt(
'var res = a + b\n' +
'- c /\n' +
'd * e\n' +
'%\n' +
'f;\n' +
' var res = g & h\n' +
'| i ^\n' +
'j;\n' +
'var res = (k &&\n' +
'l\n' +
'|| m) ?\n' +
'n\n' +
': o\n' +
';\n' +
'var res = p\n' +
'>> q <<\n' +
'r\n' +
'>>> s;\n' +
'var res\n' +
' = t\n' +
'\n' +
' === u !== v\n' +
' !=\n' +
'w\n' +
'== x >=\n' +
'y <= z > aa <\n' +
'ab;\n' +
'ac +\n' +
'-ad',
// -- output --
'var res = a + b - c / d * e % f;\n' +
'var res = g & h | i ^ j;\n' +
'var res = (k && l || m) ? n : o;\n' +
'var res = p >> q << r >>> s;\n' +
'var res = t === u !== v != w == x >= y <= z > aa < ab;\n' +
'ac + -ad');
// operator_position option - ensure no neswlines if preserve_newlines is false - (operator_position = ""before-newline"", preserve_newlines = "false")
reset_options();
set_name('operator_position option - ensure no neswlines if preserve_newlines is false - (operator_position = ""before-newline"", preserve_newlines = "false")');
@ -1424,9 +1510,131 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
//============================================================
// operator_position option - set to "before-newline" (default value)
// operator_position option - set to "before-newline" (default value) - ()
reset_options();
set_name('operator_position option - set to "before-newline" (default value)');
set_name('operator_position option - set to "before-newline" (default value) - ()');
// comprehensive, various newlines
bt(
'var res = a + b\n' +
'- c /\n' +
'd * e\n' +
'%\n' +
'f;\n' +
' var res = g & h\n' +
'| i ^\n' +
'j;\n' +
'var res = (k &&\n' +
'l\n' +
'|| m) ?\n' +
'n\n' +
': o\n' +
';\n' +
'var res = p\n' +
'>> q <<\n' +
'r\n' +
'>>> s;\n' +
'var res\n' +
' = t\n' +
'\n' +
' === u !== v\n' +
' !=\n' +
'w\n' +
'== x >=\n' +
'y <= z > aa <\n' +
'ab;\n' +
'ac +\n' +
'-ad',
// -- output --
'var res = a + b -\n' +
' c /\n' +
' d * e %\n' +
' f;\n' +
'var res = g & h |\n' +
' i ^\n' +
' j;\n' +
'var res = (k &&\n' +
' l ||\n' +
' m) ?\n' +
' n :\n' +
' o;\n' +
'var res = p >>\n' +
' q <<\n' +
' r >>>\n' +
' s;\n' +
'var res = t\n' +
'\n' +
' ===\n' +
' u !== v !=\n' +
' w ==\n' +
' x >=\n' +
' y <= z > aa <\n' +
' ab;\n' +
'ac +\n' +
' -ad');
// colon special case
bt(
'var a = {\n' +
' b\n' +
': bval,\n' +
' c:\n' +
'cval\n' +
' ,d: dval\n' +
'};\n' +
'var e = f ? g\n' +
': h;\n' +
'var i = j ? k :\n' +
'l;',
// -- output --
'var a = {\n' +
' b: bval,\n' +
' c: cval,\n' +
' d: dval\n' +
'};\n' +
'var e = f ? g :\n' +
' h;\n' +
'var i = j ? k :\n' +
' l;');
// catch-all, includes brackets and other various code
bt(
'var d = 1;\n' +
'if (a === b\n' +
' && c) {\n' +
' d = (c * everything\n' +
' / something_else) %\n' +
' b;\n' +
' e\n' +
' += d;\n' +
'\n' +
'} else if (!(complex && simple) ||\n' +
' (emotion && emotion.name === "happy")) {\n' +
' cryTearsOfJoy(many ||\n' +
' anOcean\n' +
' || aRiver);\n' +
'}',
// -- output --
'var d = 1;\n' +
'if (a === b &&\n' +
' c) {\n' +
' d = (c * everything /\n' +
' something_else) %\n' +
' b;\n' +
' e\n' +
' += d;\n' +
'\n' +
'} else if (!(complex && simple) ||\n' +
' (emotion && emotion.name === "happy")) {\n' +
' cryTearsOfJoy(many ||\n' +
' anOcean ||\n' +
' aRiver);\n' +
'}');
// operator_position option - set to "before-newline" (default value) - (operator_position = ""before-newline"")
reset_options();
set_name('operator_position option - set to "before-newline" (default value) - (operator_position = ""before-newline"")');
opts.operator_position = 'before-newline';
// comprehensive, various newlines
bt(

View File

@ -52,7 +52,7 @@ def beautify_file(file_name, opts=default_options()):
raise Exception()
stream = sys.stdin
except Exception as ex:
except Exception:
print("Must pipe input or define input file.\n", file=sys.stderr)
usage(sys.stderr)
raise Exception()

View File

@ -3,8 +3,6 @@ import sys
import re
import copy
from .options import BeautifierOptions
from jsbeautifier.core.options import mergeOpts
from jsbeautifier.core.options import normalizeOpts
from jsbeautifier.core.output import Output
from jsbeautifier.core.inputscanner import InputScanner
from jsbeautifier.__version__ import __version__
@ -117,12 +115,7 @@ class Beautifier:
self.__source_text = source_text
opts = mergeOpts(opts, 'css')
opts = normalizeOpts(opts)
# Continue to accept deprecated option
opts.space_around_combinator = opts.space_around_combinator or \
opts.space_around_selector_separator
opts = BeautifierOptions(opts)
self.opts = opts
self.indentSize = opts.indent_size
@ -130,12 +123,6 @@ class Beautifier:
self.input = None
self.ch = None
if self.opts.indent_with_tabs:
self.indentChar = "\t"
self.indentSize = 1
self.opts.eol = self.opts.eol.replace('\\r', '\r').replace('\\n', '\n')
# https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
# also in CONDITIONAL_GROUP_RULE below

View File

@ -23,41 +23,18 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from jsbeautifier.core.options import Options as BaseOptions
class BeautifierOptions:
def __init__(self):
self.indent_size = 4
self.indent_char = ' '
self.indent_with_tabs = False
self.preserve_newlines = False
self.selector_separator_newline = True
self.end_with_newline = False
self.newline_between_rules = True
self.space_around_combinator = False
self.eol = 'auto'
self.disabled = False
class BeautifierOptions(BaseOptions):
def __init__(self, options=None):
super(BeautifierOptions, self).__init__(options, 'css')
self.css = None
self.js = None
self.html = None
self.selector_separator_newline = self._get_boolean('selector_separator_newline', True)
self.newline_between_rules = self._get_boolean('newline_between_rules', True)
# deprecated
self.space_around_selector_separator = False
space_around_selector_separator = self._get_boolean('space_around_selector_separator')
def __repr__(self):
return """indent_size = %d
indent_char = [%s]
indent_with_tabs = [%s]
preserve_newlines = [%s]
separate_selectors_newline = [%s]
end_with_newline = [%s]
newline_between_rules = [%s]
space_around_combinator = [%s]
""" % (self.indent_size,
self.indent_char,
self.indent_with_tabs,
self.preserve_newlines,
self.selector_separator_newline,
self.end_with_newline,
self.newline_between_rules,
self.space_around_combinator)
# Continue to accept deprecated option
self.space_around_combinator = self._get_boolean('space_around_combinator') or \
space_around_selector_separator

View File

@ -9,7 +9,7 @@ import errno
import copy
from jsbeautifier.__version__ import __version__
from jsbeautifier.javascript.options import BeautifierOptions
from jsbeautifier.javascript.beautifier import Beautifier, sanitizeOperatorPosition
from jsbeautifier.javascript.beautifier import Beautifier
#
# The MIT License (MIT)
@ -275,7 +275,7 @@ def main():
elif opt in ('--comma-first', '-C'):
js_options.comma_first = True
elif opt in ('--operator-position', '-O'):
js_options.operator_position = sanitizeOperatorPosition(arg)
js_options.operator_position = arg
elif opt in ('--wrap-line-length ', '-w'):
js_options.wrap_line_length = int(arg)
elif opt in ('--stdin', '-i'):

View File

@ -23,6 +23,106 @@
# SOFTWARE.
import copy
import re
class Options:
def __init__(self, options=None, merge_child_field=None):
self.css = None
self.js = None
self.html = None
options = _mergeOpts(options, merge_child_field)
self.raw_options = _normalizeOpts(options)
# Support passing the source text back with no change
self.disabled = self._get_boolean('disabled')
self.eol = self._get_characters('eol', 'auto')
self.end_with_newline = self._get_boolean('end_with_newline')
self.indent_size = self._get_number('indent_size', 4)
self.indent_char = self._get_characters('indent_char', ' ')
self.preserve_newlines = self._get_boolean('preserve_newlines', True)
# TODO: fix difference in js and python
self.max_preserve_newlines = self.max_preserve_newlines = self._get_number('max_preserve_newlines', 10)
if not self.preserve_newlines:
self.max_preserve_newlines = 0
self.indent_with_tabs = self._get_boolean('indent_with_tabs')
if self.indent_with_tabs:
self.indent_char = '\t'
self.indent_size = 1
self.indent_string = self.indent_char * self.indent_size
# Backwards compat with 1.3.x
self.wrap_line_length = self._get_number('wrap_line_length', self._get_number('max_char'))
def _get_array(self, name, default_value=[]):
option_value = getattr(self.raw_options, name, default_value)
result = []
if isinstance(option_value, list):
result = copy.copy(option_value)
elif isinstance(option_value, str):
result = re.compile(r"[^a-zA-Z0-9_/\-]+").split(option_value)
return result
def _get_boolean(self, name, default_value=False):
option_value = getattr(self.raw_options, name, default_value)
result = False
try:
result = bool(option_value)
except ValueError:
pass
return result
def _get_characters(self, name, default_value=''):
option_value = getattr(self.raw_options, name, default_value)
result = ''
if isinstance(option_value, str):
result = option_value.replace('\\r', '\r').replace('\\n', '\n').replace('\\t', '\t')
return result
def _get_number(self, name, default_value=0):
option_value = getattr(self.raw_options, name, default_value)
result = 0
try:
result = int(option_value)
except ValueError:
pass
return result
def _get_selection(self, name, selection_list, default_value=None):
default_value = default_value or [selection_list[0]]
if not self._is_valid_selection(default_value, selection_list):
raise ValueError("Invalid Default Value!")
result = self._get_array(name, default_value)
self._is_valid_selection(result, selection_list)
if not self._is_valid_selection(result, selection_list):
raise ValueError(
"Invalid Option Value: The option 'operator_position' must be one of the following values\n" +
str(selection_list) +
"\nYou passed in: '" +
str(getattr(self.raw_options, name, None)) +
"'")
return result
def _is_valid_selection(self, result, selection_list):
if len(result) == 0 or len(selection_list) == 0:
return False
for item in result:
if item not in selection_list:
return False
return True
# merges child options up with the parent options object
# Example: obj = {a: 1, b: {a: 2}}
@ -31,8 +131,8 @@ import copy
# Returns: {a: 2, b: {a: 2}}
def mergeOpts(options, childFieldName):
finalOpts = copy.copy(options)
def _mergeOpts(options, childFieldName):
finalOpts = copy.copy(options) or object()
local = getattr(finalOpts, childFieldName, None)
if local:
@ -42,10 +142,10 @@ def mergeOpts(options, childFieldName):
return finalOpts
def normalizeOpts(options):
convertedOpts = copy.copy(options)
for key in options.__dict__:
def _normalizeOpts(options):
convertedOpts = copy.copy(options) or object()
option_keys = copy.copy(getattr(convertedOpts, '__dict__', {}))
for key in option_keys:
if '-' in key:
delattr(convertedOpts, key)
setattr(convertedOpts, key.replace('-', '_'), getattr(options, key, None))

View File

@ -28,8 +28,6 @@ import copy
from .tokenizer import Tokenizer
from .tokenizer import TOKEN
from .options import BeautifierOptions
from ..core.options import mergeOpts
from ..core.options import normalizeOpts
from ..core.output import Output
@ -82,21 +80,6 @@ OPERATOR_POSITION_BEFORE_OR_PRESERVE = [
OPERATOR_POSITION['preserve_newline']]
def sanitizeOperatorPosition(opPosition):
if not opPosition:
return OPERATOR_POSITION['before_newline']
elif opPosition not in OPERATOR_POSITION.values():
raise ValueError(
"Invalid Option Value: The option 'operator_position' must be one of the following values\n" +
str(
OPERATOR_POSITION.values()) +
"\nYou passed in: '" +
opPosition +
"'")
return opPosition
class MODE:
BlockStatement, Statement, ObjectLiteral, ArrayLiteral, \
ForInitializer, Conditional, Expression = range(7)
@ -119,10 +102,10 @@ def remove_redundant_indentation(output, frame):
class Beautifier:
def __init__(self, opts=default_options()):
def __init__(self, opts=None):
import jsbeautifier.core.acorn as acorn
self.acorn = acorn
self._options = copy.copy(opts)
self._options = BeautifierOptions(opts)
self._blank_state()
@ -136,23 +119,12 @@ class Beautifier:
self._flag_store = []
self._tokens = None
# force opts.space_after_anon_function to true if opts.jslint_happy
if self._options.jslint_happy:
self._options.space_after_anon_function = True
if self._options.indent_with_tabs:
self._options.indent_char = "\t"
self._options.indent_size = 1
if self._options.eol == 'auto':
self._options.eol = '\n'
if self.acorn.lineBreak.search(js_source_text or ''):
self._options.eol = self.acorn.lineBreak.search(
js_source_text).group()
self._options.eol = self._options.eol.replace('\\r', '\r').replace('\\n', '\n')
indent_string = self._options.indent_char * self._options.indent_size
baseIndentString = ''
self._last_type = TOKEN.START_BLOCK # last token type
@ -166,7 +138,7 @@ class Beautifier:
preindent_index += 1
js_source_text = js_source_text[preindent_index:]
self._output = Output(indent_string, baseIndentString)
self._output = Output(self._options.indent_string, baseIndentString)
# If testing the ignore directive, start with output disable set to
# true
self._output.raw = self._options.test_output_raw
@ -176,32 +148,8 @@ class Beautifier:
def beautify(self, source_text='', opts=None):
if opts is not None:
opts = mergeOpts(opts, 'js')
opts = normalizeOpts(opts)
self._options = copy.copy(opts)
self._options = BeautifierOptions(opts)
# Compat with old form
if self._options.brace_style == 'collapse-preserve-inline':
self._options.brace_style = 'collapse,preserve-inline'
# split always returns at least one value
split = re.compile(r"[^a-zA-Z0-9_\-]+").split(self._options.brace_style)
# preserve-inline in delimited string will trigger brace_preserve_inline
# Everything else is considered a brace_style and the last one only will
# have an effect
# specify defaults in case one half of meta-option is missing
self._options.brace_style = "collapse"
self._options.brace_preserve_inline = False
for bs in split:
if bs == "preserve-inline":
self._options.brace_preserve_inline = True
else:
# validate each brace_style that's not a preserve-inline
# (results in very similar validation as js version)
if bs not in ['expand', 'collapse', 'end-expand', 'none']:
raise(Exception(
'opts.brace_style must be "expand", "collapse", "end-expand", or "none".'))
self._options.brace_style = bs
source_text = source_text or ''
if self._options.disabled:

View File

@ -23,67 +23,71 @@
# SOFTWARE.
class BeautifierOptions:
def __init__(self):
self.indent_size = 4
self.indent_char = ' '
self.indent_with_tabs = False
self.eol = 'auto'
self.preserve_newlines = True
self.max_preserve_newlines = 10
self.space_in_paren = False
self.space_in_empty_paren = False
self.e4x = False
self.jslint_happy = False
self.space_after_anon_function = False
self.brace_style = 'collapse'
self.keep_array_indentation = False
self.space_before_conditional = True
self.keep_function_indentation = False
self.eval_code = False
self.unescape_strings = False
self.wrap_line_length = 0
self.unindent_chained_methods = False
self.break_chained_methods = False
self.end_with_newline = False
self.comma_first = False
self.operator_position = 'before-newline'
self.disabled = False
from ..core.options import Options as BaseOptions
OPERATOR_POSITION = [
'before-newline',
'after-newline',
'preserve-newline'
]
class BeautifierOptions(BaseOptions):
def __init__(self, options=None):
super(BeautifierOptions, self).__init__(options, 'js')
self.css = None
self.js = None
self.html = None
# compatibility, re
raw_brace_style = getattr(self.raw_options, 'brace_style', None)
if raw_brace_style == "expand-strict": # graceful handling of deprecated option
setattr(self.raw_options, 'brace_style', "expand")
elif raw_brace_style == "collapse-preserve-inline": # graceful handling of deprecated option
setattr(self.raw_options, 'brace_style', "collapse,preserve-inline")
# elif bool(self.raw_options.braces_on_own_line): # graceful handling of deprecated option
# raw_brace_style = "expand": "collapse"
# elif raw_brace_style is None: # Nothing exists to set it
# setattr(self.raw_options, 'brace_style', "collapse")
# preserve-inline in delimited string will trigger brace_preserve_inline, everything
# else is considered a brace_style and the last one only will have an effect
brace_style_split = self._get_selection('brace_style', ['collapse', 'expand', 'end-expand', 'none', 'preserve-inline'])
# preserve-inline in delimited string will trigger brace_preserve_inline
# Everything else is considered a brace_style and the last one only will
# have an effect
# specify defaults in case one half of meta-option is missing
self.brace_preserve_inline = False
self.brace_style = "collapse"
for bs in brace_style_split:
if bs == "preserve-inline":
self.brace_preserve_inline = True
else:
self.brace_style = bs
self.unindent_chained_methods = self._get_boolean('unindent_chained_methods')
self.break_chained_methods = self._get_boolean('break_chained_methods')
self.space_in_paren = self._get_boolean('space_in_paren')
self.space_in_empty_paren = self._get_boolean('space_in_empty_paren')
self.jslint_happy = self._get_boolean('jslint_happy')
self.space_after_anon_function = self._get_boolean('space_after_anon_function')
self.keep_array_indentation = self._get_boolean('keep_array_indentation')
self.space_before_conditional = self._get_boolean('space_before_conditional', True)
self.unescape_strings = self._get_boolean('unescape_strings')
self.e4x = self._get_boolean('e4x')
self.comma_first = self._get_boolean('comma_first')
self.operator_position = self._get_selection('operator_position', OPERATOR_POSITION)[0]
# For testing of beautify preserve:start directive
self.test_output_raw = False
self.editorconfig = False
def __repr__(self):
return \
"""indent_size = %d
indent_char = [%s]
preserve_newlines = %s
max_preserve_newlines = %d
space_in_paren = %s
jslint_happy = %s
space_after_anon_function = %s
indent_with_tabs = %s
brace_style = %s
keep_array_indentation = %s
eval_code = %s
wrap_line_length = %s
unescape_strings = %s
""" % (self.indent_size,
self.indent_char,
self.preserve_newlines,
self.max_preserve_newlines,
self.space_in_paren,
self.jslint_happy,
self.space_after_anon_function,
self.indent_with_tabs,
self.brace_style,
self.keep_array_indentation,
self.eval_code,
self.wrap_line_length,
self.unescape_strings,
)
# force opts.space_after_anon_function to true if opts.jslint_happy
if self.jslint_happy:
self.space_after_anon_function = True
self.eval_code = False

View File

@ -115,7 +115,7 @@ class Tokenizer(BaseTokenizer):
line_starters = line_starters
def __init__(self, input_string, opts):
BaseTokenizer.__init__(self, input_string, opts)
super(Tokenizer, self).__init__(input_string, opts)
self.in_html_comment = False
self.has_char_escapes = False

View File

@ -55,8 +55,6 @@ class TestJSBeautifier(unittest.TestCase):
default_options.indent_char = ' '
default_options.preserve_newlines = true
default_options.jslint_happy = false
default_options.keep_array_indentation = true
default_options.brace_style = 'collapse'
default_options.indent_level = 0
default_options.break_chained_methods = false
default_options.eol = '\n'
@ -65,9 +63,6 @@ class TestJSBeautifier(unittest.TestCase):
default_options.indent_char = ' '
default_options.preserve_newlines = true
default_options.jslint_happy = false
default_options.keep_array_indentation = false
default_options.brace_style = 'collapse'
default_options.operator_position = 'before-newline'
self.options = copy.copy(default_options)
@ -416,6 +411,47 @@ class TestJSBeautifier(unittest.TestCase):
' e();\n' +
'}')
# Brace style permutations - ()
self.reset_options()
bt(
'var a ={a: 2};\n' +
'var a ={a: 2};',
# -- output --
'var a = {\n' +
' a: 2\n' +
'};\n' +
'var a = {\n' +
' a: 2\n' +
'};')
bt(
'//case 1\n' +
'if (a == 1){}\n' +
'//case 2\n' +
'else if (a == 2){}',
# -- output --
'//case 1\n' +
'if (a == 1) {}\n' +
'//case 2\n' +
'else if (a == 2) {}')
bt(
'if(1){2}else{3}',
# -- output --
'if (1) {\n' +
' 2\n' +
'} else {\n' +
' 3\n' +
'}')
bt(
'try{a();}catch(b){c();}catch(d){}finally{e();}',
# -- output --
'try {\n' +
' a();\n' +
'} catch (b) {\n' +
' c();\n' +
'} catch (d) {} finally {\n' +
' e();\n' +
'}')
# Brace style permutations - (brace_style = ""collapse"")
self.reset_options()
self.options.brace_style = 'collapse'
@ -1059,6 +1095,54 @@ class TestJSBeautifier(unittest.TestCase):
#============================================================
# operator_position option - ensure no neswlines if preserve_newlines is false - (preserve_newlines = "false")
self.reset_options()
self.options.preserve_newlines = false
bt(
'var res = a + b - c / d * e % f;\n' +
'var res = g & h | i ^ j;\n' +
'var res = (k && l || m) ? n : o;\n' +
'var res = p >> q << r >>> s;\n' +
'var res = t === u !== v != w == x >= y <= z > aa < ab;\n' +
'ac + -ad')
bt(
'var res = a + b\n' +
'- c /\n' +
'd * e\n' +
'%\n' +
'f;\n' +
' var res = g & h\n' +
'| i ^\n' +
'j;\n' +
'var res = (k &&\n' +
'l\n' +
'|| m) ?\n' +
'n\n' +
': o\n' +
';\n' +
'var res = p\n' +
'>> q <<\n' +
'r\n' +
'>>> s;\n' +
'var res\n' +
' = t\n' +
'\n' +
' === u !== v\n' +
' !=\n' +
'w\n' +
'== x >=\n' +
'y <= z > aa <\n' +
'ab;\n' +
'ac +\n' +
'-ad',
# -- output --
'var res = a + b - c / d * e % f;\n' +
'var res = g & h | i ^ j;\n' +
'var res = (k && l || m) ? n : o;\n' +
'var res = p >> q << r >>> s;\n' +
'var res = t === u !== v != w == x >= y <= z > aa < ab;\n' +
'ac + -ad')
# operator_position option - ensure no neswlines if preserve_newlines is false - (operator_position = ""before-newline"", preserve_newlines = "false")
self.reset_options()
self.options.operator_position = 'before-newline'
@ -1208,7 +1292,7 @@ class TestJSBeautifier(unittest.TestCase):
#============================================================
# operator_position option - set to "before-newline" (default value)
# operator_position option - set to "before-newline" (default value) - ()
self.reset_options()
# comprehensive, various newlines
@ -1328,6 +1412,127 @@ class TestJSBeautifier(unittest.TestCase):
' aRiver);\n' +
'}')
# operator_position option - set to "before-newline" (default value) - (operator_position = ""before-newline"")
self.reset_options()
self.options.operator_position = 'before-newline'
# comprehensive, various newlines
bt(
'var res = a + b\n' +
'- c /\n' +
'd * e\n' +
'%\n' +
'f;\n' +
' var res = g & h\n' +
'| i ^\n' +
'j;\n' +
'var res = (k &&\n' +
'l\n' +
'|| m) ?\n' +
'n\n' +
': o\n' +
';\n' +
'var res = p\n' +
'>> q <<\n' +
'r\n' +
'>>> s;\n' +
'var res\n' +
' = t\n' +
'\n' +
' === u !== v\n' +
' !=\n' +
'w\n' +
'== x >=\n' +
'y <= z > aa <\n' +
'ab;\n' +
'ac +\n' +
'-ad',
# -- output --
'var res = a + b -\n' +
' c /\n' +
' d * e %\n' +
' f;\n' +
'var res = g & h |\n' +
' i ^\n' +
' j;\n' +
'var res = (k &&\n' +
' l ||\n' +
' m) ?\n' +
' n :\n' +
' o;\n' +
'var res = p >>\n' +
' q <<\n' +
' r >>>\n' +
' s;\n' +
'var res = t\n' +
'\n' +
' ===\n' +
' u !== v !=\n' +
' w ==\n' +
' x >=\n' +
' y <= z > aa <\n' +
' ab;\n' +
'ac +\n' +
' -ad')
# colon special case
bt(
'var a = {\n' +
' b\n' +
': bval,\n' +
' c:\n' +
'cval\n' +
' ,d: dval\n' +
'};\n' +
'var e = f ? g\n' +
': h;\n' +
'var i = j ? k :\n' +
'l;',
# -- output --
'var a = {\n' +
' b: bval,\n' +
' c: cval,\n' +
' d: dval\n' +
'};\n' +
'var e = f ? g :\n' +
' h;\n' +
'var i = j ? k :\n' +
' l;')
# catch-all, includes brackets and other various code
bt(
'var d = 1;\n' +
'if (a === b\n' +
' && c) {\n' +
' d = (c * everything\n' +
' / something_else) %\n' +
' b;\n' +
' e\n' +
' += d;\n' +
'\n' +
'} else if (!(complex && simple) ||\n' +
' (emotion && emotion.name === "happy")) {\n' +
' cryTearsOfJoy(many ||\n' +
' anOcean\n' +
' || aRiver);\n' +
'}',
# -- output --
'var d = 1;\n' +
'if (a === b &&\n' +
' c) {\n' +
' d = (c * everything /\n' +
' something_else) %\n' +
' b;\n' +
' e\n' +
' += d;\n' +
'\n' +
'} else if (!(complex && simple) ||\n' +
' (emotion && emotion.name === "happy")) {\n' +
' cryTearsOfJoy(many ||\n' +
' anOcean ||\n' +
' aRiver);\n' +
'}')
#============================================================
# operator_position option - set to "after_newline"

View File

@ -685,26 +685,12 @@ exports.test_data = {
],
tests: [{
fragment: true,
input_: '{{#if 0}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}',
output: '{{#if 0}}\n' +
'<div>\n' +
'</div>\n' +
'{{/if}}'
input_: '{{#if 0}}\n' + ' <div>\n' + ' </div>\n' + '{{/if}}',
output: '{{#if 0}}\n' + '<div>\n' + '</div>\n' + '{{/if}}'
}, {
fragment: true,
input_: '<div>\n' +
'{{#each thing}}\n' +
' {{name}}\n' +
'{{/each}}\n' +
'</div>',
output: '<div>\n' +
' {{#each thing}}\n' +
' {{name}}\n' +
' {{/each}}\n' +
'</div>'
input_: '<div>\n' + '{{#each thing}}\n' + ' {{name}}\n' + '{{/each}}\n' + '</div>',
output: '<div>\n' + ' {{#each thing}}\n' + ' {{name}}\n' + ' {{/each}}\n' + '</div>'
},
{
input_: [
@ -858,59 +844,20 @@ exports.test_data = {
input_: '{{#if words}}^^^&content$$${{/if}}',
output: '{{#if words}}^^^&content$$${{/if}}'
}, {
unchanged: '{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}'
unchanged: '{{#if 1}}\n' + ' <div>\n' + ' </div>\n' + '{{/if}}'
}, {
input_: '{{#if 1}}\n' +
'<div>\n' +
'</div>\n' +
'{{/if}}',
output: '{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}'
input_: '{{#if 1}}\n' + '<div>\n' + '</div>\n' + '{{/if}}',
output: '{{#if 1}}\n' + ' <div>\n' + ' </div>\n' + '{{/if}}'
}, {
unchanged: '<div>\n' +
' {{#if 1}}\n' +
' {{/if}}\n' +
'</div>'
unchanged: '<div>\n' + ' {{#if 1}}\n' + ' {{/if}}\n' + '</div>'
}, {
input_: '<div>\n' +
'{{#if 1}}\n' +
'{{/if}}\n' +
'</div>',
output: '<div>\n' +
' {{#if 1}}\n' +
' {{/if}}\n' +
'</div>'
input_: '<div>\n' + '{{#if 1}}\n' + '{{/if}}\n' + '</div>',
output: '<div>\n' + ' {{#if 1}}\n' + ' {{/if}}\n' + '</div>'
}, {
input_: '{{#if}}\n' +
'{{#each}}\n' +
'{{#if}}\n' +
'^^^&content$$$\n' +
'{{/if}}\n' +
'{{#if}}\n' +
'^^^&content$$$\n' +
'{{/if}}\n' +
'{{/each}}\n' +
'{{/if}}',
output: '{{#if}}\n' +
' {{#each}}\n' +
' {{#if}}\n' +
' ^^^&content$$$\n' +
' {{/if}}\n' +
' {{#if}}\n' +
' ^^^&content$$$\n' +
' {{/if}}\n' +
' {{/each}}\n' +
'{{/if}}'
input_: '{{#if}}\n' + '{{#each}}\n' + '{{#if}}\n' + '^^^&content$$$\n' + '{{/if}}\n' + '{{#if}}\n' + '^^^&content$$$\n' + '{{/if}}\n' + '{{/each}}\n' + '{{/if}}',
output: '{{#if}}\n' + ' {{#each}}\n' + ' {{#if}}\n' + ' ^^^&content$$$\n' + ' {{/if}}\n' + ' {{#if}}\n' + ' ^^^&content$$$\n' + ' {{/if}}\n' + ' {{/each}}\n' + '{{/if}}'
}, {
unchanged: '{{#if 1}}\n' +
' <div>\n' +
' </div>\n' +
'{{/if}}'
unchanged: '{{#if 1}}\n' + ' <div>\n' + ' </div>\n' + '{{/if}}'
},
// Issue #576 -- Indent Formatting with Handlebars
@ -982,42 +929,14 @@ exports.test_data = {
// Test {{else}} aligned with {{#if}} and {{/if}}
{
input_: '{{#if 1}}\n' +
' ^^^&content$$$\n' +
' {{else}}\n' +
' ^^^&content$$$\n' +
'{{/if}}',
output: '{{#if 1}}\n' +
' ^^^&content$$$\n' +
'{{else}}\n' +
' ^^^&content$$$\n' +
'{{/if}}'
input_: '{{#if 1}}\n' + ' ^^^&content$$$\n' + ' {{else}}\n' + ' ^^^&content$$$\n' + '{{/if}}',
output: '{{#if 1}}\n' + ' ^^^&content$$$\n' + '{{else}}\n' + ' ^^^&content$$$\n' + '{{/if}}'
}, {
input_: '{{#if 1}}\n' +
' {{else}}\n' +
' {{/if}}',
output: '{{#if 1}}\n' +
'{{else}}\n' +
'{{/if}}'
input_: '{{#if 1}}\n' + ' {{else}}\n' + ' {{/if}}',
output: '{{#if 1}}\n' + '{{else}}\n' + '{{/if}}'
}, {
input_: '{{#if thing}}\n' +
'{{#if otherthing}}\n' +
' ^^^&content$$$\n' +
' {{else}}\n' +
'^^^&content$$$\n' +
' {{/if}}\n' +
' {{else}}\n' +
'^^^&content$$$\n' +
'{{/if}}',
output: '{{#if thing}}\n' +
' {{#if otherthing}}\n' +
' ^^^&content$$$\n' +
' {{else}}\n' +
' ^^^&content$$$\n' +
' {{/if}}\n' +
'{{else}}\n' +
' ^^^&content$$$\n' +
'{{/if}}'
input_: '{{#if thing}}\n' + '{{#if otherthing}}\n' + ' ^^^&content$$$\n' + ' {{else}}\n' + '^^^&content$$$\n' + ' {{/if}}\n' + ' {{else}}\n' + '^^^&content$$$\n' + '{{/if}}',
output: '{{#if thing}}\n' + ' {{#if otherthing}}\n' + ' ^^^&content$$$\n' + ' {{else}}\n' + ' ^^^&content$$$\n' + ' {{/if}}\n' + '{{else}}\n' + ' ^^^&content$$$\n' + '{{/if}}'
},
{
comment: 'ISSUE #800 and #1123: else if and #unless',
@ -1089,11 +1008,7 @@ exports.test_data = {
],
tests: [{
input_: '{{#if test}}<div></div>{{else}}<div></div>{{/if}}',
output: '{{#if test}}\n' +
' <div></div>\n' +
'{{else}}\n' +
' <div></div>\n' +
'{{/if}}'
output: '{{#if test}}\n' + ' <div></div>\n' + '{{else}}\n' + ' <div></div>\n' + '{{/if}}'
}, {
unchanged: '{{#if test}}<span></span>{{else}}<span></span>{{/if}}'
},
@ -1835,14 +1750,8 @@ exports.test_data = {
],
tests: [{
fragment: true,
input_: '<div>\n' +
'<div>\n' +
'</div>\n' +
'</div>',
output: '<div>\n' +
' <div>\n' +
' </div>\n' +
'</div>'
input_: '<div>\n' + '<div>\n' + '</div>\n' + '</div>',
output: '<div>\n' + ' <div>\n' + ' </div>\n' + '</div>'
}]
}, {
name: "Do not indent html inner html by default",
@ -1935,10 +1844,8 @@ exports.test_data = {
input: '<div>\n\tfoo\n</div>',
output: '<div> foo </div>'
}, {
input_: '<div>Should not</div>\n\n\n' +
'<div>preserve newlines</div>',
output: '<div>Should not</div>\n' +
'<div>preserve newlines</div>'
input_: '<div>Should not</div>\n\n\n' + '<div>preserve newlines</div>',
output: '<div>Should not</div>\n' + '<div>preserve newlines</div>'
}, {
input: [
'<header>',
@ -1993,10 +1900,8 @@ exports.test_data = {
{ name: 'indent_size', value: "2" }
],
tests: [{
input_: '<div>Should</div>\n\n\n' +
'<div>preserve zero newlines</div>',
output: '<div>Should</div>\n' +
'<div>preserve zero newlines</div>'
input_: '<div>Should</div>\n\n\n' + '<div>preserve zero newlines</div>',
output: '<div>Should</div>\n' + '<div>preserve zero newlines</div>'
}, {
input: [
'<header>',
@ -2039,10 +1944,8 @@ exports.test_data = {
{ name: 'max_preserve_newlines', value: "1" }
],
tests: [{
input_: '<div>Should</div>\n\n\n' +
'<div>preserve one newline</div>',
output: '<div>Should</div>\n\n' +
'<div>preserve one newline</div>'
input_: '<div>Should</div>\n\n\n' + '<div>preserve one newline</div>',
output: '<div>Should</div>\n\n' + '<div>preserve one newline</div>'
}, {
input: [
'<header>',
@ -2088,8 +1991,7 @@ exports.test_data = {
{ name: 'max_preserve_newlines', value: "null" }
],
tests: [{
unchanged: '<div>Should</div>\n\n\n' +
'<div>preserve zero newlines</div>'
unchanged: '<div>Should</div>\n\n\n' + '<div>preserve zero newlines</div>'
}, {
unchanged: [
'<header>',

View File

@ -36,8 +36,6 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify,
indent_char: ' ',
preserve_newlines: true,
jslint_happy: false,
keep_array_indentation: false,
brace_style: 'collapse',
space_before_conditional: true,
break_chained_methods: false,
selector_separator: '\n',

View File

@ -52,8 +52,6 @@ class TestJSBeautifier(unittest.TestCase):
default_options.indent_char = ' '
default_options.preserve_newlines = true
default_options.jslint_happy = false
default_options.keep_array_indentation = true
default_options.brace_style = 'collapse'
default_options.indent_level = 0
default_options.break_chained_methods = false
default_options.eol = '\n'

View File

@ -31,10 +31,7 @@ exports.test_data = {
{ name: "indent_size", value: "4" },
{ name: "indent_char", value: "' '" },
{ name: "preserve_newlines", value: "true" },
{ name: "jslint_happy", value: "false" },
{ name: "keep_array_indentation", value: "false" },
{ name: "brace_style", value: "'collapse'" },
{ name: "operator_position", value: "'before-newline'" }
{ name: "jslint_happy", value: "false" }
],
groups: [{
name: "Unicode Support",
@ -257,6 +254,17 @@ exports.test_data = {
},
// brace_style collapse - Shouldn't preserve if no newlines (uses collapse styling)
{
options: [],
ibo: '',
iao: '',
ibc: '',
iac: '',
obo: ' ',
oao: '\n ',
obc: '\n',
oac: ' '
},
{
options: [
{ name: "brace_style", value: "'collapse'" }
@ -301,16 +309,10 @@ exports.test_data = {
output: 'if (1)<obo>{<oao>2<obc>}<oac>else<obo>{<oao>3<obc>}'
},
{
input: 'try<ibo>{<iao>a();<ibc>}<iac>' +
'catch(b)<ibo>{<iao>c();<ibc>}<iac>' +
'catch(d)<ibo>{}<iac>' +
'finally<ibo>{<iao>e();<ibc>}',
input: 'try<ibo>{<iao>a();<ibc>}<iac>' + 'catch(b)<ibo>{<iao>c();<ibc>}<iac>' + 'catch(d)<ibo>{}<iac>' + 'finally<ibo>{<iao>e();<ibc>}',
output:
// expected
'try<obo>{<oao>a();<obc>}<oac>' +
'catch (b)<obo>{<oao>c();<obc>}<oac>' +
'catch (d)<obo>{}<oac>' +
'finally<obo>{<oao>e();<obc>}'
'try<obo>{<oao>a();<obc>}<oac>' + 'catch (b)<obo>{<oao>c();<obc>}<oac>' + 'catch (d)<obo>{}<oac>' + 'finally<obo>{<oao>e();<obc>}'
}
]
}, {
@ -573,6 +575,12 @@ exports.test_data = {
}, {
name: "operator_position option - ensure no neswlines if preserve_newlines is false",
matrix: [{
options: [
// test for default
// { name: "operator_position", value: "'before-newline'" },
{ name: "preserve_newlines", value: "false" }
]
}, {
options: [
{ name: "operator_position", value: "'before-newline'" },
{ name: "preserve_newlines", value: "false" }
@ -596,6 +604,16 @@ exports.test_data = {
}]
}, {
name: 'operator_position option - set to "before-newline" (default value)',
matrix: [{
options: [
// test for default
// { name: "operator_position", value: "'before-newline'" }
]
}, {
options: [
{ name: "operator_position", value: "'before-newline'" }
]
}],
tests: [{
comment: 'comprehensive, various newlines',
input: inputlib.operator_position.comprehensive,
@ -2749,8 +2767,7 @@ exports.test_data = {
' var obj = {<oao>' + //NL in templates
'<oaot><oaot>a: function() { console.log("test"); },',
' b()<obo><obot><obot>{<oao>' + //NL in templates
'<oaot><oaot><oaot>console.log("test2");' +
'<obc> }' + //NL in templates
'<oaot><oaot><oaot>console.log("test2");' + '<obc> }' + //NL in templates
'<obc> };' + //NL in templates
'<obc>}'
]