jsbeautifier-1.10.3/ 0000755 0000765 0000024 00000000000 13607410064 015536 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/MANIFEST.in 0000644 0000765 0000024 00000000055 13476247317 017311 0 ustar bitwiseman staff 0000000 0000000 include js-beautify
include js-beautify-test
jsbeautifier-1.10.3/PKG-INFO 0000644 0000765 0000024 00000000525 13607410064 016635 0 ustar bitwiseman staff 0000000 0000000 Metadata-Version: 1.0
Name: jsbeautifier
Version: 1.10.3
Summary: JavaScript unobfuscator and beautifier.
Home-page: https://beautifier.io
Author: Liam Newman, Einar Lielmanis, et al.
Author-email: team@beautifier.io
License: MIT
Description: Beautify, unpack or deobfuscate JavaScript. Handles popular online obfuscators.
Platform: UNKNOWN
jsbeautifier-1.10.3/js-beautify-test 0000755 0000765 0000024 00000000215 13476247317 020676 0 ustar bitwiseman staff 0000000 0000000 #! /bin/sh
#
# Test suite launcher
#
if [ -z $PYTHON ]; then
env python js-beautify-test.py
else
env $PYTHON js-beautify-test.py
fi
jsbeautifier-1.10.3/jsbeautifier/ 0000755 0000765 0000024 00000000000 13607410063 020211 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/jsbeautifier/__init__.py 0000644 0000765 0000024 00000041761 13607407716 022346 0 ustar bitwiseman staff 0000000 0000000 from __future__ import print_function
import sys
import os
import platform
import io
import getopt
import re
import string
import errno
import copy
import glob
from jsbeautifier.__version__ import __version__
from jsbeautifier.javascript.options import BeautifierOptions
from jsbeautifier.javascript.beautifier import Beautifier
#
# 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.
#
# Originally written by Einar Lielmanis et al.,
# Conversion to python by Einar Lielmanis, einar@beautifier.io,
# Parsing improvement for brace-less and semicolon-less statements
# by Liam Newman
# Python is not my native language, feel free to push things around.
#
# Use either from command line (script displays its usage when run
# without any parameters),
#
#
# or, alternatively, use it as a module:
#
# import jsbeautifier
# res = jsbeautifier.beautify('your javascript string')
# res = jsbeautifier.beautify_file('some_file.js')
#
# you may specify some options:
#
# opts = jsbeautifier.default_options()
# opts.indent_size = 2
# res = jsbeautifier.beautify('some javascript', opts)
#
#
# Here are the available options: (read source)
class MissingInputStreamError(Exception):
pass
def default_options():
return BeautifierOptions()
def beautify(string, opts=default_options()):
b = Beautifier()
return b.beautify(string, opts)
def set_file_editorconfig_opts(filename, js_options):
from editorconfig import get_properties, EditorConfigError
try:
_ecoptions = get_properties(os.path.abspath(filename))
if _ecoptions.get("indent_style") == "tab":
js_options.indent_with_tabs = True
elif _ecoptions.get("indent_style") == "space":
js_options.indent_with_tabs = False
if _ecoptions.get("indent_size"):
js_options.indent_size = int(_ecoptions["indent_size"])
if _ecoptions.get("max_line_length"):
if _ecoptions.get("max_line_length") == "off":
js_options.wrap_line_length = 0
else:
js_options.wrap_line_length = int(
_ecoptions["max_line_length"])
if _ecoptions.get("insert_final_newline") == 'true':
js_options.end_with_newline = True
elif _ecoptions.get("insert_final_newline") == 'false':
js_options.end_with_newline = False
if _ecoptions.get("end_of_line"):
if _ecoptions["end_of_line"] == "cr":
js_options.eol = '\r'
elif _ecoptions["end_of_line"] == "lf":
js_options.eol = '\n'
elif _ecoptions["end_of_line"] == "crlf":
js_options.eol = '\r\n'
except EditorConfigError:
# do not error on bad editor config
print("Error loading EditorConfig. Ignoring.", file=sys.stderr)
def beautify_file(file_name, opts=default_options()):
input_string = ''
if file_name == '-': # stdin
if sys.stdin.isatty():
raise MissingInputStreamError()
stream = sys.stdin
if platform.platform().lower().startswith('windows'):
if sys.version_info.major >= 3:
# for python 3 on windows this prevents conversion
stream = io.TextIOWrapper(sys.stdin.buffer, newline='')
elif platform.architecture()[0] == '32bit':
# for python 2 x86 on windows this prevents conversion
import msvcrt
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
else:
raise Exception('Pipe to stdin not supported on Windows with Python 2.x 64-bit.')
input_string = stream.read()
# if you pipe an empty string, that is a failure
if input_string == '':
raise MissingInputStreamError()
else:
stream = io.open(file_name, 'rt', newline='', encoding='UTF-8')
input_string = stream.read()
return beautify(input_string, opts)
def usage(stream=sys.stdout):
print("jsbeautifier.py@" + __version__ + """
Javascript beautifier (https://beautifier.io/)
Usage: jsbeautifier.py [options]
can be "-", which means stdin.
Input options:
-i, --stdin Read input from stdin
Output options:
-s, --indent-size=NUMBER Indentation size. (default 4).
-c, --indent-char=CHAR Character to indent with. (default space).
-e, --eol=STRING Character(s) to use as line terminators.
(default first newline in file, otherwise "\\n")
-t, --indent-with-tabs Indent with tabs, overrides -s and -c
-d, --disable-preserve-newlines Do not preserve existing line breaks.
-P, --space-in-paren Add padding spaces within paren, ie. f( a, b )
-E, --space-in-empty-paren Add a single space inside empty paren, ie. f( )
-j, --jslint-happy More jslint-compatible output
-a, --space-after-anon-function Add a space before an anonymous function's parens, ie. function ()
--space-after-named-function Add a space before a named function's parens, i.e. function example ()
-b, --brace-style=collapse Brace style (collapse, expand, end-expand, none)(,preserve-inline)
-k, --keep-array-indentation Keep array indentation.
-r, --replace Write output in-place, replacing input
-o, --outfile=FILE Specify a file to output to (default stdout)
-f, --keep-function-indentation Do not re-indent function bodies defined in var lines.
-x, --unescape-strings Decode printable chars encoded in \\xNN notation.
-X, --e4x Pass E4X xml literals through untouched
-C, --comma-first Put commas at the beginning of new line instead of end.
-O, --operator-position=STRING Set operator position (before-newline, after-newline, preserve-newline)
-w, --wrap-line-length Attempt to wrap line when it exceeds this length.
NOTE: Line continues until next wrap point is found.
-n, --end-with-newline End output with newline
--indent-empty-lines Keep indentation on empty lines
--templating List of templating languages (auto,none,django,erb,handlebars,php) ["auto"] auto = none in JavaScript, all in html
--editorconfig Enable setting configuration from EditorConfig
Rarely needed options:
--eval-code evaluate code if a JS interpreter is
installed. May be useful with some obfuscated
script but poses a potential security issue.
-l, --indent-level=NUMBER Initial indentation level. (default 0).
-h, --help, --usage Prints this help statement.
-v, --version Show the version
""", file=stream)
if stream == sys.stderr:
return 1
else:
return 0
def mkdir_p(path):
try:
if path:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise Exception()
def isFileDifferent(filepath, expected):
try:
return (
''.join(
io.open(
filepath,
'rt',
newline='').readlines()) != expected)
except BaseException:
return True
def main():
argv = sys.argv[1:]
try:
opts, args = getopt.getopt(argv, "f:s:c:e:o:rdEPjab:kil:xhtvXnCO:w:m:",
['file=', 'indent-size=', 'indent-char=', 'eol=', 'outfile=', 'replace', 'disable-preserve-newlines',
'space-in-paren', 'space-in-empty-paren', 'jslint-happy', 'space-after-anon-function',
'brace-style=', 'indent-level=', 'unescape-strings',
'help', 'usage', 'stdin', 'eval-code', 'indent-with-tabs', 'keep-function-indentation', 'version',
'e4x', 'end-with-newline', 'comma-first', 'operator-position=', 'wrap-line-length', 'editorconfig', 'space-after-named-function',
'keep-array-indentation', 'indent-empty-lines', 'templating'])
except getopt.GetoptError as ex:
print(ex, file=sys.stderr)
return usage(sys.stderr)
js_options = default_options()
filepath_params = []
filepath_params.extend(args)
outfile_param = 'stdout'
replace = False
for opt, arg in opts:
if opt in ('--file', '-f'):
filepath_params.append(arg)
elif opt in ('--keep-array-indentation', '-k'):
js_options.keep_array_indentation = True
elif opt in ('--keep-function-indentation'):
js_options.keep_function_indentation = True
elif opt in ('--outfile', '-o'):
outfile_param = arg
elif opt in ('--replace', '-r'):
replace = True
elif opt in ('--indent-size', '-s'):
js_options.indent_size = int(arg)
elif opt in ('--indent-char', '-c'):
js_options.indent_char = arg
elif opt in ('--eol', '-e'):
js_options.eol = arg
elif opt in ('--indent-with-tabs', '-t'):
js_options.indent_with_tabs = True
elif opt in ('--disable-preserve-newlines', '-d'):
js_options.preserve_newlines = False
elif opt in ('--max-preserve-newlines', '-m'):
js_options.max_preserve_newlines = int(arg)
elif opt in ('--space-in-paren', '-P'):
js_options.space_in_paren = True
elif opt in ('--space-in-empty-paren', '-E'):
js_options.space_in_empty_paren = True
elif opt in ('--jslint-happy', '-j'):
js_options.jslint_happy = True
elif opt in ('--space-after-anon-function', '-a'):
js_options.space_after_anon_function = True
elif opt in ('--space-after-named-function'):
js_options.space_after_named_function = True
elif opt in ('--eval-code'):
js_options.eval_code = True
elif opt in ('--brace-style', '-b'):
js_options.brace_style = arg
elif opt in ('--unescape-strings', '-x'):
js_options.unescape_strings = True
elif opt in ('--e4x', '-X'):
js_options.e4x = True
elif opt in ('--end-with-newline', '-n'):
js_options.end_with_newline = True
elif opt in ('--comma-first', '-C'):
js_options.comma_first = True
elif opt in ('--operator-position', '-O'):
js_options.operator_position = arg
elif opt in ('--wrap-line-length ', '-w'):
js_options.wrap_line_length = int(arg)
elif opt in ('--indent-empty-lines'):
js_options.indent_empty_lines = True
elif opt in ('--templating'):
js_options.templating = arg.split(',')
elif opt in ('--stdin', '-i'):
# stdin is the default if no files are passed
filepath_params = []
elif opt in ('--editorconfig'):
js_options.editorconfig = True
elif opt in ('--version', '-v'):
return print(__version__)
elif opt in ('--help', '--usage', '-h'):
return usage()
try:
filepaths = []
if not filepath_params or (
len(filepath_params) == 1 and filepath_params[0] == '-'):
# default to stdin
filepath_params = []
filepaths.append('-')
for filepath_param in filepath_params:
# ignore stdin setting if files are specified
if '-' == filepath_param:
continue
# Check if each literal filepath exists
if os.path.isfile(filepath_param):
filepaths.append(filepath_param)
elif '*' in filepath_param or '?' in filepath_param:
# handle globs
# empty result is okay
if sys.version_info.major == 2 or (
sys.version_info.major == 3 and
sys.version_info.minor <= 4):
if '**' in filepath_param:
raise Exception('Recursive globs not supported on Python <= 3.4.')
filepaths.extend(glob.glob(filepath_param))
else:
filepaths.extend(glob.glob(filepath_param, recursive=True))
else:
# not a glob and not a file
raise OSError(errno.ENOENT, os.strerror(errno.ENOENT),
filepath_param)
if len(filepaths) > 1:
replace = True
elif filepaths and filepaths[0] == '-':
replace = False
# remove duplicates
filepaths = set(filepaths)
for filepath in filepaths:
if not replace:
outfile = outfile_param
else:
outfile = filepath
# Editorconfig used only on files, not stdin
if getattr(js_options, 'editorconfig'):
editorconfig_filepath = filepath
if editorconfig_filepath == '-':
if outfile != 'stdout':
editorconfig_filepath = outfile
else:
fileType = 'js'
editorconfig_filepath = 'stdin.' + fileType
# debug("EditorConfig is enabled for ", editorconfig_filepath);
js_options = copy.copy(js_options)
set_file_editorconfig_opts(editorconfig_filepath, js_options)
pretty = beautify_file(filepath, js_options)
if outfile == 'stdout':
stream = sys.stdout
# python automatically converts newlines in text to "\r\n" when on windows
# switch to binary to prevent this
if platform.platform().lower().startswith('windows'):
if sys.version_info.major >= 3:
# for python 3 on windows this prevents conversion
stream = io.TextIOWrapper(sys.stdout.buffer, newline='')
elif platform.architecture()[0] == '32bit':
# for python 2 x86 on windows this prevents conversion
import msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
else:
raise Exception('Pipe to stdout not supported on Windows with Python 2.x 64-bit.')
stream.write(pretty)
else:
if isFileDifferent(outfile, pretty):
mkdir_p(os.path.dirname(outfile))
# python automatically converts newlines in text to "\r\n" when on windows
# set newline to empty to prevent this
with io.open(outfile, 'wt', newline='', encoding='UTF-8') as f:
print('beautified ' + outfile, file=sys.stdout)
try:
f.write(pretty)
except TypeError:
# This is not pretty, but given how we did the version import
# it is the only way to do this without having setup.py
# fail on a missing six dependency.
six = __import__("six")
f.write(six.u(pretty))
else:
print('beautified ' + outfile + ' - unchanged', file=sys.stdout)
except MissingInputStreamError:
print(
"Must pipe input or define at least one file.\n",
file=sys.stderr)
usage(sys.stderr)
return 1
except UnicodeError as ex:
print("Error while decoding input or encoding output:",
file=sys.stderr)
print(ex, file=sys.stderr)
return 1
except Exception as ex:
print(ex, file=sys.stderr)
return 1
# Success
return 0
if __name__ == "__main__":
main()
jsbeautifier-1.10.3/jsbeautifier/__version__.py 0000644 0000765 0000024 00000000027 13607407716 023056 0 ustar bitwiseman staff 0000000 0000000 __version__ = '1.10.3'
jsbeautifier-1.10.3/jsbeautifier/core/ 0000755 0000765 0000024 00000000000 13607410064 021142 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/jsbeautifier/core/__init__.py 0000644 0000765 0000024 00000000020 13476247317 023260 0 ustar bitwiseman staff 0000000 0000000 # Empty file :)
jsbeautifier-1.10.3/jsbeautifier/core/directives.py 0000644 0000765 0000024 00000004133 13476247317 023673 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
class Directives:
def __init__(self, start_block_pattern, end_block_pattern):
self.__directives_block_pattern = re.compile(start_block_pattern + r' beautify( \w+[:]\w+)+ ' + end_block_pattern)
self.__directive_pattern = re.compile(r' (\w+)[:](\w+)')
self.__directives_end_ignore_pattern = re.compile(start_block_pattern + r'\sbeautify\signore:end\s' + end_block_pattern)
def get_directives(self, text):
if not self.__directives_block_pattern.match(text):
return None
directives = {}
directive_match = self.__directive_pattern.search(text)
while directive_match:
directives[directive_match.group(1)] = directive_match.group(2)
directive_match = self.__directive_pattern.search(
text, directive_match.end())
return directives
def readIgnored(self, input):
return input.readUntilAfter(self.__directives_end_ignore_pattern)
jsbeautifier-1.10.3/jsbeautifier/core/inputscanner.py 0000644 0000765 0000024 00000010770 13476247317 024247 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
class InputScanner:
def __init__(self, input_string):
self.__six = __import__("six")
if input_string is None:
input_string = ''
self.__input = input_string
self.__input_length = len(self.__input)
self.__position = 0
def restart(self):
self.__position = 0
def back(self):
if self.__position > 0:
self.__position -= 1
def hasNext(self):
return self.__position < self.__input_length
def next(self):
val = None
if self.hasNext():
val = self.__input[self.__position]
self.__position += 1
return val
def peek(self, index=0):
val = None
index += self.__position
if index >= 0 and index < self.__input_length:
val = self.__input[index]
return val
def test(self, pattern, index=0):
index += self.__position
return index >= 0 and index < self.__input_length and bool(
pattern.match(self.__input, index))
def testChar(self, pattern, index=0):
# test one character regex match
val = self.peek(index)
return val is not None and bool(pattern.match(val))
def match(self, pattern):
pattern_match = None
if self.hasNext():
pattern_match = pattern.match(self.__input, self.__position)
if bool(pattern_match):
self.__position = pattern_match.end(0)
return pattern_match
def read(self, starting_pattern, until_pattern=None, until_after=False):
val = ''
pattern_match = None
if bool(starting_pattern):
pattern_match = self.match(starting_pattern)
if bool(pattern_match):
val = pattern_match.group(0)
if bool(until_pattern) and \
(bool(pattern_match) or not bool(starting_pattern)):
val += self.readUntil(until_pattern, until_after)
return val
def readUntil(self, pattern, include_match=False):
val = ''
pattern_match = None
match_index = self.__position
if self.hasNext():
pattern_match = pattern.search(self.__input, self.__position)
if bool(pattern_match):
if include_match:
match_index = pattern_match.end(0)
else:
match_index = pattern_match.start(0)
else:
match_index = self.__input_length
val = self.__input[self.__position:match_index]
self.__position = match_index
return val
def readUntilAfter(self, pattern):
return self.readUntil(pattern, True)
def get_regexp(self, pattern, match_from=False):
result = None
# strings are converted to regexp
if isinstance(pattern, self.__six.string_types) and pattern != '':
result = re.compile(pattern)
elif pattern is not None:
result = re.compile(pattern.pattern)
return result
# css beautifier legacy helpers
def peekUntilAfter(self, pattern):
start = self.__position
val = self.readUntilAfter(pattern)
self.__position = start
return val
def lookBack(self, testVal):
start = self.__position - 1
return start >= len(testVal) and \
self.__input[start - len(testVal):start].lower() == testVal
jsbeautifier-1.10.3/jsbeautifier/core/options.py 0000644 0000765 0000024 00000017232 13476247317 023231 0 ustar bitwiseman staff 0000000 0000000 # 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.
import copy
import re
from collections import namedtuple
class Options:
def __init__(self, options=None, merge_child_field=None):
self.css = None
self.js = None
self.html = None
self.raw_options = _mergeOpts(options, merge_child_field)
# 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.indent_level = self._get_number('indent_level')
self.preserve_newlines = self._get_boolean('preserve_newlines', True)
self.max_preserve_newlines = self._get_number(
'max_preserve_newlines', 32786)
if not self.preserve_newlines:
self.max_preserve_newlines = 0
self.indent_with_tabs = self._get_boolean(
'indent_with_tabs', self.indent_char == '\t')
if self.indent_with_tabs:
self.indent_char = '\t'
# indent_size behavior changed after 1.8.6
# It used to be that indent_size would be
# set to 1 for indent_with_tabs. That is no longer needed and
# actually doesn't make sense - why not use spaces? Further,
# that might produce unexpected behavior - tabs being used
# for single-column alignment. So, when indent_with_tabs is true
# and indent_size is 1, reset indent_size to 4.
if self.indent_size == 1:
self.indent_size = 4
# Backwards compat with 1.3.x
self.wrap_line_length = self._get_number(
'wrap_line_length', self._get_number('max_char'))
self.indent_empty_lines = self._get_boolean('indent_empty_lines')
# valid templating languages ['django', 'erb', 'handlebars', 'php']
# For now, 'auto' = all off for javascript, all on for html (and inline javascript).
# other values ignored
self.templating = self._get_selection_list('templating',
['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto'])
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):
result = self._get_selection_list(name, selection_list, default_value)
if len(result) != 1:
raise ValueError(
"Invalid Option Value: The option '" + name + "' can only be one of the following values:\n" +
str(selection_list) +
"\nYou passed in: '" +
str(getattr(self.raw_options, name, None)) +
"'")
return result[0]
def _get_selection_list(self, name, selection_list, default_value=None):
if not selection_list:
raise ValueError("Selection list cannot be empty.")
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)
if not self._is_valid_selection(result, selection_list):
raise ValueError(
"Invalid Option Value: The option '" + name + "' can contain only 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}}
# mergeOpts(obj, 'b')
#
# Returns: {a: 2}
def _mergeOpts(options, childFieldName):
if options is None:
options = {}
if isinstance(options, tuple):
options = dict(options)
options = _normalizeOpts(options)
finalOpts = copy.copy(options)
if isinstance(options, dict):
local = finalOpts.get(childFieldName, None)
if local:
del(finalOpts[childFieldName])
for key in local:
finalOpts[key] = local[key]
finalOpts = namedtuple("CustomOptions", finalOpts.keys())(
*finalOpts.values())
if isinstance(options, Options):
local = getattr(finalOpts, childFieldName, None)
if local:
delattr(finalOpts, childFieldName)
for key in local:
setattr(finalOpts, key, local[key])
return finalOpts
def _normalizeOpts(options):
convertedOpts = copy.copy(options)
if isinstance(convertedOpts, dict):
option_keys = list(convertedOpts.keys())
for key in option_keys:
if '-' in key:
del convertedOpts[key]
convertedOpts[key.replace('-', '_')] = options[key]
else:
option_keys = list(getattr(convertedOpts, '__dict__', {}))
for key in option_keys:
if '-' in key:
delattr(convertedOpts, key)
setattr(convertedOpts, key.replace(
'-', '_'), getattr(options, key, None))
return convertedOpts
jsbeautifier-1.10.3/jsbeautifier/core/output.py 0000644 0000765 0000024 00000027423 13476247317 023101 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
import math
# Using object instead of string to allow for later expansion of info
# about each line
__all__ = ["Output"]
class OutputLine:
def __init__(self, parent):
self.__parent = parent
self.__character_count = 0
self.__indent_count = -1
self.__alignment_count = 0
self.__wrap_point_index = 0
self.__wrap_point_character_count = 0
self.__wrap_point_indent_count = -1
self.__wrap_point_alignment_count = 0
self.__items = []
def clone_empty(self):
line = OutputLine(self.__parent)
line.set_indent(self.__indent_count, self.__alignment_count)
return line
def item(self, index):
return self.__items[index]
def is_empty(self):
return len(self.__items) == 0
def set_indent(self, indent=0, alignment=0):
if self.is_empty():
self.__indent_count = indent
self.__alignment_count = alignment
self.__character_count = self.__parent.get_indent_size(
self.__indent_count, self.__alignment_count)
def _set_wrap_point(self):
if self.__parent.wrap_line_length:
self.__wrap_point_index = len(self.__items)
self.__wrap_point_character_count = self.__character_count
self.__wrap_point_indent_count = \
self.__parent.next_line.__indent_count
self.__wrap_point_alignment_count = \
self.__parent.next_line.__alignment_count
def _should_wrap(self):
return self.__wrap_point_index and \
self.__character_count > \
self.__parent.wrap_line_length and \
self.__wrap_point_character_count > \
self.__parent.next_line.__character_count
def _allow_wrap(self):
if self._should_wrap():
self.__parent.add_new_line()
next = self.__parent.current_line
next.set_indent(self.__wrap_point_indent_count,
self.__wrap_point_alignment_count)
next.__items = self.__items[self.__wrap_point_index:]
self.__items = self.__items[:self.__wrap_point_index]
next.__character_count += self.__character_count - \
self.__wrap_point_character_count
self.__character_count = self.__wrap_point_character_count
if next.__items[0] == " ":
next.__items.pop(0)
next.__character_count -= 1
return True
return False
def last(self):
if not self.is_empty():
return self.__items[-1]
return None
def push(self, item):
self.__items.append(item)
last_newline_index = item.rfind('\n')
if last_newline_index != -1:
self.__character_count = len(item) - last_newline_index
else:
self.__character_count += len(item)
def pop(self):
item = None
if not self.is_empty():
item = self.__items.pop()
self.__character_count -= len(item)
return item
def _remove_indent(self):
if self.__indent_count > 0:
self.__indent_count -= 1
self.__character_count -= self.__parent.indent_size
def _remove_wrap_indent(self):
if self.__wrap_point_indent_count > 0:
self.__wrap_point_indent_count -= 1
def trim(self):
while self.last() == ' ':
self.__items.pop()
self.__character_count -= 1
def toString(self):
result = ''
if self.is_empty():
if self.__parent.indent_empty_lines:
result = self.__parent.get_indent_string(self.__indent_count)
else:
result = self.__parent.get_indent_string(
self.__indent_count, self.__alignment_count)
result += ''.join(self.__items)
return result
class IndentStringCache:
def __init__(self, options, base_string):
self.__cache = ['']
self.__indent_size = options.indent_size
self.__indent_string = options.indent_char
if not options.indent_with_tabs:
self.__indent_string = options.indent_char * options.indent_size
# Set to null to continue support of auto detection of base indent
base_string = base_string or ''
if options.indent_level > 0:
base_string = options.indent_level * self.__indent_string
self.__base_string = base_string
self.__base_string_length = len(base_string)
def get_indent_size(self, indent, column=0):
result = self.__base_string_length
if indent < 0:
result = 0
result += indent * self.__indent_size
result += column
return result
def get_indent_string(self, indent_level, column=0):
result = self.__base_string
if indent_level < 0:
indent_level = 0
result = ''
column += indent_level * self.__indent_size
self.__ensure_cache(column)
result += self.__cache[column]
return result
def __ensure_cache(self, column):
while column >= len(self.__cache):
self.__add_column()
def __add_column(self):
column = len(self.__cache)
indent = 0
result = ''
if self.__indent_size and column >= self.__indent_size:
indent = int(math.floor(column / self.__indent_size))
column -= indent * self.__indent_size
result = indent * self.__indent_string
if column:
result += column * ' '
self.__cache.append(result)
class Output:
def __init__(self, options, baseIndentString=''):
self.__indent_cache = IndentStringCache(options, baseIndentString)
self.raw = False
self._end_with_newline = options.end_with_newline
self.indent_size = options.indent_size
self.wrap_line_length = options.wrap_line_length
self.indent_empty_lines = options.indent_empty_lines
self.__lines = []
self.previous_line = None
self.current_line = None
self.next_line = OutputLine(self)
self.space_before_token = False
self.non_breaking_space = False
self.previous_token_wrapped = False
# initialize
self.__add_outputline()
def __add_outputline(self):
self.previous_line = self.current_line
self.current_line = self.next_line.clone_empty()
self.__lines.append(self.current_line)
def get_line_number(self):
return len(self.__lines)
def get_indent_string(self, indent, column=0):
return self.__indent_cache.get_indent_string(indent, column)
def get_indent_size(self, indent, column=0):
return self.__indent_cache.get_indent_size(indent, column)
def is_empty(self):
return self.previous_line is None and self.current_line.is_empty()
def add_new_line(self, force_newline=False):
# never newline at the start of file
# otherwise, newline only if we didn't just add one or we're forced
if self.is_empty() or \
(not force_newline and self.just_added_newline()):
return False
# if raw output is enabled, don't print additional newlines,
# but still return True as though you had
if not self.raw:
self.__add_outputline()
return True
def get_code(self, eol):
self.trim(True)
# handle some edge cases where the last tokens
# has text that ends with newline(s)
last_item = self.current_line.pop()
if last_item:
if last_item[-1] == '\n':
last_item = re.sub(r'[\n]+$', '', last_item)
self.current_line.push(last_item)
if self._end_with_newline:
self.__add_outputline()
sweet_code = "\n".join(line.toString() for line in self.__lines)
if not eol == '\n':
sweet_code = sweet_code.replace('\n', eol)
return sweet_code
def set_wrap_point(self):
self.current_line._set_wrap_point()
def set_indent(self, indent=0, alignment=0):
# Next line stores alignment values
self.next_line.set_indent(indent, alignment)
# Never indent your first output indent at the start of the file
if len(self.__lines) > 1:
self.current_line.set_indent(indent, alignment)
return True
self.current_line.set_indent()
return False
def add_raw_token(self, token):
for _ in range(token.newlines):
self.__add_outputline()
self.current_line.set_indent(-1)
self.current_line.push(token.whitespace_before)
self.current_line.push(token.text)
self.space_before_token = False
self.non_breaking_space = False
self.previous_token_wrapped = False
def add_token(self, printable_token):
self.__add_space_before_token()
self.current_line.push(printable_token)
self.space_before_token = False
self.non_breaking_space = False
self.previous_token_wrapped = self.current_line._allow_wrap()
def __add_space_before_token(self):
if self.space_before_token and not self.just_added_newline():
if not self.non_breaking_space:
self.set_wrap_point()
self.current_line.push(' ')
self.space_before_token = False
def remove_indent(self, index):
while index < len(self.__lines):
self.__lines[index]._remove_indent()
index += 1
self.current_line._remove_wrap_indent()
def trim(self, eat_newlines=False):
self.current_line.trim()
while eat_newlines and len(
self.__lines) > 1 and self.current_line.is_empty():
self.__lines.pop()
self.current_line = self.__lines[-1]
self.current_line.trim()
if len(self.__lines) > 1:
self.previous_line = self.__lines[-2]
else:
self.previous_line = None
def just_added_newline(self):
return self.current_line.is_empty()
def just_added_blankline(self):
return self.is_empty() or \
(self.current_line.is_empty() and self.previous_line.is_empty())
def ensure_empty_line_above(self, starts_with, ends_with):
index = len(self.__lines) - 2
while index >= 0:
potentialEmptyLine = self.__lines[index]
if potentialEmptyLine.is_empty():
break
elif not potentialEmptyLine.item(0).startswith(starts_with) and \
potentialEmptyLine.item(-1) != ends_with:
self.__lines.insert(index + 1, OutputLine(self))
self.previous_line = self.__lines[-2]
break
index -= 1
jsbeautifier-1.10.3/jsbeautifier/core/pattern.py 0000644 0000765 0000024 00000005674 13476247317 023222 0 ustar bitwiseman staff 0000000 0000000 # 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.
__all__ = ["Pattern"]
class Pattern:
def __init__(self, input_scanner, parent=None):
self._input = input_scanner
self._starting_pattern = None
self._match_pattern = None
self._until_pattern = None
self._until_after = False
if parent is not None:
self._starting_pattern = self._input.get_regexp(parent._starting_pattern)
self._match_pattern = self._input.get_regexp(parent._match_pattern)
self._until_pattern = self._input.get_regexp(parent._until_pattern)
self._until_after = parent._until_after
def read(self):
result = self._input.read(self._starting_pattern)
if (self._starting_pattern is None) or result:
result += self._input.read(self._match_pattern,
self._until_pattern, self._until_after)
return result
def read_match(self):
return self._input.match(self._match_pattern)
def until_after(self, pattern):
result = self._create()
result._until_after = True
result._until_pattern = self._input.get_regexp(pattern)
result._update()
return result
def until(self, pattern):
result = self._create()
result._until_after = False
result._until_pattern = self._input.get_regexp(pattern)
result._update()
return result
def starting_with(self, pattern):
result = self._create()
result._starting_pattern = self._input.get_regexp(pattern)
result._update()
return result
def matching(self, pattern):
result = self._create()
result._match_pattern = self._input.get_regexp(pattern)
result._update()
return result
def _create(self):
return Pattern(self._input, self)
def _update(self):
pass
jsbeautifier-1.10.3/jsbeautifier/core/templatablepattern.py 0000644 0000765 0000024 00000015247 13522341427 025417 0 ustar bitwiseman staff 0000000 0000000 # 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.
import copy
from ..core.pattern import Pattern
__all__ = ["TemplatablePattern"]
class TemplateNames:
def __init__(self):
self.django = False
self.erb = False
self.handlebars = False
self.php = False
class TemplatePatterns:
def __init__(self, input_scanner):
pattern = Pattern(input_scanner)
self.handlebars_comment = pattern.starting_with(r'{{!--').until_after(r'--}}')
self.handlebars_unescaped = pattern.starting_with(r'{{{').until_after(r'}}}')
self.handlebars = pattern.starting_with(r'{{').until_after(r'}}')
self.php = pattern.starting_with(r'<\?(?:[=]|php)').until_after(r'\?>')
self.erb = pattern.starting_with(r'<%[^%]').until_after(r'[^%]%>')
# django coflicts with handlebars a bit.
self.django = pattern.starting_with(r'{%').until_after(r'%}')
self.django_value = pattern.starting_with(r'{{').until_after(r'}}')
self.django_comment = pattern.starting_with(r'{#').until_after(r'#}')
class TemplatablePattern(Pattern):
def __init__(self, input_scanner, parent=None):
Pattern.__init__(self, input_scanner, parent)
self.__template_pattern = None
self._disabled = TemplateNames()
self._excluded = TemplateNames()
if parent is not None:
self.__template_pattern = \
self._input.get_regexp(parent.__template_pattern)
self._disabled = copy.copy(parent._disabled)
self._excluded = copy.copy(parent._excluded)
self.__patterns = TemplatePatterns(input_scanner)
def _create(self):
return TemplatablePattern(self._input, self)
def _update(self):
self.__set_templated_pattern()
def read_options(self, options):
result = self._create()
for language in ['django', 'erb', 'handlebars', 'php']:
setattr(result._disabled, language,
not (language in options.templating))
result._update()
return result
def disable(self, language):
result = self._create()
setattr(result._disabled, language, True)
result._update()
return result
def exclude(self, language):
result = self._create()
setattr(result._excluded, language, True)
result._update()
return result
def read(self):
result = ''
if bool(self._match_pattern):
result = self._input.read(self._starting_pattern)
else:
result = self._input.read(self._starting_pattern,
self.__template_pattern)
next = self._read_template()
while (bool(next)):
if self._match_pattern is not None:
next += self._input.read(self._match_pattern)
else:
next += self._input.readUntil(self.__template_pattern)
result += next
next = self._read_template()
if self._until_after:
result += self._input.readUntilAfter(self._until_after)
return result
def __set_templated_pattern(self):
items = list()
if not self._disabled.php:
items.append(self.__patterns.php._starting_pattern.pattern)
if not self._disabled.handlebars:
items.append(self.__patterns.handlebars._starting_pattern.pattern)
if not self._disabled.erb:
items.append(self.__patterns.erb._starting_pattern.pattern)
if not self._disabled.django:
items.append(self.__patterns.django._starting_pattern.pattern)
items.append(self.__patterns.django_value._starting_pattern.pattern)
items.append(self.__patterns.django_comment._starting_pattern.pattern)
if self._until_pattern:
items.append(self._until_pattern.pattern)
self.__template_pattern = self._input.get_regexp(
r'(?:' + '|'.join(items) + ')')
def _read_template(self):
resulting_string = ''
c = self._input.peek()
if c == '<':
peek1 = self._input.peek(1)
if not self._disabled.php and \
not self._excluded.php and \
peek1 == '?':
resulting_string = resulting_string or \
self.__patterns.php.read()
if not self._disabled.erb and \
not self._excluded.erb and \
peek1 == '%':
resulting_string = resulting_string or \
self.__patterns.erb.read()
elif c == '{':
if not self._disabled.handlebars and \
not self._excluded.handlebars:
resulting_string = resulting_string or \
self.__patterns.handlebars_comment.read()
resulting_string = resulting_string or \
self.__patterns.handlebars_unescaped.read()
resulting_string = resulting_string or \
self.__patterns.handlebars.read()
if not self._disabled.django:
# django coflicts with handlebars a bit.
if not self._excluded.django and \
not self._excluded.handlebars:
resulting_string = resulting_string or \
self.__patterns.django_value.read()
if not self._excluded.django:
resulting_string = resulting_string or \
self.__patterns.django_comment.read()
resulting_string = resulting_string or \
self.__patterns.django.read()
return resulting_string
jsbeautifier-1.10.3/jsbeautifier/core/token.py 0000644 0000765 0000024 00000003153 13476247317 022653 0 ustar bitwiseman staff 0000000 0000000 # 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.
class Token:
def __init__(
self,
type,
text,
newlines=0,
whitespace_before=''):
self.type = type
self.text = text
self.comments_before = None
self.newlines = newlines
self.whitespace_before = whitespace_before
self.parent = None
self.next = None
self.previous = None
self.opened = None
self.closed = None
self.directives = None
jsbeautifier-1.10.3/jsbeautifier/core/tokenizer.py 0000644 0000765 0000024 00000010436 13476247317 023547 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
from ..core.inputscanner import InputScanner
from ..core.token import Token
from ..core.tokenstream import TokenStream
from ..core.pattern import Pattern
from ..core.whitespacepattern import WhitespacePattern
__all__ = ["TOKEN", "Tokenizer", "TokenizerPatterns", "TokenTypes"]
class TokenTypes:
START = 'TK_START'
RAW = 'TK_RAW'
EOF = 'TK_EOF'
def __init__(self):
pass
TOKEN = TokenTypes()
class TokenizerPatterns:
def __init__(self, input_scanner):
self.whitespace = WhitespacePattern(input_scanner)
class Tokenizer:
def __init__(self, input_string, options):
self._input = InputScanner(input_string)
self._options = options
self.__tokens = None
self._patterns = TokenizerPatterns(self._input)
def tokenize(self):
self._input.restart()
self.__tokens = TokenStream()
current = None
previous = Token(TOKEN.START,'')
open_token = None
open_stack = []
comments = TokenStream()
while previous.type != TOKEN.EOF:
current = self.__get_next_token_with_comments(previous, open_token)
if self._is_opening(current):
open_stack.append(open_token)
open_token = current
elif open_token is not None and \
self._is_closing(current, open_token):
current.opened = open_token
open_token.closed = current
open_token = open_stack.pop()
current.parent = open_token
self.__tokens.add(current)
previous = current
return self.__tokens
def __get_next_token_with_comments(self, previous, open_token):
current = self._get_next_token(previous, open_token)
if self._is_comment(current):
comments = TokenStream()
while self._is_comment(current):
comments.add(current)
current = self._get_next_token(previous, open_token)
if not comments.isEmpty():
current.comments_before = comments
comments = TokenStream()
current.parent = open_token
current.previous = previous
previous.next = current
return current
def _is_first_token(self):
return self.__tokens.isEmpty()
def _reset(self):
pass
def _get_next_token(self, previous_token, open_token):
self._readWhitespace()
resulting_string = self._input.read(re.compile(r'.+'))
if resulting_string:
return self._create_token(TOKEN.RAW, resulting_string)
else:
return self._create_token(TOKEN.EOF, '')
def _is_comment(self, current_token):
return False
def _is_opening(self, current_token):
return False
def _is_closing(self, current_token, open_token):
return False
def _create_token(self, token_type, text):
token = Token(token_type, text,
self._patterns.whitespace.newline_count,
self._patterns.whitespace.whitespace_before_token)
return token
def _readWhitespace(self):
return self._patterns.whitespace.read()
jsbeautifier-1.10.3/jsbeautifier/core/tokenstream.py 0000644 0000765 0000024 00000004454 13476247317 024074 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
from ..core.inputscanner import InputScanner
from ..core.token import Token
class TokenStream:
def __init__(self, parent_token=None):
self.__tokens = []
self.__tokens_length = len(self.__tokens)
self.__position = 0
self.__parent_token = parent_token
def restart(self):
self.__position = 0
def isEmpty(self):
return self.__tokens_length == 0
def hasNext(self):
return self.__position < self.__tokens_length
def next(self):
if self.hasNext():
val = self.__tokens[self.__position]
self.__position += 1
return val
else:
raise StopIteration
def peek(self, index=0):
val = None
index += self.__position
if index >= 0 and index < self.__tokens_length:
val = self.__tokens[index]
return val
def add(self, token):
if self.__parent_token:
token.parent = self.__parent_token
self.__tokens.append(token)
self.__tokens_length += 1
def __iter__(self):
self.restart()
return self
def __next__(self):
return self.next()
jsbeautifier-1.10.3/jsbeautifier/core/whitespacepattern.py 0000644 0000765 0000024 00000005336 13476247317 025272 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
from ..core.pattern import Pattern
__all__ = ["WhitespacePattern"]
class WhitespacePattern(Pattern):
def __init__(self, input_scanner, parent=None):
Pattern.__init__(self, input_scanner, parent)
if parent is not None:
self._newline_regexp = \
self._input.get_regexp(parent._newline_regexp)
else:
self.__set_whitespace_patterns('', '')
self.newline_count = 0
self.whitespace_before_token = ''
def __set_whitespace_patterns(self, whitespace_chars, newline_chars):
whitespace_chars += '\\t '
newline_chars += '\\n\\r'
self._match_pattern = self._input.get_regexp(
'[' + whitespace_chars + newline_chars + ']+')
self._newline_regexp = self._input.get_regexp(
'\\r\\n|[' + newline_chars + ']')
def read(self):
self.newline_count = 0
self.whitespace_before_token = ''
resulting_string = self._input.read(self._match_pattern)
if resulting_string == ' ':
self.whitespace_before_token = ' '
elif bool(resulting_string):
lines = self._newline_regexp.split(resulting_string)
self.newline_count = len(lines) - 1
self.whitespace_before_token = lines[-1]
return resulting_string
def matching(self, whitespace_chars, newline_chars):
result = self._create()
result.__set_whitespace_patterns(whitespace_chars, newline_chars)
result._update()
return result
def _create(self):
return WhitespacePattern(self._input, self)
jsbeautifier-1.10.3/jsbeautifier/javascript/ 0000755 0000765 0000024 00000000000 13607410064 022360 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/jsbeautifier/javascript/__init__.py 0000644 0000765 0000024 00000000020 13476247317 024476 0 ustar bitwiseman staff 0000000 0000000 # Empty file :)
jsbeautifier-1.10.3/jsbeautifier/javascript/acorn.py 0000644 0000765 0000024 00000022121 13607407716 024044 0 ustar bitwiseman staff 0000000 0000000 import re
# This section of code was translated to python from acorn (javascript).
#
# Acorn was written by Marijn Haverbeke and released under an MIT
# license. The Unicode regexps (for identifiers and whitespace) were
# taken from [Esprima](http://esprima.org) by Ariya Hidayat.
#
# Git repositories for Acorn are available at
#
# http://marijnhaverbeke.nl/git/acorn
# https://github.com/marijnh/acorn.git
# This is not pretty, but given how we did the version import
# it is the only way to do this without having setup.py fail on a missing
# six dependency.
six = __import__("six")
# ## Character categories
# acorn used char codes to squeeze the last bit of performance out
# Beautifier is okay without that, so we're using regex
# permit #(23), $ (36), and @ (64). @ is used in ES7 decorators.
# 65 through 91 are uppercase letters.
# permit _ (95).
# 97 through 123 are lowercase letters.
_baseASCIIidentifierStartChars = six.u(r"\x23\x24\x40\x41-\x5a\x5f\x61-\x7a")
# inside an identifier @ is not allowed but 0-9 are.
_baseASCIIidentifierChars = six.u(r"\x24\x30-\x39\x41-\x5a\x5f\x61-\x7a")
# Big ugly regular expressions that match characters in the
# whitespace, identifier, and identifier-start categories. These
# are only applied when a character is found to actually have a
# code point above 128.
# IMPORTANT: These strings must be run through six to handle \u chars
_nonASCIIidentifierStartChars = six.u(r"\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc")
_nonASCIIidentifierChars = six.u(r"\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f")
#_nonASCIIidentifierStart = re.compile("[" + _nonASCIIidentifierStartChars + "]")
#_nonASCIIidentifier = re.compile("[" + _nonASCIIidentifierStartChars + _nonASCIIidentifierChars + "]")
_identifierStart = six.u(r"(?:\\u[0-9a-fA-F]{4}|[") + \
_baseASCIIidentifierStartChars + \
_nonASCIIidentifierStartChars + \
six.u("])")
_identifierChars = six.u(r"(?:\\u[0-9a-fA-F]{4}|[") + \
_baseASCIIidentifierChars + \
_nonASCIIidentifierStartChars + \
_nonASCIIidentifierChars + \
six.u("])*")
identifier = re.compile(_identifierStart + _identifierChars)
identifierStart = re.compile(_identifierStart)
identifierMatch = re.compile(six.u(r"(?:\\u[0-9a-fA-F]{4}|[") + \
_baseASCIIidentifierChars + \
_nonASCIIidentifierStartChars + \
_nonASCIIidentifierChars + \
six.u("])+"))
_nonASCIIwhitespace = re.compile(
six.u(r"[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]"))
# Whether a single character denotes a newline.
# IMPORTANT: This string must be run through six to handle \u chars
newline = re.compile(six.u(r"[\n\r\u2028\u2029]"))
# Matches a whole line break (where CRLF is considered a single
# line break). Used to count lines.
# in javascript, these two differ
# in python they are the same, different methods are called on them
# IMPORTANT: This string must be run through six to handle \u chars
lineBreak = re.compile(six.u(r"\r\n|[\n\r\u2028\u2029]"))
allLineBreaks = lineBreak jsbeautifier-1.10.3/jsbeautifier/javascript/beautifier.py 0000644 0000765 0000024 00000163744 13476247317 025105 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
import string
import copy
from ..core.token import Token
from .tokenizer import Tokenizer
from .tokenizer import TOKEN
from .options import BeautifierOptions
from ..core.output import Output
def default_options():
return BeautifierOptions()
class BeautifierFlags:
def __init__(self, mode):
self.mode = mode
self.parent = None
self.last_token = Token(TOKEN.START_BLOCK, '')
self.last_word = ''
self.declaration_statement = False
self.declaration_assignment = False
self.multiline_frame = False
self.inline_frame = False
self.if_block = False
self.else_block = False
self.do_block = False
self.do_while = False
self.import_block = False
self.in_case = False
self.in_case_statement = False
self.case_body = False
self.indentation_level = 0
self.alignment = 0
self.line_indent_level = 0
self.start_line_index = 0
self.ternary_depth = 0
def apply_base(self, flags_base, added_newline):
next_indent_level = flags_base.indentation_level
if not added_newline and \
flags_base.line_indent_level > next_indent_level:
next_indent_level = flags_base.line_indent_level
self.parent = flags_base
self.last_token = flags_base.last_token
self.last_word = flags_base.last_word
self.indentation_level = next_indent_level
OPERATOR_POSITION = {
'before_newline': 'before-newline',
'after_newline': 'after-newline',
'preserve_newline': 'preserve-newline'
}
OPERATOR_POSITION_BEFORE_OR_PRESERVE = [
OPERATOR_POSITION['before_newline'],
OPERATOR_POSITION['preserve_newline']]
class MODE:
BlockStatement, Statement, ObjectLiteral, ArrayLiteral, \
ForInitializer, Conditional, Expression = range(7)
def remove_redundant_indentation(output, frame):
# This implementation is effective but has some issues:
# - can cause line wrap to happen too soon due to indent removal
# after wrap points are calculated
# These issues are minor compared to ugly indentation.
if frame.multiline_frame or \
frame.mode == MODE.ForInitializer or \
frame.mode == MODE.Conditional:
return
# remove one indent from each line inside this section
output.remove_indent(frame.start_line_index)
def reserved_word(token, word):
return token and token.type == TOKEN.RESERVED and token.text == word
def reserved_array(token, words):
return token and token.type == TOKEN.RESERVED and token.text in words
_special_word_set = frozenset([
'case',
'return',
'do',
'if',
'throw',
'else',
'await',
'break',
'continue',
'async'])
class Beautifier:
def __init__(self, opts=None):
import jsbeautifier.javascript.acorn as acorn
self.acorn = acorn
self._options = BeautifierOptions(opts)
self._blank_state()
def _blank_state(self, js_source_text=None):
if js_source_text is None:
js_source_text = ''
# internal flags
self._flags = None
self._previous_flags = None
self._flag_store = []
self._tokens = None
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()
baseIndentString = re.search("^[\t ]*", js_source_text).group(0)
self._last_last_text = '' # pre-last token text
self._output = Output(self._options, baseIndentString)
# If testing the ignore directive, start with output disable set to
# true
self._output.raw = self._options.test_output_raw
self.set_mode(MODE.BlockStatement)
return js_source_text
def beautify(self, source_text='', opts=None):
if opts is not None:
self._options = BeautifierOptions(opts)
source_text = source_text or ''
if self._options.disabled:
return source_text
source_text = self._blank_state(source_text)
source_text = self.unpack(source_text, self._options.eval_code)
self._tokens = Tokenizer(source_text, self._options).tokenize()
for current_token in self._tokens:
self.handle_token(current_token)
self._last_last_text = self._flags.last_token.text
self._flags.last_token = current_token
sweet_code = self._output.get_code(self._options.eol)
return sweet_code
def handle_token(self, current_token, preserve_statement_flags=False):
if current_token.type == TOKEN.START_EXPR:
self.handle_start_expr(current_token)
elif current_token.type == TOKEN.END_EXPR:
self.handle_end_expr(current_token)
elif current_token.type == TOKEN.START_BLOCK:
self.handle_start_block(current_token)
elif current_token.type == TOKEN.END_BLOCK:
self.handle_end_block(current_token)
elif current_token.type == TOKEN.WORD:
self.handle_word(current_token)
elif current_token.type == TOKEN.RESERVED:
self.handle_word(current_token)
elif current_token.type == TOKEN.SEMICOLON:
self.handle_semicolon(current_token)
elif current_token.type == TOKEN.STRING:
self.handle_string(current_token)
elif current_token.type == TOKEN.EQUALS:
self.handle_equals(current_token)
elif current_token.type == TOKEN.OPERATOR:
self.handle_operator(current_token)
elif current_token.type == TOKEN.COMMA:
self.handle_comma(current_token)
elif current_token.type == TOKEN.BLOCK_COMMENT:
self.handle_block_comment(current_token, preserve_statement_flags)
elif current_token.type == TOKEN.COMMENT:
self.handle_comment(current_token, preserve_statement_flags)
elif current_token.type == TOKEN.DOT:
self.handle_dot(current_token)
elif current_token.type == TOKEN.EOF:
self.handle_eof(current_token)
elif current_token.type == TOKEN.UNKNOWN:
self.handle_unknown(current_token, preserve_statement_flags)
else:
self.handle_unknown(current_token, preserve_statement_flags)
def handle_whitespace_and_comments(
self, current_token, preserve_statement_flags=False):
newlines = current_token.newlines
keep_whitespace = self._options.keep_array_indentation and self.is_array(
self._flags.mode)
if current_token.comments_before is not None:
for comment_token in current_token.comments_before:
# The cleanest handling of inline comments is to treat them
# as though they aren't there.
# Just continue formatting and the behavior should be logical.
# Also ignore unknown tokens. Again, this should result in better
# behavior.
self.handle_whitespace_and_comments(
comment_token, preserve_statement_flags)
self.handle_token(comment_token, preserve_statement_flags)
if keep_whitespace:
for i in range(newlines):
self.print_newline(i > 0, preserve_statement_flags)
else: # not keep_whitespace
if self._options.max_preserve_newlines != 0 and newlines > self._options.max_preserve_newlines:
newlines = self._options.max_preserve_newlines
if self._options.preserve_newlines and newlines > 1:
self.print_newline(False, preserve_statement_flags)
for i in range(1, newlines):
self.print_newline(True, preserve_statement_flags)
def unpack(self, source, evalcode=False):
import jsbeautifier.unpackers as unpackers
try:
return unpackers.run(source, evalcode)
except unpackers.UnpackingError:
return source
def is_array(self, mode):
return mode == MODE.ArrayLiteral
def is_expression(self, mode):
return mode == MODE.Expression or mode == MODE.ForInitializer or mode == MODE.Conditional
_newline_restricted_tokens = frozenset([
'async',
'break',
'continue',
'return',
'throw',
'yield'])
def allow_wrap_or_preserved_newline(
self, current_token, force_linewrap=False):
# never wrap the first token of a line.
if self._output.just_added_newline():
return
shouldPreserveOrForce = (
self._options.preserve_newlines and current_token.newlines) or force_linewrap
operatorLogicApplies = self._flags.last_token.text in Tokenizer.positionable_operators or current_token.text in Tokenizer.positionable_operators
if operatorLogicApplies:
shouldPrintOperatorNewline = (self._flags.last_token.text in Tokenizer.positionable_operators and self._options.operator_position in OPERATOR_POSITION_BEFORE_OR_PRESERVE) \
or current_token.text in Tokenizer.positionable_operators
shouldPreserveOrForce = shouldPreserveOrForce and shouldPrintOperatorNewline
if shouldPreserveOrForce:
self.print_newline(preserve_statement_flags=True)
elif self._options.wrap_line_length > 0:
if reserved_array(self._flags.last_token, self._newline_restricted_tokens):
# These tokens should never have a newline inserted between
# them and the following expression.
return
self._output.set_wrap_point()
def print_newline(
self,
force_newline=False,
preserve_statement_flags=False):
if not preserve_statement_flags:
if self._flags.last_token.text != ';' and self._flags.last_token.text != ',' and self._flags.last_token.text != '=' and (
self._flags.last_token.type != TOKEN.OPERATOR or self._flags.last_token.text == '--' or self._flags.last_token.text == '++'):
next_token = self._tokens.peek()
while (self._flags.mode == MODE.Statement and \
not (self._flags.if_block and reserved_word(next_token, 'else')) and \
not self._flags.do_block):
self.restore_mode()
if self._output.add_new_line(force_newline):
self._flags.multiline_frame = True
def print_token_line_indentation(self, current_token):
if self._output.just_added_newline():
line = self._output.current_line
if self._options.keep_array_indentation and \
current_token.newlines and \
(self.is_array(self._flags.mode) or
current_token.text == '['):
line.set_indent(-1)
line.push(current_token.whitespace_before)
self._output.space_before_token = False
elif self._output.set_indent(self._flags.indentation_level,
self._flags.alignment):
self._flags.line_indent_level = self._flags.indentation_level
def print_token(self, current_token, s=None):
if self._output.raw:
self._output.add_raw_token(current_token)
return
if self._options.comma_first and current_token.previous and \
current_token.previous.type == TOKEN.COMMA and \
self._output.just_added_newline():
if self._output.previous_line.last() == ',':
# if the comma was already at the start of the line,
# pull back onto that line and reprint the indentation
popped = self._output.previous_line.pop()
if self._output.previous_line.is_empty():
self._output.previous_line.push(popped)
self._output.trim(True)
self._output.current_line.pop()
self._output.trim()
# add the comma in front of the next token
self.print_token_line_indentation(current_token)
self._output.add_token(',')
self._output.space_before_token = True
if s is None:
s = current_token.text
self.print_token_line_indentation(current_token)
self._output.non_breaking_space = True
self._output.add_token(s)
if self._output.previous_token_wrapped:
self._flags.multiline_frame = True
def indent(self):
self._flags.indentation_level += 1
self._output.set_indent(self._flags.indentation_level,
self._flags.alignment)
def deindent(self):
allow_deindent = self._flags.indentation_level > 0 and (
(self._flags.parent is None) or self._flags.indentation_level > self._flags.parent.indentation_level)
if allow_deindent:
self._flags.indentation_level -= 1
self._output.set_indent(self._flags.indentation_level,
self._flags.alignment)
def set_mode(self, mode):
if self._flags:
self._flag_store.append(self._flags)
self._previous_flags = self._flags
else:
self._previous_flags = BeautifierFlags(mode)
self._flags = BeautifierFlags(mode)
self._flags.apply_base(
self._previous_flags,
self._output.just_added_newline())
self._flags.start_line_index = self._output.get_line_number()
self._output.set_indent(self._flags.indentation_level,
self._flags.alignment)
def restore_mode(self):
if len(self._flag_store) > 0:
self._previous_flags = self._flags
self._flags = self._flag_store.pop()
if self._previous_flags.mode == MODE.Statement:
remove_redundant_indentation(self._output, self._previous_flags)
self._output.set_indent(self._flags.indentation_level,
self._flags.alignment)
def start_of_object_property(self):
return self._flags.parent.mode == MODE.ObjectLiteral and self._flags.mode == MODE.Statement and (
(self._flags.last_token.text == ':' and self._flags.ternary_depth == 0) or (
reserved_array(self._flags.last_token, ['get', 'set'])))
def start_of_statement(self, current_token):
start = False
start = start or (
reserved_array(self._flags.last_token, ['var', 'let', 'const']) and
current_token.type == TOKEN.WORD)
start = start or reserved_word(self._flags.last_token, 'do')
start = start or (
not (self._flags.parent.mode == MODE.ObjectLiteral and self._flags.mode == MODE.Statement) and
reserved_array(self._flags.last_token, self._newline_restricted_tokens) and
not current_token.newlines)
start = start or (
reserved_word(self._flags.last_token, 'else') and not (
reserved_word(current_token, 'if') and \
current_token.comments_before is None))
start = start or (self._flags.last_token.type == TOKEN.END_EXPR and (
self._previous_flags.mode == MODE.ForInitializer or self._previous_flags.mode == MODE.Conditional))
start = start or (self._flags.last_token.type == TOKEN.WORD and self._flags.mode == MODE.BlockStatement
and not self._flags.in_case
and not (current_token.text == '--' or current_token.text == '++')
and self._last_last_text != 'function'
and current_token.type != TOKEN.WORD and current_token.type != TOKEN.RESERVED)
start = start or (
self._flags.mode == MODE.ObjectLiteral and (
(self._flags.last_token.text == ':' and self._flags.ternary_depth == 0) or (
reserved_array(self._flags.last_token, ['get', 'set']))))
if (start):
self.set_mode(MODE.Statement)
self.indent()
self.handle_whitespace_and_comments(current_token, True)
# Issue #276:
# If starting a new statement with [if, for, while, do], push to a new line.
# if (a) if (b) if(c) d(); else e(); else f();
if not self.start_of_object_property():
self.allow_wrap_or_preserved_newline(
current_token, reserved_array(current_token, ['do', 'for', 'if', 'while']))
return True
else:
return False
def handle_start_expr(self, current_token):
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
pass
else:
self.handle_whitespace_and_comments(current_token)
next_mode = MODE.Expression
if current_token.text == '[':
if self._flags.last_token.type == TOKEN.WORD or self._flags.last_token.text == ')':
if reserved_array(self._flags.last_token, Tokenizer.line_starters):
self._output.space_before_token = True
self.print_token(current_token)
self.set_mode(next_mode)
self.indent()
if self._options.space_in_paren:
self._output.space_before_token = True
return
next_mode = MODE.ArrayLiteral
if self.is_array(self._flags.mode):
if self._flags.last_token.text == '[' or (
self._flags.last_token.text == ',' and (
self._last_last_text == ']' or self._last_last_text == '}')):
# ], [ goes to a new line
# }, [ goes to a new line
if not self._options.keep_array_indentation:
self.print_newline()
if self._flags.last_token.type not in [
TOKEN.START_EXPR,
TOKEN.END_EXPR,
TOKEN.WORD,
TOKEN.OPERATOR]:
self._output.space_before_token = True
else:
if self._flags.last_token.type == TOKEN.RESERVED:
if self._flags.last_token.text == 'for':
self._output.space_before_token = self._options.space_before_conditional
next_mode = MODE.ForInitializer
elif self._flags.last_token.text in ['if', 'while']:
self._output.space_before_token = self._options.space_before_conditional
next_mode = MODE.Conditional
elif self._flags.last_word in ['await', 'async']:
# Should be a space between await and an IIFE, or async and
# an arrow function
self._output.space_before_token = True
elif self._flags.last_token.text == 'import' and current_token.whitespace_before == '':
self._output.space_before_token = False
elif self._flags.last_token.text in Tokenizer.line_starters or self._flags.last_token.text == 'catch':
self._output.space_before_token = True
elif self._flags.last_token.type in [TOKEN.EQUALS, TOKEN.OPERATOR]:
# Support of this kind of newline preservation:
# a = (b &&
# (c || d));
if not self.start_of_object_property():
self.allow_wrap_or_preserved_newline(current_token)
elif self._flags.last_token.type == TOKEN.WORD:
self._output.space_before_token = False
# function name() vs function name ()
# function* name() vs function* name ()
# async name() vs async name ()
# In ES6, you can also define the method properties of an object
# var obj = {a: function() {}}
# It can be abbreviated
# var obj = {a() {}}
# var obj = { a() {}} vs var obj = { a () {}}
# var obj = { * a() {}} vs var obj = { * a () {}}
peek_back_two = self._tokens.peek(-3)
if self._options.space_after_named_function and peek_back_two:
# peek starts at next character so -1 is current token
peek_back_three = self._tokens.peek(-4)
if reserved_array(peek_back_two, ['async', 'function']) or (
peek_back_two.text == '*' and
reserved_array(peek_back_three, ['async', 'function'])):
self._output.space_before_token = True
elif self._flags.mode == MODE.ObjectLiteral:
if (peek_back_two.text == '{' or peek_back_two.text == ',') or (
peek_back_two.text == '*' and (
peek_back_three.text == '{' or peek_back_three.text == ',')):
self._output.space_before_token = True
else:
# Support preserving wrapped arrow function expressions
# a.b('c',
# () => d.e
# )
self.allow_wrap_or_preserved_newline(current_token)
# function() vs function (), typeof() vs typeof ()
# function*() vs function* (), yield*() vs yield* ()
if (
self._flags.last_token.type == TOKEN.RESERVED and (
self._flags.last_word == 'function' or self._flags.last_word == 'typeof')) or (
self._flags.last_token.text == '*' and (
self._last_last_text in [
'function', 'yield'] or (
self._flags.mode == MODE.ObjectLiteral and self._last_last_text in [
'{', ',']))):
self._output.space_before_token = self._options.space_after_anon_function
if self._flags.last_token.text == ';' or self._flags.last_token.type == TOKEN.START_BLOCK:
self.print_newline()
elif self._flags.last_token.type in [TOKEN.END_EXPR, TOKEN.START_EXPR, TOKEN.END_BLOCK, TOKEN.COMMA] or self._flags.last_token.text == '.':
# do nothing on (( and )( and ][ and ]( and .(
# TODO: Consider whether forcing this is required. Review failing
# tests when removed.
self.allow_wrap_or_preserved_newline(
current_token, current_token.newlines)
self.print_token(current_token)
self.set_mode(next_mode)
if self._options.space_in_paren:
self._output.space_before_token = True
# In all cases, if we newline while inside an expression it should be
# indented.
self.indent()
def handle_end_expr(self, current_token):
# statements inside expressions are not valid syntax, but...
# statements must all be closed when their container closes
while self._flags.mode == MODE.Statement:
self.restore_mode()
self.handle_whitespace_and_comments(current_token)
if self._flags.multiline_frame:
self.allow_wrap_or_preserved_newline(
current_token, current_token.text == ']' and self.is_array(
self._flags.mode) and not self._options.keep_array_indentation)
if self._options.space_in_paren:
if self._flags.last_token.type == TOKEN.START_EXPR and not self._options.space_in_empty_paren:
# empty parens are always "()" and "[]", not "( )" or "[ ]"
self._output.space_before_token = False
self._output.trim()
else:
self._output.space_before_token = True
self.deindent()
self.print_token(current_token)
self.restore_mode()
remove_redundant_indentation(self._output, self._previous_flags)
# do {} while () // no statement required after
if self._flags.do_while and self._previous_flags.mode == MODE.Conditional:
self._previous_flags.mode = MODE.Expression
self._flags.do_block = False
self._flags.do_while = False
def handle_start_block(self, current_token):
self.handle_whitespace_and_comments(current_token)
# Check if this is a BlockStatement that should be treated as a
# ObjectLiteral
next_token = self._tokens.peek()
second_token = self._tokens.peek(1)
if self._flags.last_word == 'switch' and \
self._flags.last_token.type == TOKEN.END_EXPR:
self.set_mode(MODE.BlockStatement)
self._flags.in_case_statement = True
elif self._flags.case_body:
self.set_mode(MODE.BlockStatement)
elif second_token is not None and (
(second_token.text in [
':',
','] and next_token.type in [
TOKEN.STRING,
TOKEN.WORD,
TOKEN.RESERVED]) or (
next_token.text in [
'get',
'set',
'...'] and second_token.type in [
TOKEN.WORD,
TOKEN.RESERVED])):
# We don't support TypeScript,but we didn't break it for a very long time.
# We'll try to keep not breaking it.
if self._last_last_text not in ['class', 'interface']:
self.set_mode(MODE.ObjectLiteral)
else:
self.set_mode(MODE.BlockStatement)
elif self._flags.last_token.type == TOKEN.OPERATOR and self._flags.last_token.text == '=>':
# arrow function: (param1, paramN) => { statements }
self.set_mode(MODE.BlockStatement)
elif self._flags.last_token.type in [TOKEN.EQUALS, TOKEN.START_EXPR, TOKEN.COMMA, TOKEN.OPERATOR] or \
reserved_array(self._flags.last_token, ['return', 'throw', 'import', 'default']):
# Detecting shorthand function syntax is difficult by scanning forward,
# so check the surrounding context.
# If the block is being returned, imported, export default, passed as arg,
# assigned with = or assigned in a nested object, treat as an
# ObjectLiteral.
self.set_mode(MODE.ObjectLiteral)
else:
self.set_mode(MODE.BlockStatement)
empty_braces = (next_token is not None) and \
next_token.comments_before is None and next_token.text == '}'
empty_anonymous_function = empty_braces and self._flags.last_word == 'function' and \
self._flags.last_token.type == TOKEN.END_EXPR
if self._options.brace_preserve_inline: # check for inline, set inline_frame if so
# search forward for newline wanted inside this block
index = 0
check_token = None
self._flags.inline_frame = True
do_loop = True
while (do_loop):
index += 1
check_token = self._tokens.peek(index - 1)
if check_token.newlines:
self._flags.inline_frame = False
do_loop = (
check_token.type != TOKEN.EOF and not (
check_token.type == TOKEN.END_BLOCK and check_token.opened == current_token))
if (self._options.brace_style == 'expand' or (self._options.brace_style ==
'none' and current_token.newlines)) and not self._flags.inline_frame:
if self._flags.last_token.type != TOKEN.OPERATOR and (
empty_anonymous_function or self._flags.last_token.type == TOKEN.EQUALS or (
reserved_array(self._flags.last_token, _special_word_set) and self._flags.last_token.text != 'else')):
self._output.space_before_token = True
else:
self.print_newline(preserve_statement_flags=True)
else: # collapse || inline_frame
if self.is_array(
self._previous_flags.mode) and (
self._flags.last_token.type == TOKEN.START_EXPR or self._flags.last_token.type == TOKEN.COMMA):
# if we're preserving inline,
# allow newline between comma and next brace.
if self._flags.inline_frame:
self.allow_wrap_or_preserved_newline(current_token)
self._flags.inline_frame = True
self._previous_flags.multiline_frame = self._previous_flags.multiline_frame or self._flags.multiline_frame
self._flags.multiline_frame = False
elif self._flags.last_token.type == TOKEN.COMMA:
self._output.space_before_token = True
elif self._flags.last_token.type not in [TOKEN.OPERATOR, TOKEN.START_EXPR]:
if self._flags.last_token.type == TOKEN.START_BLOCK and not self._flags.inline_frame:
self.print_newline()
else:
self._output.space_before_token = True
self.print_token(current_token)
self.indent()
# Except for specific cases, open braces are followed by a new line.
if not empty_braces and not (
self._options.brace_preserve_inline and
self._flags.inline_frame):
self.print_newline()
def handle_end_block(self, current_token):
# statements must all be closed when their container closes
self.handle_whitespace_and_comments(current_token)
while self._flags.mode == MODE.Statement:
self.restore_mode()
empty_braces = self._flags.last_token.type == TOKEN.START_BLOCK
# try inline_frame (only set if opt.braces-preserve-inline) first
if self._flags.inline_frame and not empty_braces:
self._output.space_before_token = True
elif self._options.brace_style == 'expand':
if not empty_braces:
self.print_newline()
else:
# skip {}
if not empty_braces:
if self.is_array(
self._flags.mode) and self._options.keep_array_indentation:
self._options.keep_array_indentation = False
self.print_newline()
self._options.keep_array_indentation = True
else:
self.print_newline()
self.restore_mode()
self.print_token(current_token)
def handle_word(self, current_token):
if current_token.type == TOKEN.RESERVED:
if current_token.text in [
'set', 'get'] and self._flags.mode != MODE.ObjectLiteral:
current_token.type = TOKEN.WORD
elif current_token.text == 'import' and self._tokens.peek().text == '(':
current_token.type = TOKEN.WORD
elif current_token.text in ['as', 'from'] and not self._flags.import_block:
current_token.type = TOKEN.WORD
elif self._flags.mode == MODE.ObjectLiteral:
next_token = self._tokens.peek()
if next_token.text == ':':
current_token.type = TOKEN.WORD
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
if reserved_array(self._flags.last_token, ['var', 'let', 'const']) and \
current_token.type == TOKEN.WORD:
self._flags.declaration_statement = True
elif current_token.newlines and \
not self.is_expression(self._flags.mode) and \
(self._flags.last_token.type != TOKEN.OPERATOR or (self._flags.last_token.text == '--' or self._flags.last_token.text == '++')) and \
self._flags.last_token.type != TOKEN.EQUALS and \
(self._options.preserve_newlines or not reserved_array(self._flags.last_token, ['var', 'let', 'const', 'set', 'get'])):
self.handle_whitespace_and_comments(current_token)
self.print_newline()
else:
self.handle_whitespace_and_comments(current_token)
if self._flags.do_block and not self._flags.do_while:
if reserved_word(current_token, 'while'):
# do {} ## while ()
self._output.space_before_token = True
self.print_token(current_token)
self._output.space_before_token = True
self._flags.do_while = True
return
else:
# do {} should always have while as the next word.
# if we don't see the expected while, recover
self.print_newline()
self._flags.do_block = False
# if may be followed by else, or not
# Bare/inline ifs are tricky
# Need to unwind the modes correctly: if (a) if (b) c(); else d(); else
# e();
if self._flags.if_block:
if (not self._flags.else_block) and reserved_word(current_token, 'else'):
self._flags.else_block = True
else:
while self._flags.mode == MODE.Statement:
self.restore_mode()
self._flags.if_block = False
if self._flags.in_case_statement and reserved_array(current_token, ['case', 'default']):
self.print_newline()
if self._flags.last_token.type != TOKEN.END_BLOCK and (
self._flags.case_body or self._options.jslint_happy):
self.deindent()
self._flags.case_body = False
self.print_token(current_token)
self._flags.in_case = True
return
if self._flags.last_token.type in [
TOKEN.COMMA,
TOKEN.START_EXPR,
TOKEN.EQUALS,
TOKEN.OPERATOR]:
if not self.start_of_object_property():
self.allow_wrap_or_preserved_newline(current_token)
if reserved_word(current_token, 'function'):
if (self._flags.last_token.text in ['}', ';'] or (self._output.just_added_newline() and not (
self._flags.last_token.text in ['(', '[', '{', ':', '=', ','] or self._flags.last_token.type == TOKEN.OPERATOR))):
# make sure there is a nice clean space of at least one blank line
# before a new function definition, except in arrays
if not self._output.just_added_blankline() and \
current_token.comments_before is None:
self.print_newline()
self.print_newline(True)
if self._flags.last_token.type == TOKEN.RESERVED or self._flags.last_token.type == TOKEN.WORD:
if reserved_array(self._flags.last_token, ['get', 'set', 'new', 'export']) or \
reserved_array(self._flags.last_token, self._newline_restricted_tokens):
self._output.space_before_token = True
elif reserved_word(self._flags.last_token, 'default') and self._last_last_text == 'export':
self._output.space_before_token = True
elif self._flags.last_token.text == 'declare':
# accomodates Typescript declare function formatting
self._output.space_before_token = True
else:
self.print_newline()
elif self._flags.last_token.type == TOKEN.OPERATOR or self._flags.last_token.text == '=':
# foo = function
self._output.space_before_token = True
elif not self._flags.multiline_frame and (self.is_expression(self._flags.mode) or self.is_array(self._flags.mode)):
# (function
pass
else:
self.print_newline()
self.print_token(current_token)
self._flags.last_word = current_token.text
return
prefix = 'NONE'
if self._flags.last_token.type == TOKEN.END_BLOCK:
if self._previous_flags.inline_frame:
prefix = 'SPACE'
elif not reserved_array(current_token, ['else', 'catch', 'finally', 'from']):
prefix = 'NEWLINE'
else:
if self._options.brace_style in ['expand', 'end-expand'] or (
self._options.brace_style == 'none' and current_token.newlines):
prefix = 'NEWLINE'
else:
prefix = 'SPACE'
self._output.space_before_token = True
elif self._flags.last_token.type == TOKEN.SEMICOLON and self._flags.mode == MODE.BlockStatement:
# TODO: Should this be for STATEMENT as well?
prefix = 'NEWLINE'
elif self._flags.last_token.type == TOKEN.SEMICOLON and self.is_expression(self._flags.mode):
prefix = 'SPACE'
elif self._flags.last_token.type == TOKEN.STRING:
prefix = 'NEWLINE'
elif self._flags.last_token.type == TOKEN.RESERVED or self._flags.last_token.type == TOKEN.WORD or \
(self._flags.last_token.text == '*' and (
self._last_last_text in ['function', 'yield'] or
(self._flags.mode == MODE.ObjectLiteral and self._last_last_text in ['{', ',']))):
prefix = 'SPACE'
elif self._flags.last_token.type == TOKEN.START_BLOCK:
if self._flags.inline_frame:
prefix = 'SPACE'
else:
prefix = 'NEWLINE'
elif self._flags.last_token.type == TOKEN.END_EXPR:
self._output.space_before_token = True
prefix = 'NEWLINE'
if reserved_array(current_token, Tokenizer.line_starters) and self._flags.last_token.text != ')':
if self._flags.inline_frame or self._flags.last_token.text == 'else ' or self._flags.last_token.text == 'export':
prefix = 'SPACE'
else:
prefix = 'NEWLINE'
if reserved_array(current_token, ['else', 'catch', 'finally']):
if ((not (self._flags.last_token.type == TOKEN.END_BLOCK and self._previous_flags.mode == MODE.BlockStatement))
or self._options.brace_style == 'expand'
or self._options.brace_style == 'end-expand'
or (self._options.brace_style == 'none' and current_token.newlines)) \
and not self._flags.inline_frame:
self.print_newline()
else:
self._output.trim(True)
# If we trimmed and there's something other than a close block before us
# put a newline back in. Handles '} // comment' scenario.
if self._output.current_line.last() != '}':
self.print_newline()
self._output.space_before_token = True
elif prefix == 'NEWLINE':
if reserved_array(self._flags.last_token, _special_word_set):
# no newline between return nnn
self._output.space_before_token = True
elif self._flags.last_token.text == 'declare' and reserved_array(current_token, [
'var',
'let',
'const']):
# accomodates Typescript declare formatting
self._output.space_before_token = True
elif self._flags.last_token.type != TOKEN.END_EXPR:
if (
self._flags.last_token.type != TOKEN.START_EXPR or not (
reserved_array(current_token, [
'var',
'let',
'const']))) and self._flags.last_token.text != ':':
# no need to force newline on VAR -
# for (var x = 0...
if reserved_word(current_token, 'if') and self._flags.last_token.text == 'else':
self._output.space_before_token = True
else:
self.print_newline()
elif reserved_array(current_token, Tokenizer.line_starters) and self._flags.last_token.text != ')':
self.print_newline()
elif self._flags.multiline_frame and self.is_array(self._flags.mode) and self._flags.last_token.text == ',' and self._last_last_text == '}':
self.print_newline() # }, in lists get a newline
elif prefix == 'SPACE':
self._output.space_before_token = True
if current_token.previous and (current_token.previous.type == TOKEN.WORD or
current_token.previous.type == TOKEN.RESERVED):
self._output.space_before_token = True
self.print_token(current_token)
self._flags.last_word = current_token.text
if current_token.type == TOKEN.RESERVED:
if current_token.text == 'do':
self._flags.do_block = True
elif current_token.text == 'if':
self._flags.if_block = True
elif current_token.text == 'import':
self._flags.import_block = True
elif current_token.text == 'from' and self._flags.import_block:
self._flags.import_block = False
def handle_semicolon(self, current_token):
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
# Semicolon can be the start (and end) of a statement
self._output.space_before_token = False
else:
self.handle_whitespace_and_comments(current_token)
next_token = self._tokens.peek()
while (self._flags.mode == MODE.Statement and
not (self._flags.if_block and reserved_word(next_token, 'else')) and
not self._flags.do_block):
self.restore_mode()
if self._flags.import_block:
self._flags.import_block = False
self.print_token(current_token)
def handle_string(self, current_token):
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
# One difference - strings want at least a space before
self._output.space_before_token = True
else:
self.handle_whitespace_and_comments(current_token)
if self._flags.last_token.type == TOKEN.RESERVED or self._flags.last_token.type == TOKEN.WORD or self._flags.inline_frame:
self._output.space_before_token = True
elif self._flags.last_token.type in [TOKEN.COMMA, TOKEN.START_EXPR, TOKEN.EQUALS, TOKEN.OPERATOR]:
if not self.start_of_object_property():
self.allow_wrap_or_preserved_newline(current_token)
else:
self.print_newline()
self.print_token(current_token)
def handle_equals(self, current_token):
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
pass
else:
self.handle_whitespace_and_comments(current_token)
if self._flags.declaration_statement:
# just got an '=' in a var-line, different line breaking rules will
# apply
self._flags.declaration_assignment = True
self._output.space_before_token = True
self.print_token(current_token)
self._output.space_before_token = True
def handle_comma(self, current_token):
self.handle_whitespace_and_comments(current_token, True)
self.print_token(current_token)
self._output.space_before_token = True
if self._flags.declaration_statement:
if self.is_expression(self._flags.parent.mode):
# do not break on comma, for ( var a = 1, b = 2
self._flags.declaration_assignment = False
if self._flags.declaration_assignment:
self._flags.declaration_assignment = False
self.print_newline(preserve_statement_flags=True)
elif self._options.comma_first:
# for comma-first, we want to allow a newline before the comma
# to turn into a newline after the comma, which we will fixup
# later
self.allow_wrap_or_preserved_newline(current_token)
elif self._flags.mode == MODE.ObjectLiteral \
or (self._flags.mode == MODE.Statement and self._flags.parent.mode == MODE.ObjectLiteral):
if self._flags.mode == MODE.Statement:
self.restore_mode()
if not self._flags.inline_frame:
self.print_newline()
elif self._options.comma_first:
# EXPR or DO_BLOCK
# for comma-first, we want to allow a newline before the comma
# to turn into a newline after the comma, which we will fixup later
self.allow_wrap_or_preserved_newline(current_token)
def handle_operator(self, current_token):
isGeneratorAsterisk = current_token.text == '*' and \
(reserved_array(self._flags.last_token, ['function', 'yield']) or
(self._flags.last_token.type in [TOKEN.START_BLOCK, TOKEN.COMMA, TOKEN.END_BLOCK, TOKEN.SEMICOLON]))
isUnary = current_token.text in ['+', '-'] \
and (self._flags.last_token.type in [TOKEN.START_BLOCK, TOKEN.START_EXPR, TOKEN.EQUALS, TOKEN.OPERATOR]
or self._flags.last_token.text in Tokenizer.line_starters or self._flags.last_token.text == ',')
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
pass
else:
preserve_statement_flags = not isGeneratorAsterisk
self.handle_whitespace_and_comments(
current_token, preserve_statement_flags)
if reserved_array(self._flags.last_token, _special_word_set):
# return had a special handling in TK_WORD
self._output.space_before_token = True
self.print_token(current_token)
return
# hack for actionscript's import .*;
if current_token.text == '*' and self._flags.last_token.type == TOKEN.DOT:
self.print_token(current_token)
return
if current_token.text == '::':
# no spaces around the exotic namespacing syntax operator
self.print_token(current_token)
return
# Allow line wrapping between operators when operator_position is
# set to before or preserve
if self._flags.last_token.type == TOKEN.OPERATOR and self._options.operator_position in OPERATOR_POSITION_BEFORE_OR_PRESERVE:
self.allow_wrap_or_preserved_newline(current_token)
if current_token.text == ':' and self._flags.in_case:
self.print_token(current_token)
self._flags.in_case = False
self._flags.case_body = True
if self._tokens.peek().type != TOKEN.START_BLOCK:
self.indent()
self.print_newline()
else:
self._output.space_before_token = True
return
space_before = True
space_after = True
in_ternary = False
if current_token.text == ':':
if self._flags.ternary_depth == 0:
# Colon is invalid javascript outside of ternary and object,
# but do our best to guess what was meant.
space_before = False
else:
self._flags.ternary_depth -= 1
in_ternary = True
elif current_token.text == '?':
self._flags.ternary_depth += 1
# let's handle the operator_position option prior to any conflicting
# logic
if (not isUnary) and (not isGeneratorAsterisk) and \
self._options.preserve_newlines and current_token.text in Tokenizer.positionable_operators:
isColon = current_token.text == ':'
isTernaryColon = isColon and in_ternary
isOtherColon = isColon and not in_ternary
if self._options.operator_position == OPERATOR_POSITION['before_newline']:
# if the current token is : and it's not a ternary statement
# then we set space_before to false
self._output.space_before_token = not isOtherColon
self.print_token(current_token)
if (not isColon) or isTernaryColon:
self.allow_wrap_or_preserved_newline(current_token)
self._output.space_before_token = True
return
elif self._options.operator_position == OPERATOR_POSITION['after_newline']:
# if the current token is anything but colon, or (via deduction) it's a colon and in a ternary statement,
# then print a newline.
self._output.space_before_token = True
if (not isColon) or isTernaryColon:
if self._tokens.peek().newlines:
self.print_newline(preserve_statement_flags=True)
else:
self.allow_wrap_or_preserved_newline(current_token)
else:
self._output.space_before_token = False
self.print_token(current_token)
self._output.space_before_token = True
return
elif self._options.operator_position == OPERATOR_POSITION['preserve_newline']:
if not isOtherColon:
self.allow_wrap_or_preserved_newline(current_token)
# if we just added a newline, or the current token is : and it's not a ternary statement,
# then we set space_before to false
self._output.space_before_token = not (
self._output.just_added_newline() or isOtherColon)
self.print_token(current_token)
self._output.space_before_token = True
return
if isGeneratorAsterisk:
self.allow_wrap_or_preserved_newline(current_token)
space_before = False
next_token = self._tokens.peek()
space_after = next_token and next_token.type in [
TOKEN.WORD, TOKEN.RESERVED]
elif current_token.text == '...':
self.allow_wrap_or_preserved_newline(current_token)
space_before = self._flags.last_token.type == TOKEN.START_BLOCK
space_after = False
elif current_token.text in ['--', '++', '!', '~'] or isUnary:
if self._flags.last_token.type == TOKEN.COMMA or self._flags.last_token.type == TOKEN.START_EXPR:
self.allow_wrap_or_preserved_newline(current_token)
space_before = False
space_after = False
# http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1
# if there is a newline between -- or ++ and anything else we
# should preserve it.
if current_token.newlines and (
current_token.text == '--' or current_token.text == '++'):
self.print_newline(preserve_statement_flags=True)
if self._flags.last_token.text == ';' and self.is_expression(
self._flags.mode):
# for (;; ++i)
# ^^
space_before = True
if self._flags.last_token.type == TOKEN.RESERVED:
space_before = True
elif self._flags.last_token.type == TOKEN.END_EXPR:
space_before = not (
self._flags.last_token.text == ']' and current_token.text in [
'--', '++'])
elif self._flags.last_token.type == TOKEN.OPERATOR:
# a++ + ++b
# a - -b
space_before = current_token.text in [
'--', '-', '++', '+'] and self._flags.last_token.text in ['--', '-', '++', '+']
# + and - are not unary when preceeded by -- or ++ operator
# a-- + b
# a * +b
# a - -b
if current_token.text in [
'-', '+'] and self._flags.last_token.text in ['--', '++']:
space_after = True
if (((self._flags.mode == MODE.BlockStatement and not self._flags.inline_frame)
or self._flags.mode == MODE.Statement) and self._flags.last_token.text in ['{', ';']):
# { foo: --i }
# foo(): --bar
self.print_newline()
if space_before:
self._output.space_before_token = True
self.print_token(current_token)
if space_after:
self._output.space_before_token = True
def handle_block_comment(self, current_token, preserve_statement_flags):
if self._output.raw:
self._output.add_raw_token(current_token)
if current_token.directives and current_token.directives.get(
'preserve') == 'end':
# If we're testing the raw output behavior, do not allow a
# directive to turn it off.
self._output.raw = self._options.test_output_raw
return
if current_token.directives:
self.print_newline(
preserve_statement_flags=preserve_statement_flags)
self.print_token(current_token)
if current_token.directives.get('preserve') == 'start':
self._output.raw = True
self.print_newline(preserve_statement_flags=True)
return
# inline block
if not self.acorn.newline.search(
current_token.text) and not current_token.newlines:
self._output.space_before_token = True
self.print_token(current_token)
self._output.space_before_token = True
return
lines = self.acorn.allLineBreaks.split(current_token.text)
javadoc = False
starless = False
last_indent = current_token.whitespace_before
last_indent_length = len(last_indent)
# block comment starts with a new line
self.print_newline(preserve_statement_flags=preserve_statement_flags)
# first line always indented
self.print_token(current_token, lines[0])
self.print_newline(preserve_statement_flags=preserve_statement_flags)
if len(lines) > 1:
lines = lines[1:]
javadoc = not any(l for l in lines if (
l.strip() == '' or (l.lstrip())[0] != '*'))
starless = all(l.startswith(last_indent)
or l.strip() == '' for l in lines)
if javadoc:
self._flags.alignment = 1
for line in lines:
if javadoc:
# javadoc: reformat and re-indent
self.print_token(current_token, line.lstrip())
elif starless and len(line) > last_indent_length:
# starless: re-indent non-empty content, avoiding trim
self.print_token(current_token, line[last_indent_length:])
else:
# normal comments output raw
self._output.current_line.set_indent(-1)
self._output.add_token(line)
# for comments on their own line or more than one line,
# make sure there's a new line after
self.print_newline(preserve_statement_flags=preserve_statement_flags)
self._flags.alignment = 0
def handle_comment(self, current_token, preserve_statement_flags):
if current_token.newlines:
self.print_newline(
preserve_statement_flags=preserve_statement_flags)
if not current_token.newlines:
self._output.trim(True)
self._output.space_before_token = True
self.print_token(current_token)
self.print_newline(preserve_statement_flags=preserve_statement_flags)
def handle_dot(self, current_token):
if self.start_of_statement(current_token):
# The conditional starts the statement if appropriate.
pass
else:
self.handle_whitespace_and_comments(current_token, True)
if reserved_array(self._flags.last_token, _special_word_set):
self._output.space_before_token = False
else:
# allow preserved newlines before dots in general
# force newlines on dots after close paren when break_chained - for
# bar().baz()
self.allow_wrap_or_preserved_newline(
current_token, self._flags.last_token.text == ')' and
self._options.break_chained_methods)
# Only unindent chained method dot if this dot starts a new line.
# Otherwise the automatic extra indentation removal
# will handle any over indent
if self._options.unindent_chained_methods and \
self._output.just_added_newline():
self.deindent()
self.print_token(current_token)
def handle_unknown(self, current_token, preserve_statement_flags):
self.print_token(current_token)
if current_token.text[-1] == '\n':
self.print_newline(
preserve_statement_flags=preserve_statement_flags)
def handle_eof(self, current_token):
# Unwind any open statements
while self._flags.mode == MODE.Statement:
self.restore_mode()
self.handle_whitespace_and_comments(current_token)
jsbeautifier-1.10.3/jsbeautifier/javascript/options.py 0000644 0000765 0000024 00000010426 13476247317 024445 0 ustar bitwiseman staff 0000000 0000000 # 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.
from ..core.options import Options as BaseOptions
OPERATOR_POSITION = [
'before-newline',
'after-newline',
'preserve-newline'
]
class BeautifierOptions(BaseOptions):
def __init__(self, options=None):
BaseOptions.__init__(self, 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_list('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.space_after_named_function = self._get_boolean('space_after_named_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)
# For testing of beautify preserve:start directive
self.test_output_raw = False
self.editorconfig = False
# 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
jsbeautifier-1.10.3/jsbeautifier/javascript/tokenizer.py 0000644 0000765 0000024 00000052253 13607407716 024765 0 ustar bitwiseman staff 0000000 0000000 # 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.
import re
from ..core.inputscanner import InputScanner
from ..core.tokenizer import TokenTypes as BaseTokenTypes
from ..core.tokenizer import Tokenizer as BaseTokenizer
from ..core.tokenizer import TokenizerPatterns as BaseTokenizerPatterns
from ..core.directives import Directives
from ..core.pattern import Pattern
from ..core.templatablepattern import TemplatablePattern
__all__ = ["TOKEN", "Tokenizer", "TokenTypes"]
class TokenTypes(BaseTokenTypes):
START_EXPR = 'TK_START_EXPR'
END_EXPR = 'TK_END_EXPR'
START_BLOCK = 'TK_START_BLOCK'
END_BLOCK = 'TK_END_BLOCK'
WORD = 'TK_WORD'
RESERVED = 'TK_RESERVED'
SEMICOLON = 'TK_SEMICOLON'
STRING = 'TK_STRING'
EQUALS = 'TK_EQUALS'
OPERATOR = 'TK_OPERATOR'
COMMA = 'TK_COMMA'
BLOCK_COMMENT = 'TK_BLOCK_COMMENT'
COMMENT = 'TK_COMMENT'
DOT = 'TK_DOT'
UNKNOWN = 'TK_UNKNOWN'
def __init__(self):
pass
TOKEN = TokenTypes()
dot_pattern = re.compile(r'[^\d\.]')
number_pattern = re.compile(
r'0[xX][0123456789abcdefABCDEF]*|0[oO][01234567]*|0[bB][01]*|\d+n|(?:\.\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?')
digit = re.compile(r'[0-9]')
positionable_operators = frozenset(
(">>> === !== " +
"<< && >= ** != == <= >> || " +
"< / - + > : & % ? ^ | *").split(' '))
punct = (">>>= " +
"... >>= <<= === >>> !== **= " +
"=> ^= :: /= << <= == && -= >= >> != -- += ** || ++ %= &= *= |= " +
"= ! ? > < : / ^ - + * & % ~ |")
punct = re.compile(r'([-[\]{}()*+?.,\\^$|#])').sub(r'\\\1', punct)
punct = punct.replace(' ', '|')
punct_pattern = re.compile(punct)
# Words which always should start on a new line
line_starters = frozenset(
('continue,try,throw,return,var,let,const,if,switch,case,default,for,' +
'while,break,function,import,export').split(','))
reserved_words = line_starters | frozenset(['do',
'in',
'of',
'else',
'get',
'set',
'new',
'catch',
'finally',
'typeof',
'yield',
'async',
'await',
'from',
'as'])
reserved_word_pattern = re.compile(r'^(?:' + '|'.join(reserved_words) + r')$')
directives_core = Directives(r'/\*', r'\*/')
xmlRegExp = re.compile(
r'[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*(\'[^\']*\'|"[^"]*"|{[\s\S]+?}))*\s*(/?)\s*>')
class TokenizerPatterns(BaseTokenizerPatterns):
def __init__(self, input_scanner, acorn, options):
BaseTokenizerPatterns.__init__(self, input_scanner)
# This is not pretty, but given how we did the version import
# it is the only way to do this without having setup.py fail on a missing
# six dependency.
six = __import__("six")
# IMPORTANT: This string must be run through six to handle \u chars
self.whitespace = self.whitespace.matching(
six.u(r'\u00A0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff'),
six.u(r'\u2028\u2029'))
pattern = Pattern(input_scanner)
templatable = TemplatablePattern(input_scanner) \
.read_options(options)
self.identifier = templatable.starting_with(acorn.identifier \
).matching(acorn.identifierMatch)
self.number = pattern.matching(number_pattern)
self.punct = pattern.matching(punct_pattern)
self.comment = pattern.starting_with(r'//').until(
six.u(r'[\n\r\u2028\u2029]'))
self.block_comment = pattern.starting_with(r'/\*').until_after(r'\*/')
self.html_comment_start = pattern.matching(r'')
self.include = pattern.starting_with(r'#include' \
).until_after(acorn.lineBreak)
self.shebang = pattern.starting_with(r'#!' \
).until_after(acorn.lineBreak)
self.xml = pattern.matching(xmlRegExp)
self.single_quote = templatable.until(six.u(r"['\\\n\r\u2028\u2029]"))
self.double_quote = templatable.until(six.u(r'["\\\n\r\u2028\u2029]'))
self.template_text = templatable.until(r'[`\\$]')
self.template_expression = templatable.until(r'[`}\\]')
class Tokenizer(BaseTokenizer):
positionable_operators = positionable_operators
line_starters = line_starters
def __init__(self, input_string, opts):
BaseTokenizer.__init__(self, input_string, opts)
import jsbeautifier.javascript.acorn as acorn
self.acorn = acorn
self.in_html_comment = False
self.has_char_escapes = False
self._patterns = TokenizerPatterns(self._input, self.acorn, opts)
def _reset(self):
self.in_html_comment = False
def _is_comment(self, current_token):
return current_token.type == TOKEN.COMMENT or \
current_token.type == TOKEN.BLOCK_COMMENT or \
current_token.type == TOKEN.UNKNOWN
def _is_opening(self, current_token):
return current_token.type == TOKEN.START_BLOCK or current_token.type == TOKEN.START_EXPR
def _is_closing(self, current_token, open_token):
return (current_token.type == TOKEN.END_BLOCK or current_token.type == TOKEN.END_EXPR) and \
(open_token is not None and (
(current_token.text == ']' and open_token.text == '[') or
(current_token.text == ')' and open_token.text == '(') or
(current_token.text == '}' and open_token.text == '{')))
def _get_next_token(self, previous_token, open_token):
token = None
self._readWhitespace()
c = self._input.peek()
if c is None:
token = self._create_token(TOKEN.EOF, '')
token = token or self._read_non_javascript(c)
token = token or self._read_string(c)
token = token or self._read_word(previous_token)
token = token or self._read_singles(c)
token = token or self._read_comment(c)
token = token or self._read_regexp(c, previous_token)
token = token or self._read_xml(c, previous_token)
token = token or self._read_punctuation()
token = token or self._create_token(TOKEN.UNKNOWN, self._input.next())
return token
def _read_singles(self, c):
token = None
if c == '(' or c == '[':
token = self._create_token(TOKEN.START_EXPR, c)
elif c == ')' or c == ']':
token = self._create_token(TOKEN.END_EXPR, c)
elif c == '{':
token = self._create_token(TOKEN.START_BLOCK, c)
elif c == '}':
token = self._create_token(TOKEN.END_BLOCK, c)
elif c == ';':
token = self._create_token(TOKEN.SEMICOLON, c)
elif c == '.' and self._input.peek(1) is not None and \
bool(dot_pattern.match(self._input.peek(1))):
token = self._create_token(TOKEN.DOT, c)
elif c == ',':
token = self._create_token(TOKEN.COMMA, c)
if token is not None:
self._input.next()
return token
def _read_word(self, previous_token):
resulting_string = self._patterns.identifier.read()
if bool(resulting_string):
resulting_string = re.sub(self.acorn.allLineBreaks, '\n', resulting_string)
if not (previous_token.type == TOKEN.DOT or (
previous_token.type == TOKEN.RESERVED and (
previous_token.text == 'set' or previous_token.text == 'get')
)) and reserved_word_pattern.match(resulting_string):
if resulting_string == 'in' or resulting_string == 'of':
# in and of are operators, need to hack
return self._create_token(TOKEN.OPERATOR, resulting_string)
return self._create_token(TOKEN.RESERVED, resulting_string)
return self._create_token(TOKEN.WORD, resulting_string)
resulting_string = self._patterns.number.read()
if resulting_string != '':
return self._create_token(TOKEN.WORD, resulting_string)
def _read_comment(self, c):
token = None
if c == '/':
comment = ''
if self._input.peek(1) == '*': # peek /* .. */ comment
comment = self._patterns.block_comment.read()
directives = directives_core.get_directives(comment)
if directives and directives.get('ignore') == 'start':
comment += directives_core.readIgnored(self._input)
comment = re.sub(self.acorn.allLineBreaks, '\n', comment)
token = self._create_token(TOKEN.BLOCK_COMMENT, comment)
token.directives = directives
elif self._input.peek(1) == '/': # peek // comment
comment = self._patterns.comment.read()
token = self._create_token(TOKEN.COMMENT, comment)
return token
def _read_string(self, c):
if c == '`' or c == "'" or c == '"':
resulting_string = self._input.next()
self.has_char_escapes = False
if c == '`':
resulting_string += self.parse_string('`', True, '${')
else:
resulting_string += self.parse_string(c)
if self.has_char_escapes and self._options.unescape_strings:
resulting_string = self.unescape_string(resulting_string)
if self._input.peek() == c:
resulting_string += self._input.next()
resulting_string = re.sub(
self.acorn.allLineBreaks, '\n', resulting_string)
return self._create_token(TOKEN.STRING, resulting_string)
return None
def _read_regexp(self, c, previous_token):
if c == '/' and self.allowRegExOrXML(previous_token):
# handle regexp
resulting_string = self._input.next()
esc = False
in_char_class = False
while self._input.hasNext() and \
(esc or in_char_class or self._input.peek() != c) and \
not self._input.testChar(self.acorn.newline):
resulting_string += self._input.peek()
if not esc:
esc = self._input.peek() == '\\'
if self._input.peek() == '[':
in_char_class = True
elif self._input.peek() == ']':
in_char_class = False
else:
esc = False
self._input.next()
if self._input.peek() == c:
resulting_string += self._input.next()
if c == '/':
# regexps may have modifiers /regexp/MOD, so fetch those too
# Only [gim] are valid, but if the user puts in garbage, do
# what we can to take it.
resulting_string += self._input.read(
self.acorn.identifier)
return self._create_token(TOKEN.STRING, resulting_string)
return None
def _read_xml(self, c, previous_token):
if self._options.e4x and c == "<" and self.allowRegExOrXML(previous_token):
# handle e4x xml literals
xmlStr = ""
match = self._patterns.xml.read_match()
if match and not match.group(1):
rootTag = match.group(2)
rootTag = re.sub(r'^{\s+', '{', re.sub(r'\s+}$', '}', rootTag))
isCurlyRoot = rootTag.startswith('{')
depth = 0
while bool(match):
isEndTag = match.group(1)
tagName = match.group(2)
isSingletonTag = (
match.groups()[-1] != "") or (match.group(2)[0:8] == "![CDATA[")
if not isSingletonTag and (tagName == rootTag or (
isCurlyRoot and re.sub(r'^{\s+', '{', re.sub(r'\s+}$', '}', tagName)))):
if isEndTag:
depth -= 1
else:
depth += 1
xmlStr += match.group(0)
if depth <= 0:
break
match = self._patterns.xml.read_match()
# if we didn't close correctly, keep unformatted.
if not match:
xmlStr += self._input.match(re.compile(r'[\s\S]*')).group(0)
xmlStr = re.sub(self.acorn.allLineBreaks, '\n', xmlStr)
return self._create_token(TOKEN.STRING, xmlStr)
return None
def _read_non_javascript(self, c):
resulting_string = ''
if c == '#':
# she-bang
if self._is_first_token():
resulting_string = self._patterns.shebang.read()
if resulting_string:
return self._create_token(TOKEN.UNKNOWN, resulting_string.strip() + '\n')
# handles extendscript #includes
resulting_string = self._patterns.include.read()
if resulting_string:
return self._create_token(TOKEN.UNKNOWN, resulting_string.strip() + '\n')
c = self._input.next()
# Spidermonkey-specific sharp variables for circular references
# https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
# http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp
# around line 1935
sharp = '#'
if self._input.hasNext() and self._input.testChar(digit):
while True:
c = self._input.next()
sharp += c
if (not self._input.hasNext()) or c == '#' or c == '=':
break
if c == '#':
pass
elif self._input.peek() == '[' and self._input.peek(1) == ']':
sharp += '[]'
self._input.next()
self._input.next()
elif self._input.peek() == '{' and self._input.peek(1) == '}':
sharp += '{}'
self._input.next()
self._input.next()
return self._create_token(TOKEN.WORD, sharp)
self._input.back()
elif c == '<' and self._is_first_token():
if self._patterns.html_comment_start.read():
c = '')
return None
def _read_punctuation(self):
token = None
resulting_string = self._patterns.punct.read()
if resulting_string != '':
if resulting_string == '=':
token = self._create_token(TOKEN.EQUALS, resulting_string)
else:
token = self._create_token(TOKEN.OPERATOR, resulting_string)
return token
__regexTokens = { TOKEN.COMMENT, TOKEN.START_EXPR, TOKEN.START_BLOCK,
TOKEN.START, TOKEN.END_BLOCK, TOKEN.OPERATOR,
TOKEN.EQUALS, TOKEN.EOF, TOKEN.SEMICOLON, TOKEN.COMMA }
def allowRegExOrXML(self, previous_token):
return (previous_token.type == TOKEN.RESERVED and previous_token.text in {'return', 'case', 'throw', 'else', 'do', 'typeof', 'yield'}) or \
(previous_token.type == TOKEN.END_EXPR and previous_token.text == ')' and
previous_token.opened.previous.type == TOKEN.RESERVED and previous_token.opened.previous.text in {'if', 'while', 'for'}) or \
(previous_token.type in self.__regexTokens )
def parse_string(
self,
delimiter,
allow_unescaped_newlines=False,
start_sub=None):
if delimiter == '\'':
pattern = self._patterns.single_quote
elif delimiter == '"':
pattern = self._patterns.double_quote
elif delimiter == '`':
pattern = self._patterns.template_text
elif delimiter == '}':
pattern = self._patterns.template_expression
resulting_string = pattern.read()
next = ''
while self._input.hasNext():
next = self._input.next()
if next == delimiter or \
(not allow_unescaped_newlines and
self.acorn.newline.match(next)):
self._input.back()
break
elif next == '\\' and self._input.hasNext():
current_char = self._input.peek()
if current_char == 'x' or current_char == 'u':
self.has_char_escapes = True
elif current_char == '\r' and self._input.peek(1) == '\n':
self._input.next()
next += self._input.next()
elif start_sub is not None:
if start_sub == '${' and next == '$' and \
self._input.peek() == '{':
next += self._input.next()
if start_sub == next:
if delimiter == '`':
next += self.parse_string(
'}', allow_unescaped_newlines, '`')
else:
next += self.parse_string(
'`', allow_unescaped_newlines, '${')
if self._input.hasNext():
next += self._input.next()
next += pattern.read()
resulting_string += next
return resulting_string
def unescape_string(self, s):
# You think that a regex would work for this
# return s.replace(/\\x([0-9a-f]{2})/gi, function(match, val) {
# return String.fromCharCode(parseInt(val, 16));
# })
# However, dealing with '\xff', '\\xff', '\\\xff' makes this more fun.
out = self.acorn.six.u('')
escaped = 0
input_scan = InputScanner(s)
matched = None
while input_scan.hasNext():
# Keep any whitespace, non-slash characters
# also keep slash pairs.
matched = input_scan.match(re.compile(r'([\s]|[^\\]|\\\\)+'))
if matched:
out += matched.group(0)
if input_scan.peek() != '\\':
continue
input_scan.next()
if input_scan.peek() == 'x':
matched = input_scan.match(re.compile(r'x([0-9A-Fa-f]{2})'))
elif input_scan.peek() == 'u':
matched = input_scan.match(re.compile(r'u([0-9A-Fa-f]{4})'))
else:
out += '\\'
if input_scan.hasNext():
out += input_scan.next()
continue
# If there's some error decoding, return the original string
if not matched:
return s
escaped = int(matched.group(1), 16)
if escaped > 0x7e and escaped <= 0xff and matched.group(
0).startswith('x'):
# we bail out on \x7f..\xff,
# leaving whole string escaped,
# as it's probably completely binary
return s
elif escaped >= 0x00 and escaped < 0x20:
# leave 0x00...0x1f escaped
out += '\\' + matched.group(0)
continue
elif escaped == 0x22 or escaped == 0x27 or escaped == 0x5c:
# single-quote, apostrophe, backslash - escape these
out += ('\\' + chr(escaped))
else:
out += self.acorn.six.unichr(escaped)
return out
jsbeautifier-1.10.3/jsbeautifier/tests/ 0000755 0000765 0000024 00000000000 13607410064 021354 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/jsbeautifier/tests/__init__.py 0000644 0000765 0000024 00000000020 13476247317 023472 0 ustar bitwiseman staff 0000000 0000000 # Empty file :)
jsbeautifier-1.10.3/jsbeautifier/tests/generated/ 0000755 0000765 0000024 00000000000 13607410064 023312 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/jsbeautifier/tests/generated/__init__.py 0000644 0000765 0000024 00000000020 13476247317 025430 0 ustar bitwiseman staff 0000000 0000000 # Empty file :)
jsbeautifier-1.10.3/jsbeautifier/tests/generated/tests.py 0000644 0000765 0000024 00001114166 13607410033 025034 0 ustar bitwiseman staff 0000000 0000000 #!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
AUTO-GENERATED. DO NOT MODIFY.
Script: test/generate-tests.js
Template: test/data/javascript/python.mustache
Data: test/data/javascript/tests.js
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.
'''
import re
import unittest
import jsbeautifier
import six
import copy
class TestJSBeautifier(unittest.TestCase):
options = None
@classmethod
def setUpClass(cls):
pass
cls.wrapregex = re.compile('^(.+)$', re.MULTILINE)
def reset_options(self):
true = True
false = False
default_options = jsbeautifier.default_options()
default_options.indent_size = 4
default_options.indent_char = ' '
default_options.preserve_newlines = true
default_options.jslint_happy = false
default_options.indent_level = 0
default_options.break_chained_methods = false
default_options.eol = '\n'
default_options.indent_size = 4
default_options.indent_char = ' '
default_options.preserve_newlines = true
default_options.jslint_happy = false
self.options = copy.copy(default_options)
def test_unescape(self):
# Test cases contributed by
test_fragment = self.decodesto
self.reset_options()
bt = self.bt
def unicode_char(value):
return six.unichr(value)
bt('"\\\\s"') # == "\\s" in the js source
bt("'\\\\s'") # == '\\s' in the js source
bt("'\\\\\\s'") # == '\\\s' in the js source
bt("'\\s'") # == '\s' in the js source
bt('"•"')
bt('"—"')
bt('"\\x41\\x42\\x43\\x01"', '"\\x41\\x42\\x43\\x01"')
bt('"\\u2022"', '"\\u2022"')
bt('a = /\s+/')
#bt('a = /\\x41/','a = /A/')
bt('"\\u2022";a = /\s+/;"\\x41\\x42\\x43\\x01".match(/\\x41/);','"\\u2022";\na = /\s+/;\n"\\x41\\x42\\x43\\x01".match(/\\x41/);')
test_fragment('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"', '"\\x22\\x27", \'\\x22\\x27\', "\\x5c", \'\\x5c\', "\\xff and \\xzz", "unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"')
self.options.unescape_strings = True
bt('"\\x41\\x42\\x43\\x01"', '"ABC\\x01"')
test_fragment('"\\x20\\x40\\x4a"', '" @J"')
test_fragment('"\\xff\\x40\\x4a"')
test_fragment('"\\u0072\\u016B\\u0137\\u012B\\u0074\\u0069\\u0073"', six.u('"\u0072\u016B\u0137\u012B\u0074\u0069\u0073"'))
bt('a = /\s+/')
test_fragment('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff"',
'"\\"\\\'", \'\\"\\\'\', "\\\\", \'\\\\\', "\\xff", "unicode \\u0000 \\" \\\' \\\\ ' + unicode_char(0xffff) + '"')
# For error case, return the string unchanged
test_fragment('"\\x22\\x27",\'\\x22\\x27\',"\\x5c",\'\\x5c\',"\\xff and \\xzz","unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"',
'"\\"\\\'", \'\\"\\\'\', "\\\\", \'\\\\\', "\\xff and \\xzz", "unicode \\u0000 \\u0022 \\u0027 \\u005c \\uffff \\uzzzz"')
self.options.unescape_strings = False
def test_beautifier(self):
test_fragment = self.decodesto
bt = self.bt
true = True
false = False
def unicode_char(value):
return six.unichr(value)
##============================================================
# Line wrap test inputs
#....---------1---------2---------3---------4---------5---------6---------7
#....1234567890123456789012345678901234567890123456789012345678901234567890
wrap_input_1=(
'foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' +
'return between_return_and_expression_should_never_wrap.but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' +
'object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
'}');
#....---------1---------2---------3---------4---------5---------6---------7
#....1234567890123456789012345678901234567890123456789012345678901234567890
wrap_input_2=(
'{\n' +
' foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n.but_this_can\n' +
' return between_return_and_expression_should_never_wrap.but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
' if (wraps_can_occur && inside_an_if_block) that_is_\n.okay();\n' +
' object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
' }' +
'}');
#============================================================
# Unicode Support
self.reset_options()
bt('var ' + unicode_char(3232) + '_' + unicode_char(3232) + ' = "hi";')
bt(
'var ' + unicode_char(228) + 'x = {\n' +
' ' + unicode_char(228) + 'rgerlich: true\n' +
'};')
bt(
'var \\u00E4\\u0ca0\\u0cA0\\u0Ca0 = {\n' +
' \\u0ca0rgerlich: true\n' +
'};')
bt(
'var \\u00E4add\\u0025 = {\n' +
' \\u0044rgerlich\\u0ca0: true\n' +
'};')
bt(
'var' + unicode_char(160) + unicode_char(3232) + '_' + unicode_char(3232) + ' = "hi";',
# -- output --
'var ' + unicode_char(3232) + '_' + unicode_char(3232) + ' = "hi";')
#============================================================
# Test template and continuation strings
self.reset_options()
bt('`This is a ${template} string.`')
bt(
'`This\n' +
' is\n' +
' a\n' +
' ${template}\n' +
' string.`')
bt(
'a = `This is a continuation\\\n' +
'string.`')
bt(
'a = "This is a continuation\\\n' +
'string."')
bt(
'`SELECT\n' +
' nextval(\'${this.options.schema ? `${this.options.schema}.` : \'\'}"${this.tableName}_${this.autoIncrementField}_seq"\'::regclass\n' +
' ) nextval;`')
# Tests for #1030
bt(
'const composeUrl = (host) => {\n' +
' return `${host `test`}`;\n' +
'};')
bt(
'const composeUrl = (host, api, key, data) => {\n' +
' switch (api) {\n' +
' case "Init":\n' +
' return `${host}/vwapi/Init?VWID=${key}&DATA=${encodeURIComponent(\n' +
' Object.keys(data).map((k) => `${k}=${ data[k]}` ).join(";")\n' +
' )}`;\n' +
' case "Pay":\n' +
' return `${host}/vwapi/Pay?SessionId=${par}`;\n' +
' };\n' +
'};')
#============================================================
# Private Class Fields
self.reset_options()
bt('#foo')
bt(
'class X {\n' +
' #foo = null;\n' +
' get foo() {\n' +
' return this.#foo;\n' +
' }\n' +
'}')
bt(
'class X {#foo=null;}',
# -- output --
'class X {\n' +
' #foo = null;\n' +
'}')
#============================================================
# ES7 Decorators
self.reset_options()
bt('@foo')
bt('@foo(bar)')
bt(
'@foo(function(k, v) {\n' +
' implementation();\n' +
'})')
#============================================================
# ES7 exponential
self.reset_options()
bt('x ** 2')
bt('x ** -2')
#============================================================
# Spread operator
self.reset_options()
self.options.brace_style = "collapse,preserve-inline"
bt('const m = { ...item, c: 3 };')
bt(
'const m = {\n' +
' ...item,\n' +
' c: 3\n' +
'};')
bt('const m = { c: 3, ...item };')
bt('const m = [...item, 3];')
bt('const m = [3, ...item];')
#============================================================
# Object literal shorthand functions
self.reset_options()
bt(
'return {\n' +
' foo() {\n' +
' return 42;\n' +
' }\n' +
'}')
bt(
'var foo = {\n' +
' * bar() {\n' +
' yield 42;\n' +
' }\n' +
'};')
bt(
'var foo = {bar(){return 42;},*barGen(){yield 42;}};',
# -- output --
'var foo = {\n' +
' bar() {\n' +
' return 42;\n' +
' },\n' +
' * barGen() {\n' +
' yield 42;\n' +
' }\n' +
'};')
# also handle generator shorthand in class - #1013
bt(
'class A {\n' +
' fn() {\n' +
' return true;\n' +
' }\n' +
'\n' +
' * gen() {\n' +
' return true;\n' +
' }\n' +
'}')
bt(
'class A {\n' +
' * gen() {\n' +
' return true;\n' +
' }\n' +
'\n' +
' fn() {\n' +
' return true;\n' +
' }\n' +
'}')
#============================================================
# End With Newline - (end_with_newline = "true")
self.reset_options()
self.options.end_with_newline = true
test_fragment('', '\n')
test_fragment(' return .5', ' return .5\n')
test_fragment(
' \n' +
'\n' +
'return .5\n' +
'\n' +
'\n' +
'\n',
# -- output --
' return .5\n')
test_fragment('\n')
# End With Newline - (end_with_newline = "false")
self.reset_options()
self.options.end_with_newline = false
test_fragment('')
test_fragment(' return .5')
test_fragment(
' \n' +
'\n' +
'return .5\n' +
'\n' +
'\n' +
'\n',
# -- output --
' return .5')
test_fragment('\n', '')
#============================================================
# Support Indent Level Options and Base Indent Autodetection - ()
self.reset_options()
test_fragment(' a')
test_fragment(
' function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
test_fragment(
' // This is a random comment\n' +
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' // This is a random comment\n' +
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
# Support Indent Level Options and Base Indent Autodetection - (indent_level = "0")
self.reset_options()
self.options.indent_level = 0
test_fragment(' a')
test_fragment(
' function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
test_fragment(
' // This is a random comment\n' +
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' // This is a random comment\n' +
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
# Support Indent Level Options and Base Indent Autodetection - (indent_level = "1")
self.reset_options()
self.options.indent_level = 1
test_fragment(' a', ' a')
test_fragment(
' function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
test_fragment(
' // This is a random comment\n' +
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' // This is a random comment\n' +
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
# Support Indent Level Options and Base Indent Autodetection - (indent_level = "2")
self.reset_options()
self.options.indent_level = 2
test_fragment('a', ' a')
test_fragment(
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
test_fragment(
'// This is a random comment\n' +
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
' // This is a random comment\n' +
' function test() {\n' +
' console.log("this is a test");\n' +
' }')
# Support Indent Level Options and Base Indent Autodetection - (indent_with_tabs = "true", indent_level = "2")
self.reset_options()
self.options.indent_with_tabs = true
self.options.indent_level = 2
test_fragment('a', '\t\ta')
test_fragment(
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
'\t\tfunction test() {\n' +
'\t\t\tconsole.log("this is a test");\n' +
'\t\t}')
test_fragment(
'// This is a random comment\n' +
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
'\t\t// This is a random comment\n' +
'\t\tfunction test() {\n' +
'\t\t\tconsole.log("this is a test");\n' +
'\t\t}')
# Support Indent Level Options and Base Indent Autodetection - (indent_level = "0")
self.reset_options()
self.options.indent_level = 0
test_fragment('\t a')
test_fragment(
'\t function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
'\t function test() {\n' +
'\t console.log("this is a test");\n' +
'\t }')
test_fragment(
'\t // This is a random comment\n' +
'function test(){\n' +
' console.log("this is a test");\n' +
'}',
# -- output --
'\t // This is a random comment\n' +
'\t function test() {\n' +
'\t console.log("this is a test");\n' +
'\t }')
#============================================================
# Support simple language specific option inheritance/overriding - (js = "{ "indent_size": 3 }", css = "{ "indent_size": 5 }")
self.reset_options()
self.options.js = { 'indent_size': 3 }
self.options.css = { 'indent_size': 5 }
bt(
'if (a == b) {\n' +
' test();\n' +
'}')
# Support simple language specific option inheritance/overriding - (html = "{ "js": { "indent_size": 3 }, "css": { "indent_size": 5 } }")
self.reset_options()
self.options.html = { 'js': { 'indent_size': 3 }, 'css': { 'indent_size': 5 } }
bt(
'if (a == b) {\n' +
' test();\n' +
'}')
# Support simple language specific option inheritance/overriding - (indent_size = "9", html = "{ "js": { "indent_size": 3 }, "css": { "indent_size": 5 }, "indent_size": 2}", js = "{ "indent_size": 4 }", css = "{ "indent_size": 3 }")
self.reset_options()
self.options.indent_size = 9
self.options.html = { 'js': { 'indent_size': 3 }, 'css': { 'indent_size': 5 }, 'indent_size': 2}
self.options.js = { 'indent_size': 4 }
self.options.css = { 'indent_size': 3 }
bt(
'if (a == b) {\n' +
' test();\n' +
'}')
#============================================================
# Brace style permutations - (brace_style = ""collapse,preserve-inline"")
self.reset_options()
self.options.brace_style = 'collapse,preserve-inline'
bt(
'var a ={a: 2};\n' +
'var a ={a: 2};',
# -- output --
'var a = { a: 2 };\n' +
'var a = { a: 2 };')
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}', 'if (1) { 2 } else { 3 }')
bt('try{a();}catch(b){c();}catch(d){}finally{e();}', 'try { a(); } catch (b) { c(); } catch (d) {} finally { e(); }')
# Brace style permutations - (brace_style = ""collapse,preserve-inline"")
self.reset_options()
self.options.brace_style = 'collapse,preserve-inline'
bt(
'var a =\n' +
'{\n' +
'a: 2\n' +
'}\n' +
';\n' +
'var a =\n' +
'{\n' +
'a: 2\n' +
'}\n' +
';',
# -- output --
'var a = {\n' +
' a: 2\n' +
'};\n' +
'var a = {\n' +
' a: 2\n' +
'};')
bt(
'//case 1\n' +
'if (a == 1)\n' +
'{}\n' +
'//case 2\n' +
'else if (a == 2)\n' +
'{}',
# -- output --
'//case 1\n' +
'if (a == 1) {}\n' +
'//case 2\n' +
'else if (a == 2) {}')
bt(
'if(1)\n' +
'{\n' +
'2\n' +
'}\n' +
'else\n' +
'{\n' +
'3\n' +
'}',
# -- output --
'if (1) {\n' +
' 2\n' +
'} else {\n' +
' 3\n' +
'}')
bt(
'try\n' +
'{\n' +
'a();\n' +
'}\n' +
'catch(b)\n' +
'{\n' +
'c();\n' +
'}\n' +
'catch(d)\n' +
'{}\n' +
'finally\n' +
'{\n' +
'e();\n' +
'}',
# -- output --
'try {\n' +
' a();\n' +
'} catch (b) {\n' +
' c();\n' +
'} catch (d) {} finally {\n' +
' 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'
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'
bt(
'var a =\n' +
'{\n' +
'a: 2\n' +
'}\n' +
';\n' +
'var a =\n' +
'{\n' +
'a: 2\n' +
'}\n' +
';',
# -- output --
'var a = {\n' +
' a: 2\n' +
'};\n' +
'var a = {\n' +
' a: 2\n' +
'};')
bt(
'//case 1\n' +
'if (a == 1)\n' +
'{}\n' +
'//case 2\n' +
'else if (a == 2)\n' +
'{}',
# -- output --
'//case 1\n' +
'if (a == 1) {}\n' +
'//case 2\n' +
'else if (a == 2) {}')
bt(
'if(1)\n' +
'{\n' +
'2\n' +
'}\n' +
'else\n' +
'{\n' +
'3\n' +
'}',
# -- output --
'if (1) {\n' +
' 2\n' +
'} else {\n' +
' 3\n' +
'}')
bt(
'try\n' +
'{\n' +
'a();\n' +
'}\n' +
'catch(b)\n' +
'{\n' +
'c();\n' +
'}\n' +
'catch(d)\n' +
'{}\n' +
'finally\n' +
'{\n' +
'e();\n' +
'}',
# -- output --
'try {\n' +
' a();\n' +
'} catch (b) {\n' +
' c();\n' +
'} catch (d) {} finally {\n' +
' e();\n' +
'}')
#============================================================
# Comma-first option - (comma_first = "false")
self.reset_options()
self.options.comma_first = false
bt(
'{a:1, b:2}',
# -- output --
'{\n' +
' a: 1,\n' +
' b: 2\n' +
'}')
bt(
'var a=1, b=c[d], e=6;',
# -- output --
'var a = 1,\n' +
' b = c[d],\n' +
' e = 6;')
bt(
'for(var a=1,b=2,c=3;d<3;d++)\n' +
'e',
# -- output --
'for (var a = 1, b = 2, c = 3; d < 3; d++)\n' +
' e')
bt(
'for(var a=1,b=2,\n' +
'c=3;d<3;d++)\n' +
'e',
# -- output --
'for (var a = 1, b = 2,\n' +
' c = 3; d < 3; d++)\n' +
' e')
bt(
'function foo() {\n' +
' return [\n' +
' "one",\n' +
' "two"\n' +
' ];\n' +
'}')
bt(
'a=[[1,2],[4,5],[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],[7,8],]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' [7, 8],\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' function() {},\n' +
' [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' function() {},\n' +
' function() {},\n' +
' [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' function() {},\n' +
' [7, 8]\n' +
']')
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]')
bt(
'a=[b,c,\n' +
'function(){},function(){},d]',
# -- output --
'a = [b, c,\n' +
' function() {},\n' +
' function() {},\n' +
' d\n' +
']')
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]')
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]')
bt(
'[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
# -- output --
'[\n' +
' [\n' +
' ["1", "2"],\n' +
' ["3", "4"]\n' +
' ],\n' +
' [\n' +
' ["5", "6", "7"],\n' +
' ["8", "9", "0"]\n' +
' ],\n' +
' [\n' +
' ["1", "2", "3"],\n' +
' ["4", "5", "6", "7"],\n' +
' ["8", "9", "0"]\n' +
' ]\n' +
']')
bt(
'changeCollection.add({\n' +
' name: "Jonathan" // New line inserted after this line on every save\n' +
' , age: 25\n' +
'});',
# -- output --
'changeCollection.add({\n' +
' name: "Jonathan" // New line inserted after this line on every save\n' +
' ,\n' +
' age: 25\n' +
'});')
bt(
'changeCollection.add(\n' +
' function() {\n' +
' return true;\n' +
' },\n' +
' function() {\n' +
' return true;\n' +
' }\n' +
');')
# Comma-first option - (comma_first = "true")
self.reset_options()
self.options.comma_first = true
bt(
'{a:1, b:2}',
# -- output --
'{\n' +
' a: 1\n' +
' , b: 2\n' +
'}')
bt(
'var a=1, b=c[d], e=6;',
# -- output --
'var a = 1\n' +
' , b = c[d]\n' +
' , e = 6;')
bt(
'for(var a=1,b=2,c=3;d<3;d++)\n' +
'e',
# -- output --
'for (var a = 1, b = 2, c = 3; d < 3; d++)\n' +
' e')
bt(
'for(var a=1,b=2,\n' +
'c=3;d<3;d++)\n' +
'e',
# -- output --
'for (var a = 1, b = 2\n' +
' , c = 3; d < 3; d++)\n' +
' e')
bt(
'function foo() {\n' +
' return [\n' +
' "one"\n' +
' , "two"\n' +
' ];\n' +
'}')
bt(
'a=[[1,2],[4,5],[7,8]]',
# -- output --
'a = [\n' +
' [1, 2]\n' +
' , [4, 5]\n' +
' , [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],[7,8],]',
# -- output --
'a = [\n' +
' [1, 2]\n' +
' , [4, 5]\n' +
' , [7, 8]\n' +
', ]')
bt(
'a=[[1,2],[4,5],function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2]\n' +
' , [4, 5]\n' +
' , function() {}\n' +
' , [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2]\n' +
' , [4, 5]\n' +
' , function() {}\n' +
' , function() {}\n' +
' , [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2]\n' +
' , [4, 5]\n' +
' , function() {}\n' +
' , [7, 8]\n' +
']')
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]')
bt(
'a=[b,c,\n' +
'function(){},function(){},d]',
# -- output --
'a = [b, c\n' +
' , function() {}\n' +
' , function() {}\n' +
' , d\n' +
']')
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]')
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]')
bt(
'[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
# -- output --
'[\n' +
' [\n' +
' ["1", "2"]\n' +
' , ["3", "4"]\n' +
' ]\n' +
' , [\n' +
' ["5", "6", "7"]\n' +
' , ["8", "9", "0"]\n' +
' ]\n' +
' , [\n' +
' ["1", "2", "3"]\n' +
' , ["4", "5", "6", "7"]\n' +
' , ["8", "9", "0"]\n' +
' ]\n' +
']')
bt(
'changeCollection.add({\n' +
' name: "Jonathan" // New line inserted after this line on every save\n' +
' , age: 25\n' +
'});')
bt(
'changeCollection.add(\n' +
' function() {\n' +
' return true;\n' +
' },\n' +
' function() {\n' +
' return true;\n' +
' }\n' +
');',
# -- output --
'changeCollection.add(\n' +
' function() {\n' +
' return true;\n' +
' }\n' +
' , function() {\n' +
' return true;\n' +
' }\n' +
');')
#============================================================
# Unindent chained functions - (unindent_chained_methods = "true")
self.reset_options()
self.options.unindent_chained_methods = true
bt(
'f().f().f()\n' +
' .f().f();',
# -- output --
'f().f().f()\n' +
'.f().f();')
bt(
'f()\n' +
' .f()\n' +
' .f();',
# -- output --
'f()\n' +
'.f()\n' +
'.f();')
bt(
'f(function() {\n' +
' f()\n' +
' .f()\n' +
' .f();\n' +
'});',
# -- output --
'f(function() {\n' +
' f()\n' +
' .f()\n' +
' .f();\n' +
'});')
# regression test for fix #1378
bt(
'f(function() {\n' +
' if(g === 1)\n' +
' g = 0;\n' +
' else\n' +
' g = 1;\n' +
'\n' +
' f()\n' +
' .f()\n' +
' .f();\n' +
'});',
# -- output --
'f(function() {\n' +
' if (g === 1)\n' +
' g = 0;\n' +
' else\n' +
' g = 1;\n' +
'\n' +
' f()\n' +
' .f()\n' +
' .f();\n' +
'});')
# regression test for fix #1533
bt(
'angular.module("test").controller("testCtrl", function($scope) {\n' +
' $scope.tnew;\n' +
' $scope.toggle_tnew = function() {\n' +
' $scope.mode = 0;\n' +
' if (!$scope.tnew) {\n' +
' $scope.tnew = {};\n' +
' } else $scope.tnew = null;\n' +
' }\n' +
' $scope.fn = function() {\n' +
' return null;\n' +
' }\n' +
'});')
#============================================================
# Space in parens tests - (space_in_paren = "false", space_in_empty_paren = "false")
self.reset_options()
self.options.space_in_paren = false
self.options.space_in_empty_paren = false
bt('if(p) foo(a,b);', 'if (p) foo(a, b);')
bt(
'try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
# -- output --
'try {\n' +
' while (true) {\n' +
' willThrow()\n' +
' }\n' +
'} catch (result) switch (result) {\n' +
' case 1:\n' +
' ++result\n' +
'}')
bt('((e/((a+(b)*c)-d))^2)*5;', '((e / ((a + (b) * c) - d)) ^ 2) * 5;')
bt(
'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
# -- output --
'function f(a, b) {\n' +
' if (a) b()\n' +
'}\n' +
'\n' +
'function g(a, b) {\n' +
' if (!a) b()\n' +
'}')
bt('a=[][ ]( );', 'a = [][]();')
bt('a=()( )[ ];', 'a = ()()[];')
bt('a=[b,c,d];', 'a = [b, c, d];')
bt('a= f[b];', 'a = f[b];')
bt(
'{\n' +
' files: a[][ {\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b(c)[ "im/design_standards/*.*" ],\n' +
' dest: "www/gui/build"\n' +
' } ]\n' +
'}',
# -- output --
'{\n' +
' files: a[][{\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b(c)["im/design_standards/*.*"],\n' +
' dest: "www/gui/build"\n' +
' }]\n' +
'}')
# Space in parens tests - (space_in_paren = "false", space_in_empty_paren = "true")
self.reset_options()
self.options.space_in_paren = false
self.options.space_in_empty_paren = true
bt('if(p) foo(a,b);', 'if (p) foo(a, b);')
bt(
'try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
# -- output --
'try {\n' +
' while (true) {\n' +
' willThrow()\n' +
' }\n' +
'} catch (result) switch (result) {\n' +
' case 1:\n' +
' ++result\n' +
'}')
bt('((e/((a+(b)*c)-d))^2)*5;', '((e / ((a + (b) * c) - d)) ^ 2) * 5;')
bt(
'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
# -- output --
'function f(a, b) {\n' +
' if (a) b()\n' +
'}\n' +
'\n' +
'function g(a, b) {\n' +
' if (!a) b()\n' +
'}')
bt('a=[][ ]( );', 'a = [][]();')
bt('a=()( )[ ];', 'a = ()()[];')
bt('a=[b,c,d];', 'a = [b, c, d];')
bt('a= f[b];', 'a = f[b];')
bt(
'{\n' +
' files: a[][ {\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b(c)[ "im/design_standards/*.*" ],\n' +
' dest: "www/gui/build"\n' +
' } ]\n' +
'}',
# -- output --
'{\n' +
' files: a[][{\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b(c)["im/design_standards/*.*"],\n' +
' dest: "www/gui/build"\n' +
' }]\n' +
'}')
# Space in parens tests - (space_in_paren = "true", space_in_empty_paren = "false")
self.reset_options()
self.options.space_in_paren = true
self.options.space_in_empty_paren = false
bt('if(p) foo(a,b);', 'if ( p ) foo( a, b );')
bt(
'try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
# -- output --
'try {\n' +
' while ( true ) {\n' +
' willThrow()\n' +
' }\n' +
'} catch ( result ) switch ( result ) {\n' +
' case 1:\n' +
' ++result\n' +
'}')
bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;')
bt(
'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
# -- output --
'function f( a, b ) {\n' +
' if ( a ) b()\n' +
'}\n' +
'\n' +
'function g( a, b ) {\n' +
' if ( !a ) b()\n' +
'}')
bt('a=[][ ]( );', 'a = [][]();')
bt('a=()( )[ ];', 'a = ()()[];')
bt('a=[b,c,d];', 'a = [ b, c, d ];')
bt('a= f[b];', 'a = f[ b ];')
bt(
'{\n' +
' files: a[][ {\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b(c)[ "im/design_standards/*.*" ],\n' +
' dest: "www/gui/build"\n' +
' } ]\n' +
'}',
# -- output --
'{\n' +
' files: a[][ {\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b( c )[ "im/design_standards/*.*" ],\n' +
' dest: "www/gui/build"\n' +
' } ]\n' +
'}')
# Space in parens tests - (space_in_paren = "true", space_in_empty_paren = "true")
self.reset_options()
self.options.space_in_paren = true
self.options.space_in_empty_paren = true
bt('if(p) foo(a,b);', 'if ( p ) foo( a, b );')
bt(
'try{while(true){willThrow()}}catch(result)switch(result){case 1:++result }',
# -- output --
'try {\n' +
' while ( true ) {\n' +
' willThrow( )\n' +
' }\n' +
'} catch ( result ) switch ( result ) {\n' +
' case 1:\n' +
' ++result\n' +
'}')
bt('((e/((a+(b)*c)-d))^2)*5;', '( ( e / ( ( a + ( b ) * c ) - d ) ) ^ 2 ) * 5;')
bt(
'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
# -- output --
'function f( a, b ) {\n' +
' if ( a ) b( )\n' +
'}\n' +
'\n' +
'function g( a, b ) {\n' +
' if ( !a ) b( )\n' +
'}')
bt('a=[][ ]( );', 'a = [ ][ ]( );')
bt('a=()( )[ ];', 'a = ( )( )[ ];')
bt('a=[b,c,d];', 'a = [ b, c, d ];')
bt('a= f[b];', 'a = f[ b ];')
bt(
'{\n' +
' files: a[][ {\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b(c)[ "im/design_standards/*.*" ],\n' +
' dest: "www/gui/build"\n' +
' } ]\n' +
'}',
# -- output --
'{\n' +
' files: a[ ][ {\n' +
' expand: true,\n' +
' cwd: "www/gui/",\n' +
' src: b( c )[ "im/design_standards/*.*" ],\n' +
' dest: "www/gui/build"\n' +
' } ]\n' +
'}')
#============================================================
# general preserve_newlines tests - (preserve_newlines = "false")
self.reset_options()
self.options.preserve_newlines = false
bt(
'if (foo) // comment\n' +
' bar();')
bt(
'if (foo) // comment\n' +
' bar();')
bt(
'if (foo) // comment\n' +
' (bar());')
bt(
'if (foo) // comment\n' +
' (bar());')
bt(
'if (foo) // comment\n' +
' /asdf/;')
bt(
'this.oa = new OAuth(\n' +
' _requestToken,\n' +
' _accessToken,\n' +
' consumer_key\n' +
');',
# -- output --
'this.oa = new OAuth(_requestToken, _accessToken, consumer_key);')
bt(
'foo = {\n' +
' x: y, // #44\n' +
' w: z // #44\n' +
'}')
bt(
'switch (x) {\n' +
' case "a":\n' +
' // comment on newline\n' +
' break;\n' +
' case "b": // comment on same line\n' +
' break;\n' +
'}')
bt(
'this.type =\n' +
' this.options =\n' +
' // comment\n' +
' this.enabled null;',
# -- output --
'this.type = this.options =\n' +
' // comment\n' +
' this.enabled null;')
bt(
'someObj\n' +
' .someFunc1()\n' +
' // This comment should not break the indent\n' +
' .someFunc2();',
# -- output --
'someObj.someFunc1()\n' +
' // This comment should not break the indent\n' +
' .someFunc2();')
bt(
'if (true ||\n' +
'!true) return;',
# -- output --
'if (true || !true) return;')
bt(
'if\n' +
'(foo)\n' +
'if\n' +
'(bar)\n' +
'if\n' +
'(baz)\n' +
'whee();\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if\n' +
'(foo)\n' +
'if\n' +
'(bar)\n' +
'if\n' +
'(baz)\n' +
'whee();\n' +
'else\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz) whee();\n' +
' else a();')
bt(
'if (foo)\n' +
'bar();\n' +
'else\n' +
'car();',
# -- output --
'if (foo) bar();\n' +
'else car();')
bt(
'if (foo) if (bar) if (baz);\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz);\n' +
'a();')
bt(
'if (foo) if (bar) if (baz) whee();\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if (foo) a()\n' +
'if (bar) if (baz) whee();\n' +
'a();',
# -- output --
'if (foo) a()\n' +
'if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if (foo);\n' +
'if (bar) if (baz) whee();\n' +
'a();',
# -- output --
'if (foo);\n' +
'if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if (options)\n' +
' for (var p in options)\n' +
' this[p] = options[p];',
# -- output --
'if (options)\n' +
' for (var p in options) this[p] = options[p];')
bt(
'if (options) for (var p in options) this[p] = options[p];',
# -- output --
'if (options)\n' +
' for (var p in options) this[p] = options[p];')
bt(
'if (options) do q(); while (b());',
# -- output --
'if (options)\n' +
' do q(); while (b());')
bt(
'if (options) while (b()) q();',
# -- output --
'if (options)\n' +
' while (b()) q();')
bt(
'if (options) do while (b()) q(); while (a());',
# -- output --
'if (options)\n' +
' do\n' +
' while (b()) q(); while (a());')
bt(
'function f(a, b, c,\n' +
'd, e) {}',
# -- output --
'function f(a, b, c, d, e) {}')
bt(
'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
# -- output --
'function f(a, b) {\n' +
' if (a) b()\n' +
'}\n' +
'\n' +
'function g(a, b) {\n' +
' if (!a) b()\n' +
'}')
bt(
'function f(a,b) {if(a) b()}\n' +
'\n' +
'\n' +
'\n' +
'function g(a,b) {if(!a) b()}',
# -- output --
'function f(a, b) {\n' +
' if (a) b()\n' +
'}\n' +
'\n' +
'function g(a, b) {\n' +
' if (!a) b()\n' +
'}')
bt(
'(if(a) b())(if(a) b())',
# -- output --
'(\n' +
' if (a) b())(\n' +
' if (a) b())')
bt(
'(if(a) b())\n' +
'\n' +
'\n' +
'(if(a) b())',
# -- output --
'(\n' +
' if (a) b())\n' +
'(\n' +
' if (a) b())')
bt(
'if\n' +
'(a)\n' +
'b();',
# -- output --
'if (a) b();')
bt(
'var a =\n' +
'foo',
# -- output --
'var a = foo')
bt(
'var a = {\n' +
'"a":1,\n' +
'"b":2}',
# -- output --
'var a = {\n' +
' "a": 1,\n' +
' "b": 2\n' +
'}')
bt(
'var a = {\n' +
'\'a\':1,\n' +
'\'b\':2}',
# -- output --
'var a = {\n' +
' \'a\': 1,\n' +
' \'b\': 2\n' +
'}')
bt('var a = /*i*/ "b";')
bt(
'var a = /*i*/\n' +
'"b";',
# -- output --
'var a = /*i*/ "b";')
bt(
'{\n' +
'\n' +
'\n' +
'"x"\n' +
'}',
# -- output --
'{\n' +
' "x"\n' +
'}')
bt(
'if(a &&\n' +
'b\n' +
'||\n' +
'c\n' +
'||d\n' +
'&&\n' +
'e) e = f',
# -- output --
'if (a && b || c || d && e) e = f')
bt(
'if(a &&\n' +
'(b\n' +
'||\n' +
'c\n' +
'||d)\n' +
'&&\n' +
'e) e = f',
# -- output --
'if (a && (b || c || d) && e) e = f')
test_fragment(
'\n' +
'\n' +
'"x"',
# -- output --
'"x"')
test_fragment(
'{\n' +
'\n' +
'"x"\n' +
'h=5;\n' +
'}',
# -- output --
'{\n' +
' "x"\n' +
' h = 5;\n' +
'}')
bt(
'var a = "foo" +\n' +
' "bar";',
# -- output --
'var a = "foo" + "bar";')
bt(
'var a = 42; // foo\n' +
'\n' +
'var b;',
# -- output --
'var a = 42; // foo\n' +
'var b;')
bt(
'var a = 42; // foo\n' +
'\n' +
'\n' +
'var b;',
# -- output --
'var a = 42; // foo\n' +
'var b;')
bt(
'a = 1;\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'b = 2;',
# -- output --
'a = 1;\n' +
'b = 2;')
# general preserve_newlines tests - (preserve_newlines = "true")
self.reset_options()
self.options.preserve_newlines = true
bt(
'if (foo) // comment\n' +
' bar();')
bt(
'if (foo) // comment\n' +
' bar();')
bt(
'if (foo) // comment\n' +
' (bar());')
bt(
'if (foo) // comment\n' +
' (bar());')
bt(
'if (foo) // comment\n' +
' /asdf/;')
bt(
'this.oa = new OAuth(\n' +
' _requestToken,\n' +
' _accessToken,\n' +
' consumer_key\n' +
');')
bt(
'foo = {\n' +
' x: y, // #44\n' +
' w: z // #44\n' +
'}')
bt(
'switch (x) {\n' +
' case "a":\n' +
' // comment on newline\n' +
' break;\n' +
' case "b": // comment on same line\n' +
' break;\n' +
'}')
bt(
'this.type =\n' +
' this.options =\n' +
' // comment\n' +
' this.enabled null;')
bt(
'someObj\n' +
' .someFunc1()\n' +
' // This comment should not break the indent\n' +
' .someFunc2();')
bt(
'if (true ||\n' +
'!true) return;',
# -- output --
'if (true ||\n' +
' !true) return;')
bt(
'if\n' +
'(foo)\n' +
'if\n' +
'(bar)\n' +
'if\n' +
'(baz)\n' +
'whee();\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz)\n' +
' whee();\n' +
'a();')
bt(
'if\n' +
'(foo)\n' +
'if\n' +
'(bar)\n' +
'if\n' +
'(baz)\n' +
'whee();\n' +
'else\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz)\n' +
' whee();\n' +
' else\n' +
' a();')
bt(
'if (foo)\n' +
'bar();\n' +
'else\n' +
'car();',
# -- output --
'if (foo)\n' +
' bar();\n' +
'else\n' +
' car();')
bt(
'if (foo) if (bar) if (baz);\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz);\n' +
'a();')
bt(
'if (foo) if (bar) if (baz) whee();\n' +
'a();',
# -- output --
'if (foo)\n' +
' if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if (foo) a()\n' +
'if (bar) if (baz) whee();\n' +
'a();',
# -- output --
'if (foo) a()\n' +
'if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if (foo);\n' +
'if (bar) if (baz) whee();\n' +
'a();',
# -- output --
'if (foo);\n' +
'if (bar)\n' +
' if (baz) whee();\n' +
'a();')
bt(
'if (options)\n' +
' for (var p in options)\n' +
' this[p] = options[p];')
bt(
'if (options) for (var p in options) this[p] = options[p];',
# -- output --
'if (options)\n' +
' for (var p in options) this[p] = options[p];')
bt(
'if (options) do q(); while (b());',
# -- output --
'if (options)\n' +
' do q(); while (b());')
bt(
'if (options) while (b()) q();',
# -- output --
'if (options)\n' +
' while (b()) q();')
bt(
'if (options) do while (b()) q(); while (a());',
# -- output --
'if (options)\n' +
' do\n' +
' while (b()) q(); while (a());')
bt(
'function f(a, b, c,\n' +
'd, e) {}',
# -- output --
'function f(a, b, c,\n' +
' d, e) {}')
bt(
'function f(a,b) {if(a) b()}function g(a,b) {if(!a) b()}',
# -- output --
'function f(a, b) {\n' +
' if (a) b()\n' +
'}\n' +
'\n' +
'function g(a, b) {\n' +
' if (!a) b()\n' +
'}')
bt(
'function f(a,b) {if(a) b()}\n' +
'\n' +
'\n' +
'\n' +
'function g(a,b) {if(!a) b()}',
# -- output --
'function f(a, b) {\n' +
' if (a) b()\n' +
'}\n' +
'\n' +
'\n' +
'\n' +
'function g(a, b) {\n' +
' if (!a) b()\n' +
'}')
bt(
'(if(a) b())(if(a) b())',
# -- output --
'(\n' +
' if (a) b())(\n' +
' if (a) b())')
bt(
'(if(a) b())\n' +
'\n' +
'\n' +
'(if(a) b())',
# -- output --
'(\n' +
' if (a) b())\n' +
'\n' +
'\n' +
'(\n' +
' if (a) b())')
bt(
'if\n' +
'(a)\n' +
'b();',
# -- output --
'if (a)\n' +
' b();')
bt(
'var a =\n' +
'foo',
# -- output --
'var a =\n' +
' foo')
bt(
'var a = {\n' +
'"a":1,\n' +
'"b":2}',
# -- output --
'var a = {\n' +
' "a": 1,\n' +
' "b": 2\n' +
'}')
bt(
'var a = {\n' +
'\'a\':1,\n' +
'\'b\':2}',
# -- output --
'var a = {\n' +
' \'a\': 1,\n' +
' \'b\': 2\n' +
'}')
bt('var a = /*i*/ "b";')
bt(
'var a = /*i*/\n' +
'"b";',
# -- output --
'var a = /*i*/\n' +
' "b";')
bt(
'{\n' +
'\n' +
'\n' +
'"x"\n' +
'}',
# -- output --
'{\n' +
'\n' +
'\n' +
' "x"\n' +
'}')
bt(
'if(a &&\n' +
'b\n' +
'||\n' +
'c\n' +
'||d\n' +
'&&\n' +
'e) e = f',
# -- output --
'if (a &&\n' +
' b ||\n' +
' c ||\n' +
' d &&\n' +
' e) e = f')
bt(
'if(a &&\n' +
'(b\n' +
'||\n' +
'c\n' +
'||d)\n' +
'&&\n' +
'e) e = f',
# -- output --
'if (a &&\n' +
' (b ||\n' +
' c ||\n' +
' d) &&\n' +
' e) e = f')
test_fragment(
'\n' +
'\n' +
'"x"',
# -- output --
'"x"')
test_fragment(
'{\n' +
'\n' +
'"x"\n' +
'h=5;\n' +
'}',
# -- output --
'{\n' +
'\n' +
' "x"\n' +
' h = 5;\n' +
'}')
bt(
'var a = "foo" +\n' +
' "bar";')
bt(
'var a = 42; // foo\n' +
'\n' +
'var b;')
bt(
'var a = 42; // foo\n' +
'\n' +
'\n' +
'var b;')
bt(
'a = 1;\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'b = 2;')
#============================================================
# break chained methods - (break_chained_methods = "false", preserve_newlines = "false")
self.reset_options()
self.options.break_chained_methods = false
self.options.preserve_newlines = false
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'foo.bar().baz().cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat); foo.bar().baz().cucumber(fat)',
# -- output --
'foo.bar().baz().cucumber(fat);\n' +
'foo.bar().baz().cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)\n' +
' foo.bar().baz().cucumber(fat)',
# -- output --
'foo.bar().baz().cucumber(fat)\n' +
'foo.bar().baz().cucumber(fat)')
bt(
'this\n' +
'.something = foo.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'this.something = foo.bar().baz().cucumber(fat)')
bt('this.something.xxx = foo.moo.bar()')
bt(
'this\n' +
'.something\n' +
'.xxx = foo.moo\n' +
'.bar()',
# -- output --
'this.something.xxx = foo.moo.bar()')
# break chained methods - (break_chained_methods = "false", preserve_newlines = "true")
self.reset_options()
self.options.break_chained_methods = false
self.options.preserve_newlines = true
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'foo\n' +
' .bar()\n' +
' .baz().cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat); foo.bar().baz().cucumber(fat)',
# -- output --
'foo\n' +
' .bar()\n' +
' .baz().cucumber(fat);\n' +
'foo.bar().baz().cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)\n' +
' foo.bar().baz().cucumber(fat)',
# -- output --
'foo\n' +
' .bar()\n' +
' .baz().cucumber(fat)\n' +
'foo.bar().baz().cucumber(fat)')
bt(
'this\n' +
'.something = foo.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'this\n' +
' .something = foo.bar()\n' +
' .baz().cucumber(fat)')
bt('this.something.xxx = foo.moo.bar()')
bt(
'this\n' +
'.something\n' +
'.xxx = foo.moo\n' +
'.bar()',
# -- output --
'this\n' +
' .something\n' +
' .xxx = foo.moo\n' +
' .bar()')
# break chained methods - (break_chained_methods = "true", preserve_newlines = "false")
self.reset_options()
self.options.break_chained_methods = true
self.options.preserve_newlines = false
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat); foo.bar().baz().cucumber(fat)',
# -- output --
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat);\n' +
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)\n' +
' foo.bar().baz().cucumber(fat)',
# -- output --
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)\n' +
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt(
'this\n' +
'.something = foo.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'this.something = foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt('this.something.xxx = foo.moo.bar()')
bt(
'this\n' +
'.something\n' +
'.xxx = foo.moo\n' +
'.bar()',
# -- output --
'this.something.xxx = foo.moo.bar()')
# break chained methods - (break_chained_methods = "true", preserve_newlines = "true")
self.reset_options()
self.options.break_chained_methods = true
self.options.preserve_newlines = true
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'foo\n' +
' .bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat); foo.bar().baz().cucumber(fat)',
# -- output --
'foo\n' +
' .bar()\n' +
' .baz()\n' +
' .cucumber(fat);\n' +
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt(
'foo\n' +
'.bar()\n' +
'.baz().cucumber(fat)\n' +
' foo.bar().baz().cucumber(fat)',
# -- output --
'foo\n' +
' .bar()\n' +
' .baz()\n' +
' .cucumber(fat)\n' +
'foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt(
'this\n' +
'.something = foo.bar()\n' +
'.baz().cucumber(fat)',
# -- output --
'this\n' +
' .something = foo.bar()\n' +
' .baz()\n' +
' .cucumber(fat)')
bt('this.something.xxx = foo.moo.bar()')
bt(
'this\n' +
'.something\n' +
'.xxx = foo.moo\n' +
'.bar()',
# -- output --
'this\n' +
' .something\n' +
' .xxx = foo.moo\n' +
' .bar()')
#============================================================
# line wrapping 0
self.reset_options()
self.options.preserve_newlines = false
self.options.wrap_line_length = 0
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
'return between_return_and_expression_should_never_wrap.but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
'object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
' return between_return_and_expression_should_never_wrap.but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
' if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
' object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 70
self.reset_options()
self.options.preserve_newlines = false
self.options.wrap_line_length = 70
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
'return between_return_and_expression_should_never_wrap.but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
'object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap.but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
' if (wraps_can_occur && inside_an_if_block) that_is_.okay();\n' +
' object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 40
self.reset_options()
self.options.preserve_newlines = false
self.options.wrap_line_length = 40
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f &&\n' +
' "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_.okay();\n' +
'object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f &&\n' +
' "sass") || (leans &&\n' +
' mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 41
self.reset_options()
self.options.preserve_newlines = false
self.options.wrap_line_length = 41
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") ||\n' +
' (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_.okay();\n' +
'object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f &&\n' +
' "sass") || (leans &&\n' +
' mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 45
self.reset_options()
self.options.preserve_newlines = false
self.options.wrap_line_length = 45
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") || (\n' +
' leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block)\n' +
' that_is_.okay();\n' +
'object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f && "sass") ||\n' +
' (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_.okay();\n' +
' object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 0
self.reset_options()
self.options.preserve_newlines = true
self.options.wrap_line_length = 0
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap.but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block) that_is_\n' +
' .okay();\n' +
'object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap.but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
' if (wraps_can_occur && inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 70
self.reset_options()
self.options.preserve_newlines = true
self.options.wrap_line_length = 70
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap.but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block) that_is_\n' +
' .okay();\n' +
'object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f && "sass") || (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap.but_this_can\n' +
' if (wraps_can_occur && inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token + 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap + but_this_can,\n' +
' propertz: first_token_should_never_wrap + !but_this_can,\n' +
' proper: "first_token_should_never_wrap" + "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 40
self.reset_options()
self.options.preserve_newlines = true
self.options.wrap_line_length = 40
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f &&\n' +
' "sass") || (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
'object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f &&\n' +
' "sass") || (leans &&\n' +
' mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 41
self.reset_options()
self.options.preserve_newlines = true
self.options.wrap_line_length = 41
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") ||\n' +
' (leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
'object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f &&\n' +
' "sass") || (leans &&\n' +
' mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# line wrapping 45
self.reset_options()
self.options.preserve_newlines = true
self.options.wrap_line_length = 45
test_fragment(
'' + wrap_input_1 + '',
# -- output --
'foo.bar().baz().cucumber((f && "sass") || (\n' +
' leans && mean));\n' +
'Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
'return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
'if (wraps_can_occur && inside_an_if_block)\n' +
' that_is_\n' +
' .okay();\n' +
'object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
'}')
test_fragment(
'' + wrap_input_2 + '',
# -- output --
'{\n' +
' foo.bar().baz().cucumber((f && "sass") ||\n' +
' (leans && mean));\n' +
' Test_very_long_variable_name_this_should_never_wrap\n' +
' .but_this_can\n' +
' return between_return_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' throw between_throw_and_expression_should_never_wrap\n' +
' .but_this_can\n' +
' if (wraps_can_occur &&\n' +
' inside_an_if_block) that_is_\n' +
' .okay();\n' +
' object_literal = {\n' +
' propertx: first_token +\n' +
' 12345678.99999E-6,\n' +
' property: first_token_should_never_wrap +\n' +
' but_this_can,\n' +
' propertz: first_token_should_never_wrap +\n' +
' !but_this_can,\n' +
' proper: "first_token_should_never_wrap" +\n' +
' "but_this_can"\n' +
' }\n' +
'}')
#============================================================
# general preserve_newlines tests preserve limit
self.reset_options()
self.options.preserve_newlines = true
self.options.max_preserve_newlines = 8
bt(
'a = 1;\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'b = 2;',
# -- output --
'a = 1;\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'\n' +
'b = 2;')
#============================================================
# more random test
self.reset_options()
bt('return function();')
bt('var a = function();')
bt('var a = 5 + function();')
# actionscript import
bt('import foo.*;')
# actionscript
bt('function f(a: a, b: b)')
bt(
'function a(a) {} function b(b) {} function c(c) {}',
# -- output --
'function a(a) {}\n' +
'\n' +
'function b(b) {}\n' +
'\n' +
'function c(c) {}')
bt('foo(a, function() {})')
bt('foo(a, /regex/)')
bt(
'/* foo */\n' +
'"x"')
test_fragment(
'roo = {\n' +
' /*\n' +
' ****\n' +
' FOO\n' +
' ****\n' +
' */\n' +
' BAR: 0\n' +
'};')
test_fragment(
'if (zz) {\n' +
' // ....\n' +
'}\n' +
'(function')
bt(
'a = //comment\n' +
' /regex/;')
bt('var a = new function();')
bt('new function')
bt(
'if (a)\n' +
'{\n' +
'b;\n' +
'}\n' +
'else\n' +
'{\n' +
'c;\n' +
'}',
# -- output --
'if (a) {\n' +
' b;\n' +
'} else {\n' +
' c;\n' +
'}')
#============================================================
# 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'
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 = ""after-newline"", preserve_newlines = "false")
self.reset_options()
self.options.operator_position = 'after-newline'
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 = ""preserve-newline"", preserve_newlines = "false")
self.reset_options()
self.options.operator_position = 'preserve-newline'
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 - set to "before-newline" (default value) - ()
self.reset_options()
# 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"")
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"
self.reset_options()
self.options.operator_position = 'after-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' +
' === 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 "preserve-newline"
self.reset_options()
self.options.operator_position = 'preserve-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' +
' %\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' +
' === u !== v\n' +
' !=\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' +
'}')
#============================================================
# Yield tests
self.reset_options()
bt('yield /foo\\//;')
bt('result = yield pgClient.query_(queryString);')
bt('yield [1, 2]')
bt('yield function() {};')
bt('yield* bar();')
# yield should have no space between yield and star
bt('yield * bar();', 'yield* bar();')
# yield should have space between star and generator
bt('yield *bar();', 'yield* bar();')
#============================================================
# Async / await tests
self.reset_options()
bt('async function foo() {}')
bt('let w = async function foo() {}')
bt(
'async function foo() {}\n' +
'var x = await foo();')
# async function as an input to another function
bt('wrapper(async function foo() {})')
# await on inline anonymous function. should have a space after await
bt(
'async function() {\n' +
' var w = await(async function() {\n' +
' return await foo();\n' +
' })();\n' +
'}',
# -- output --
'async function() {\n' +
' var w = await (async function() {\n' +
' return await foo();\n' +
' })();\n' +
'}')
# Regression test #1228
bt('const module = await import("...")')
# Regression test #1658
bt('.')
# ensure that this doesn't break anyone with the async library
bt('async.map(function(t) {})')
# async on arrow function. should have a space after async
bt(
'async() => {}',
# -- output --
'async () => {}')
# async on arrow function. should have a space after async
bt(
'async() => {\n' +
' return 5;\n' +
'}',
# -- output --
'async () => {\n' +
' return 5;\n' +
'}')
# async on arrow function returning expression. should have a space after async
bt(
'async() => 5;',
# -- output --
'async () => 5;')
# async on arrow function returning object literal. should have a space after async
bt(
'async(x) => ({\n' +
' foo: "5"\n' +
'})',
# -- output --
'async (x) => ({\n' +
' foo: "5"\n' +
'})')
bt(
'async (x) => {\n' +
' return x * 2;\n' +
'}')
bt('async () => 5;')
bt('async x => x * 2;')
bt(
'async function() {\n' +
' const obj = {\n' +
' a: 1,\n' +
' b: await fn(),\n' +
' c: 2\n' +
' };\n' +
'}')
bt(
'const a = 1,\n' +
' b = a ? await foo() : b,\n' +
' c = await foo(),\n' +
' d = 3,\n' +
' e = (await foo()),\n' +
' f = 4;')
bt(
'a = {\n' +
' myVar: async function() {\n' +
' return a;\n' +
' },\n' +
' myOtherVar: async function() {\n' +
' yield b;\n' +
' }\n' +
'}')
bt(
'a = {\n' +
' myVar: async () => {\n' +
' return a;\n' +
' },\n' +
' myOtherVar: async async () => {\n' +
' yield b;\n' +
' }\n' +
'}')
#============================================================
# e4x - Test that e4x literals passed through when e4x-option is enabled
self.reset_options()
self.options.e4x = true
bt(
'xml=\n' +
' foo x ;',
# -- output --
'xml = \n' +
' foo x ;')
bt(' ')
bt(' ')
bt(' ')
bt(' ')
bt(' ')
# Handles inline expressions
bt(
'xml=<{a} b="c">\n' +
' foo x{a}>;',
# -- output --
'xml = <{a} b="c">\n' +
' foo x{a}>;')
bt(
'xml=<{a} b="c">\n' +
' \n' +
' foo x{a}>;',
# -- output --
'xml = <{a} b="c">\n' +
' \n' +
' foo x{a}>;')
# xml literals with special characters in elem names - see http://www.w3.org/TR/REC-xml/#NT-NameChar
bt('xml = <_:.valid.xml- _:.valid.xml-="123"/>;')
# xml literals with attributes without equal sign
bt('xml = ;')
# Handles CDATA
bt(
'xml=\n' +
' foo x/]]>;',
# -- output --
'xml = \n' +
' foo x/]]>;')
bt('xml=;', 'xml = ;')
bt('xml= {}]]>;', 'xml = {}]]>;')
# JSX - working jsx from http://prettydiff.com/unit_tests/beautification_javascript_jsx.txt
bt(
'var ListItem = React.createClass({\n' +
' render: function() {\n' +
' return (\n' +
' \n' +
' \n' +
' this.props.item.name\n' +
' \n' +
' \n' +
' );\n' +
' }\n' +
'});')
bt(
'var List = React.createClass({\n' +
' renderList: function() {\n' +
' return this.props.items.map(function(item) {\n' +
' return ;\n' +
' });\n' +
' },\n' +
'\n' +
' render: function() {\n' +
' return \n' +
' this.renderList()\n' +
' \n' +
' }\n' +
'});')
bt(
'var Mist = React.createClass({\n' +
' renderList: function() {\n' +
' return this.props.items.map(function(item) {\n' +
' return {item}} key={item.id} />;\n' +
' });\n' +
' }\n' +
'});')
bt(
'// JSX\n' +
'var box = \n' +
' {shouldShowAnswer(user) ?\n' +
' no : \n' +
' Text Content\n' +
' }\n' +
' ;\n' +
'var a = function() {\n' +
' return asdf ;\n' +
'};\n' +
'\n' +
'var HelloMessage = React.createClass({\n' +
' render: function() {\n' +
' return Hello {this.props.name}
;\n' +
' }\n' +
'});\n' +
'React.render( , mountNode);')
bt(
'var Timer = React.createClass({\n' +
' getInitialState: function() {\n' +
' return {\n' +
' secondsElapsed: 0\n' +
' };\n' +
' },\n' +
' tick: function() {\n' +
' this.setState({\n' +
' secondsElapsed: this.state.secondsElapsed + 1\n' +
' });\n' +
' },\n' +
' componentDidMount: function() {\n' +
' this.interval = setInterval(this.tick, 1000);\n' +
' },\n' +
' componentWillUnmount: function() {\n' +
' clearInterval(this.interval);\n' +
' },\n' +
' render: function() {\n' +
' return (\n' +
' Seconds Elapsed: {this.state.secondsElapsed}
\n' +
' );\n' +
' }\n' +
'});\n' +
'React.render( , mountNode);')
bt(
'var TodoList = React.createClass({\n' +
' render: function() {\n' +
' var createItem = function(itemText) {\n' +
' return {itemText} ;\n' +
' };\n' +
' return {this.props.items.map(createItem)} ;\n' +
' }\n' +
'});')
bt(
'var TodoApp = React.createClass({\n' +
' getInitialState: function() {\n' +
' return {\n' +
' items: [],\n' +
' text: \'\'\n' +
' };\n' +
' },\n' +
' onChange: function(e) {\n' +
' this.setState({\n' +
' text: e.target.value\n' +
' });\n' +
' },\n' +
' handleSubmit: function(e) {\n' +
' e.preventDefault();\n' +
' var nextItems = this.state.items.concat([this.state.text]);\n' +
' var nextText = \'\';\n' +
' this.setState({\n' +
' items: nextItems,\n' +
' text: nextText\n' +
' });\n' +
' },\n' +
' render: function() {\n' +
' return (\n' +
' \n' +
'
TODO \n' +
' \n' +
' \n' +
'
\n' +
' );\n' +
' }\n' +
'});\n' +
'React.render( , mountNode);')
bt(
'var converter = new Showdown.converter();\n' +
'var MarkdownEditor = React.createClass({\n' +
' getInitialState: function() {\n' +
' return {value: \'Type some *markdown* here!\'};\n' +
' },\n' +
' handleChange: function() {\n' +
' this.setState({value: this.refs.textarea.getDOMNode().value});\n' +
' },\n' +
' render: function() {\n' +
' return (\n' +
' \n' +
'
Input \n' +
'
\n' +
'
Output \n' +
'
\n' +
'
\n' +
' );\n' +
' }\n' +
'});\n' +
'React.render( , mountNode);',
# -- output --
'var converter = new Showdown.converter();\n' +
'var MarkdownEditor = React.createClass({\n' +
' getInitialState: function() {\n' +
' return {\n' +
' value: \'Type some *markdown* here!\'\n' +
' };\n' +
' },\n' +
' handleChange: function() {\n' +
' this.setState({\n' +
' value: this.refs.textarea.getDOMNode().value\n' +
' });\n' +
' },\n' +
' render: function() {\n' +
' return (\n' +
' \n' +
'
Input \n' +
'
\n' +
'
Output \n' +
'
\n' +
'
\n' +
' );\n' +
' }\n' +
'});\n' +
'React.render( , mountNode);')
# JSX - Not quite correct jsx formatting that still works
bt(
'var content = (\n' +
' \n' +
' {/* child comment, put {} around */}\n' +
' \n' +
' \n' +
' );\n' +
'var qwer = A dropdown list Do Something Do Something Fun! Do Something Else ;\n' +
'render(dropdown);',
# -- output --
'var content = (\n' +
' \n' +
' {/* child comment, put {} around */}\n' +
' \n' +
' \n' +
');\n' +
'var qwer = A dropdown list Do Something Do Something Fun! Do Something Else ;\n' +
'render(dropdown);')
# Handles messed up tags, as long as it isn't the same name
# as the root tag. Also handles tags of same name as root tag
# as long as nesting matches.
bt(
'xml= ;',
# -- output --
'xml = ;')
# If xml is not terminated, the remainder of the file is treated
# as part of the xml-literal (passed through unaltered)
test_fragment(
'xml=\n' +
'c \n' +
'c\n' +
' c \n' +
' \n' +
' );\n' +
' }\n' +
'});')
bt(
'let a = React.createClass({\n' +
' render() {\n' +
' return (\n' +
' \n' +
' c \n' +
'
\n' +
' );\n' +
' }\n' +
'});')
bt(
'let a = React.createClass({\n' +
' render() {\n' +
' return (\n' +
' \n' +
' c \n' +
'
\n' +
' );\n' +
' }\n' +
'});')
bt(
'let a = React.createClass({\n' +
' render() {\n' +
' return (\n' +
' <{e} className = {d}>\n' +
' c \n' +
' {e}>\n' +
' );\n' +
' }\n' +
'});')
# Issue #914 - Multiline attribute in root tag
bt(
'return (\n' +
' {\n' +
' e.preventDefault()\n' +
' onClick()\n' +
' }}>\n' +
' {children}\n' +
' \n' +
');')
bt(
'return (\n' +
' <{\n' +
' a + b\n' +
' } href="#"\n' +
' onClick={e => {\n' +
' e.preventDefault()\n' +
' onClick()\n' +
' }}>\n' +
' {children}\n' +
' {\n' +
' a + b\n' +
' }>\n' +
');')
bt(
'return (\n' +
' <{\n' +
' a + b\n' +
' } href="#"\n' +
' onClick={e => {\n' +
' e.preventDefault()\n' +
' onClick()\n' +
' }}>\n' +
' {children}\n' +
' {a + b}>\n' +
' );',
# -- output --
'return (\n' +
' <{\n' +
' a + b\n' +
' } href="#"\n' +
' onClick={e => {\n' +
' e.preventDefault()\n' +
' onClick()\n' +
' }}>\n' +
' {children}\n' +
' {a + b}>\n' +
');')
#============================================================
#
self.reset_options()
#============================================================
# e4x disabled
self.reset_options()
self.options.e4x = false
bt(
'xml=\n' +
' foo x ;',
# -- output --
'xml = < a b = "c" > < d / > < e >\n' +
' foo < /e>x ;')
#============================================================
# Multiple braces
self.reset_options()
bt(
'{{}/z/}',
# -- output --
'{\n' +
' {}\n' +
' /z/\n' +
'}')
#============================================================
# Space before conditional - (space_before_conditional = "false")
self.reset_options()
self.options.space_before_conditional = false
bt('if(a) b()')
bt('while(a) b()')
bt(
'do\n' +
' c();\n' +
'while(a) b()')
bt(
'if(a)\n' +
'b();',
# -- output --
'if(a)\n' +
' b();')
bt(
'while(a)\n' +
'b();',
# -- output --
'while(a)\n' +
' b();')
bt(
'do\n' +
'c();\n' +
'while(a);',
# -- output --
'do\n' +
' c();\n' +
'while(a);')
bt('return [];')
bt('return ();')
# Space before conditional - (space_before_conditional = "true")
self.reset_options()
self.options.space_before_conditional = true
bt('if (a) b()')
bt('while (a) b()')
bt(
'do\n' +
' c();\n' +
'while (a) b()')
bt(
'if(a)\n' +
'b();',
# -- output --
'if (a)\n' +
' b();')
bt(
'while(a)\n' +
'b();',
# -- output --
'while (a)\n' +
' b();')
bt(
'do\n' +
'c();\n' +
'while(a);',
# -- output --
'do\n' +
' c();\n' +
'while (a);')
bt('return [];')
bt('return ();')
#============================================================
# Beautify preserve formatting
self.reset_options()
bt(
'/* beautify preserve:start */\n' +
'/* beautify preserve:end */')
bt(
'/* beautify preserve:start */\n' +
' var a = 1;\n' +
'/* beautify preserve:end */')
bt(
'var a = 1;\n' +
'/* beautify preserve:start */\n' +
' var a = 1;\n' +
'/* beautify preserve:end */')
bt('/* beautify preserve:start */ {asdklgh;y;;{}dd2d}/* beautify preserve:end */')
bt(
'var a = 1;\n' +
'/* beautify preserve:start */\n' +
' var a = 1;\n' +
'/* beautify preserve:end */',
# -- output --
'var a = 1;\n' +
'/* beautify preserve:start */\n' +
' var a = 1;\n' +
'/* beautify preserve:end */')
bt(
'var a = 1;\n' +
' /* beautify preserve:start */\n' +
' var a = 1;\n' +
'/* beautify preserve:end */',
# -- output --
'var a = 1;\n' +
'/* beautify preserve:start */\n' +
' var a = 1;\n' +
'/* beautify preserve:end */')
bt(
'var a = {\n' +
' /* beautify preserve:start */\n' +
' one : 1\n' +
' two : 2,\n' +
' three : 3,\n' +
' ten : 10\n' +
' /* beautify preserve:end */\n' +
'};')
bt(
'var a = {\n' +
'/* beautify preserve:start */\n' +
' one : 1,\n' +
' two : 2,\n' +
' three : 3,\n' +
' ten : 10\n' +
'/* beautify preserve:end */\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify preserve:start */\n' +
' one : 1,\n' +
' two : 2,\n' +
' three : 3,\n' +
' ten : 10\n' +
'/* beautify preserve:end */\n' +
'};')
# one space before and after required, only single spaces inside.
bt(
'var a = {\n' +
'/* beautify preserve:start */\n' +
' one : 1,\n' +
' two : 2,\n' +
' three : 3,\n' +
' ten : 10\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify preserve:start */\n' +
' one: 1,\n' +
' two: 2,\n' +
' three: 3,\n' +
' ten: 10\n' +
'};')
bt(
'var a = {\n' +
'/*beautify preserve:start*/\n' +
' one : 1,\n' +
' two : 2,\n' +
' three : 3,\n' +
' ten : 10\n' +
'};',
# -- output --
'var a = {\n' +
' /*beautify preserve:start*/\n' +
' one: 1,\n' +
' two: 2,\n' +
' three: 3,\n' +
' ten: 10\n' +
'};')
bt(
'var a = {\n' +
'/*beautify preserve:start*/\n' +
' one : 1,\n' +
' two : 2,\n' +
' three : 3,\n' +
' ten : 10\n' +
'};',
# -- output --
'var a = {\n' +
' /*beautify preserve:start*/\n' +
' one: 1,\n' +
' two: 2,\n' +
' three: 3,\n' +
' ten: 10\n' +
'};')
# Directive: ignore
bt(
'/* beautify ignore:start */\n' +
'/* beautify ignore:end */')
bt(
'/* beautify ignore:start */\n' +
' var a,,,{ 1;\n' +
' /* beautify ignore:end */')
bt(
'var a = 1;\n' +
'/* beautify ignore:start */\n' +
' var a = 1;\n' +
'/* beautify ignore:end */')
# ignore starts _after_ the start comment, ends after the end comment
bt('/* beautify ignore:start */ {asdklgh;y;+++;dd2d}/* beautify ignore:end */')
bt('/* beautify ignore:start */ {asdklgh;y;+++;dd2d} /* beautify ignore:end */')
bt(
'var a = 1;\n' +
'/* beautify ignore:start */\n' +
' var a,,,{ 1;\n' +
'/*beautify ignore:end*/',
# -- output --
'var a = 1;\n' +
'/* beautify ignore:start */\n' +
' var a,,,{ 1;\n' +
'/*beautify ignore:end*/')
bt(
'var a = 1;\n' +
' /* beautify ignore:start */\n' +
' var a,,,{ 1;\n' +
'/* beautify ignore:end */',
# -- output --
'var a = 1;\n' +
'/* beautify ignore:start */\n' +
' var a,,,{ 1;\n' +
'/* beautify ignore:end */')
bt(
'var a = {\n' +
' /* beautify ignore:start */\n' +
' one : 1\n' +
' two : 2,\n' +
' three : {\n' +
' ten : 10\n' +
' /* beautify ignore:end */\n' +
'};')
bt(
'var a = {\n' +
'/* beautify ignore:start */\n' +
' one : 1\n' +
' two : 2,\n' +
' three : {\n' +
' ten : 10\n' +
'/* beautify ignore:end */\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify ignore:start */\n' +
' one : 1\n' +
' two : 2,\n' +
' three : {\n' +
' ten : 10\n' +
'/* beautify ignore:end */\n' +
'};')
# Directives - multiple and interacting
bt(
'var a = {\n' +
'/* beautify preserve:start */\n' +
'/* beautify preserve:start */\n' +
' one : 1,\n' +
' /* beautify preserve:end */\n' +
' two : 2,\n' +
' three : 3,\n' +
'/* beautify preserve:start */\n' +
' ten : 10\n' +
'/* beautify preserve:end */\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify preserve:start */\n' +
'/* beautify preserve:start */\n' +
' one : 1,\n' +
' /* beautify preserve:end */\n' +
' two: 2,\n' +
' three: 3,\n' +
' /* beautify preserve:start */\n' +
' ten : 10\n' +
'/* beautify preserve:end */\n' +
'};')
bt(
'var a = {\n' +
'/* beautify ignore:start */\n' +
' one : 1\n' +
' /* beautify ignore:end */\n' +
' two : 2,\n' +
'/* beautify ignore:start */\n' +
' three : {\n' +
' ten : 10\n' +
'/* beautify ignore:end */\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify ignore:start */\n' +
' one : 1\n' +
' /* beautify ignore:end */\n' +
' two: 2,\n' +
' /* beautify ignore:start */\n' +
' three : {\n' +
' ten : 10\n' +
'/* beautify ignore:end */\n' +
'};')
# Starts can occur together, ignore:end must occur alone.
bt(
'var a = {\n' +
'/* beautify ignore:start */\n' +
' one : 1\n' +
' NOTE: ignore end block does not support starting other directives\n' +
' This does not match the ending the ignore...\n' +
' /* beautify ignore:end preserve:start */\n' +
' two : 2,\n' +
'/* beautify ignore:start */\n' +
' three : {\n' +
' ten : 10\n' +
' ==The next comment ends the starting ignore==\n' +
'/* beautify ignore:end */\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify ignore:start */\n' +
' one : 1\n' +
' NOTE: ignore end block does not support starting other directives\n' +
' This does not match the ending the ignore...\n' +
' /* beautify ignore:end preserve:start */\n' +
' two : 2,\n' +
'/* beautify ignore:start */\n' +
' three : {\n' +
' ten : 10\n' +
' ==The next comment ends the starting ignore==\n' +
'/* beautify ignore:end */\n' +
'};')
bt(
'var a = {\n' +
'/* beautify ignore:start preserve:start */\n' +
' one : {\n' +
' /* beautify ignore:end */\n' +
' two : 2,\n' +
' /* beautify ignore:start */\n' +
' three : {\n' +
'/* beautify ignore:end */\n' +
' ten : 10\n' +
' // This is all preserved\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify ignore:start preserve:start */\n' +
' one : {\n' +
' /* beautify ignore:end */\n' +
' two : 2,\n' +
' /* beautify ignore:start */\n' +
' three : {\n' +
'/* beautify ignore:end */\n' +
' ten : 10\n' +
' // This is all preserved\n' +
'};')
bt(
'var a = {\n' +
'/* beautify ignore:start preserve:start */\n' +
' one : {\n' +
' /* beautify ignore:end */\n' +
' two : 2,\n' +
' /* beautify ignore:start */\n' +
' three : {\n' +
'/* beautify ignore:end */\n' +
' ten : 10,\n' +
'/* beautify preserve:end */\n' +
' eleven: 11\n' +
'};',
# -- output --
'var a = {\n' +
' /* beautify ignore:start preserve:start */\n' +
' one : {\n' +
' /* beautify ignore:end */\n' +
' two : 2,\n' +
' /* beautify ignore:start */\n' +
' three : {\n' +
'/* beautify ignore:end */\n' +
' ten : 10,\n' +
'/* beautify preserve:end */\n' +
' eleven: 11\n' +
'};')
#============================================================
# Comments and tests
self.reset_options()
# #913
bt(
'class test {\n' +
' method1() {\n' +
' let resp = null;\n' +
' }\n' +
' /**\n' +
' * @param {String} id\n' +
' */\n' +
' method2(id) {\n' +
' let resp2 = null;\n' +
' }\n' +
'}')
# #1090
bt(
'for (var i = 0; i < 20; ++i) // loop\n' +
' if (i % 3) {\n' +
' console.log(i);\n' +
' }\n' +
'console.log("done");')
# #1043
bt(
'var o = {\n' +
' k: 0\n' +
'}\n' +
'// ...\n' +
'foo(o)')
# #713 and #964
bt(
'Meteor.call("foo", bar, function(err, result) {\n' +
' Session.set("baz", result.lorem)\n' +
'})\n' +
'//blah blah')
# #815
bt(
'foo()\n' +
'// this is a comment\n' +
'bar()\n' +
'\n' +
'const foo = 5\n' +
'// comment\n' +
'bar()')
# This shows current behavior. Note #1069 is not addressed yet.
bt(
'if (modulus === 2) {\n' +
' // i might be odd here\n' +
' i += (i & 1);\n' +
' // now i is guaranteed to be even\n' +
' // this block is obviously about the statement above\n' +
'\n' +
' // #1069 This should attach to the block below\n' +
' // this comment is about the block after it.\n' +
'} else {\n' +
' // rounding up using integer arithmetic only\n' +
' if (i % modulus)\n' +
' i += modulus - (i % modulus);\n' +
' // now i is divisible by modulus\n' +
' // behavior of comments should be different for single statements vs block statements/expressions\n' +
'}\n' +
'\n' +
'if (modulus === 2)\n' +
' // i might be odd here\n' +
' i += (i & 1);\n' +
'// now i is guaranteed to be even\n' +
'// non-braced comments unindent immediately\n' +
'\n' +
'// this comment is about the block after it.\n' +
'else\n' +
' // rounding up using integer arithmetic only\n' +
' if (i % modulus)\n' +
' i += modulus - (i % modulus);\n' +
'// behavior of comments should be different for single statements vs block statements/expressions')
#============================================================
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = ;', 'var a = ;')
bt(
'a = abc");\n' +
'}\n' +
'?>;')
test_fragment(
'\n' +
'test.method();')
bt(
'abc;\n' +
'.test();\n' +
'" "')
bt(
';\n' +
'test.method();')
bt('"";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = =$view["name"]; ?>;', 'var a = =$view["name"]; ?>;')
bt(
'a = abc=\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'?>;')
test_fragment(
'= ?>\n' +
'test.met= someValue ?>hod();')
bt(
'= "A" ?>abc= "D" ?>;\n' +
'= "B" ?>.test();\n' +
'" = "C" \'D\' ?> "')
bt(
'=\n' +
'echo "A";\n' +
'?>;\n' +
'test.method();')
bt('"=";if(0){}"?>";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = <%$view["name"]; %>;', 'var a = <%$view["name"]; %>;')
bt(
'a = abc<%\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'%>;')
test_fragment(
'<% %>\n' +
'test.met<% someValue %>hod();')
bt(
'<% "A" %>abc<% "D" %>;\n' +
'<% "B" %>.test();\n' +
'" <% "C" \'D\' %> "')
bt(
'<%\n' +
'echo "A";\n' +
'%>;\n' +
'test.method();')
bt('"<%";if(0){}"%>";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = <%=$view["name"]; %>;', 'var a = <%=$view["name"]; %>;')
bt(
'a = abc<%=\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'%>;')
test_fragment(
'<%= %>\n' +
'test.met<%= someValue %>hod();')
bt(
'<%= "A" %>abc<%= "D" %>;\n' +
'<%= "B" %>.test();\n' +
'" <%= "C" \'D\' %> "')
bt(
'<%=\n' +
'echo "A";\n' +
'%>;\n' +
'test.method();')
bt('"<%=";if(0){}"%>";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{$view["name"]; }};', 'var a = {{$view["name"]; }};')
bt(
'a = abc{{\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'}};')
test_fragment(
'{{ }}\n' +
'test.met{{ someValue }}hod();')
bt(
'{{ "A" }}abc{{ "D" }};\n' +
'{{ "B" }}.test();\n' +
'" {{ "C" \'D\' }} "')
bt(
'{{\n' +
'echo "A";\n' +
'}};\n' +
'test.method();')
bt('"{{";if(0){}"}}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {#$view["name"]; #};', 'var a = {#$view["name"]; #};')
bt(
'a = abc{#\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'#};')
test_fragment(
'{# #}\n' +
'test.met{# someValue #}hod();')
bt(
'{# "A" #}abc{# "D" #};\n' +
'{# "B" #}.test();\n' +
'" {# "C" \'D\' #} "')
bt(
'{#\n' +
'echo "A";\n' +
'#};\n' +
'test.method();')
bt('"{#";if(0){}"#}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {%$view["name"]; %};', 'var a = {%$view["name"]; %};')
bt(
'a = abc{%\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'%};')
test_fragment(
'{% %}\n' +
'test.met{% someValue %}hod();')
bt(
'{% "A" %}abc{% "D" %};\n' +
'{% "B" %}.test();\n' +
'" {% "C" \'D\' %} "')
bt(
'{%\n' +
'echo "A";\n' +
'%};\n' +
'test.method();')
bt('"{%";if(0){}"%}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{$view["name"]; }};', 'var a = {{$view["name"]; }};')
bt(
'a = abc{{\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'}};')
test_fragment(
'{{ }}\n' +
'test.met{{ someValue }}hod();')
bt(
'{{ "A" }}abc{{ "D" }};\n' +
'{{ "B" }}.test();\n' +
'" {{ "C" \'D\' }} "')
bt(
'{{\n' +
'echo "A";\n' +
'}};\n' +
'test.method();')
bt('"{{";if(0){}"}}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{{$view["name"]; }}};', 'var a = {{{$view["name"]; }}};')
bt(
'a = abc{{{\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'}}};')
test_fragment(
'{{{ }}}\n' +
'test.met{{{ someValue }}}hod();')
bt(
'{{{ "A" }}}abc{{{ "D" }}};\n' +
'{{{ "B" }}}.test();\n' +
'" {{{ "C" \'D\' }}} "')
bt(
'{{{\n' +
'echo "A";\n' +
'}}};\n' +
'test.method();')
bt('"{{{";if(0){}"}}}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{^$view["name"]; }};', 'var a = {{^$view["name"]; }};')
bt(
'a = abc{{^\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'}};')
test_fragment(
'{{^ }}\n' +
'test.met{{^ someValue }}hod();')
bt(
'{{^ "A" }}abc{{^ "D" }};\n' +
'{{^ "B" }}.test();\n' +
'" {{^ "C" \'D\' }} "')
bt(
'{{^\n' +
'echo "A";\n' +
'}};\n' +
'test.method();')
bt('"{{^";if(0){}"}}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{#$view["name"]; }};', 'var a = {{#$view["name"]; }};')
bt(
'a = abc{{#\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'}};')
test_fragment(
'{{# }}\n' +
'test.met{{# someValue }}hod();')
bt(
'{{# "A" }}abc{{# "D" }};\n' +
'{{# "B" }}.test();\n' +
'" {{# "C" \'D\' }} "')
bt(
'{{#\n' +
'echo "A";\n' +
'}};\n' +
'test.method();')
bt('"{{#";if(0){}"}}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{!$view["name"]; }};', 'var a = {{!$view["name"]; }};')
bt(
'a = abc{{!\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'}};')
test_fragment(
'{{! }}\n' +
'test.met{{! someValue }}hod();')
bt(
'{{! "A" }}abc{{! "D" }};\n' +
'{{! "B" }}.test();\n' +
'" {{! "C" \'D\' }} "')
bt(
'{{!\n' +
'echo "A";\n' +
'}};\n' +
'test.method();')
bt('"{{!";if(0){}"}}";')
# minimal template handling - ()
self.reset_options()
self.options.templating = ['django', 'erb', 'handlebars', 'php']
bt('var a = {{!--$view["name"]; --}};', 'var a = {{!--$view["name"]; --}};')
bt(
'a = abc{{!--\n' +
'for($i = 1; $i <= 100; $i++;) {\n' +
' #count to 100!\n' +
' echo($i . "");\n' +
'}\n' +
'--}};')
test_fragment(
'{{!-- --}}\n' +
'test.met{{!-- someValue --}}hod();')
bt(
'{{!-- "A" --}}abc{{!-- "D" --}};\n' +
'{{!-- "B" --}}.test();\n' +
'" {{!-- "C" \'D\' --}} "')
bt(
'{{!--\n' +
'echo "A";\n' +
'--}};\n' +
'test.method();')
bt('"{{!--";if(0){}"--}}";')
#============================================================
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"";',
# -- output --
'"";')
bt(
'"";',
# -- output --
'"=";\n' +
'if (0) {}\n' +
'"?>";')
bt(
'"=";if(0){}',
# -- output --
'"=";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"<%";if(0){}"%>";',
# -- output --
'"<%";\n' +
'if (0) {}\n' +
'"%>";')
bt(
'"<%";if(0){}',
# -- output --
'"<%";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"<%=";if(0){}"%>";',
# -- output --
'"<%=";\n' +
'if (0) {}\n' +
'"%>";')
bt(
'"<%=";if(0){}',
# -- output --
'"<%=";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{";if(0){}"}}";',
# -- output --
'"{{";\n' +
'if (0) {}\n' +
'"}}";')
bt(
'"{{";if(0){}',
# -- output --
'"{{";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{#";if(0){}"#}";',
# -- output --
'"{#";\n' +
'if (0) {}\n' +
'"#}";')
bt(
'"{#";if(0){}',
# -- output --
'"{#";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{%";if(0){}"%}";',
# -- output --
'"{%";\n' +
'if (0) {}\n' +
'"%}";')
bt(
'"{%";if(0){}',
# -- output --
'"{%";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{";if(0){}"}}";',
# -- output --
'"{{";\n' +
'if (0) {}\n' +
'"}}";')
bt(
'"{{";if(0){}',
# -- output --
'"{{";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{{";if(0){}"}}}";',
# -- output --
'"{{{";\n' +
'if (0) {}\n' +
'"}}}";')
bt(
'"{{{";if(0){}',
# -- output --
'"{{{";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{^";if(0){}"}}";',
# -- output --
'"{{^";\n' +
'if (0) {}\n' +
'"}}";')
bt(
'"{{^";if(0){}',
# -- output --
'"{{^";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{#";if(0){}"}}";',
# -- output --
'"{{#";\n' +
'if (0) {}\n' +
'"}}";')
bt(
'"{{#";if(0){}',
# -- output --
'"{{#";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{!";if(0){}"}}";',
# -- output --
'"{{!";\n' +
'if (0) {}\n' +
'"}}";')
bt(
'"{{!";if(0){}',
# -- output --
'"{{!";\n' +
'if (0) {}')
# Templating disabled - ensure formatting - ()
self.reset_options()
self.options.templating = ['auto']
bt(
'"{{!--";if(0){}"--}}";',
# -- output --
'"{{!--";\n' +
'if (0) {}\n' +
'"--}}";')
bt(
'"{{!--";if(0){}',
# -- output --
'"{{!--";\n' +
'if (0) {}')
#============================================================
# jslint and space after anon function - (jslint_happy = "true", space_after_anon_function = "true")
self.reset_options()
self.options.jslint_happy = true
self.options.space_after_anon_function = true
bt(
'a=typeof(x)',
# -- output --
'a = typeof (x)')
bt(
'x();\n' +
'\n' +
'function(){}',
# -- output --
'x();\n' +
'\n' +
'function () {}')
bt(
'x();\n' +
'\n' +
'function y(){}',
# -- output --
'x();\n' +
'\n' +
'function y() {}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function () {}\n' +
'}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function y(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function y() {}\n' +
'}')
bt(
'function () {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}')
bt(
'switch(x) {case 0: case 1: a(); break; default: break}',
# -- output --
'switch (x) {\n' +
'case 0:\n' +
'case 1:\n' +
' a();\n' +
' break;\n' +
'default:\n' +
' break\n' +
'}')
bt(
'switch(x){case -1:break;case !y:break;}',
# -- output --
'switch (x) {\n' +
'case -1:\n' +
' break;\n' +
'case !y:\n' +
' break;\n' +
'}')
# Issue #1357
bt(
'switch(x) {case 0: case 1:{a(); break;} default: break}',
# -- output --
'switch (x) {\n' +
'case 0:\n' +
'case 1: {\n' +
' a();\n' +
' break;\n' +
'}\n' +
'default:\n' +
' break\n' +
'}')
# Issue #1357
bt(
'switch(x){case -1:break;case !y:{break;}}',
# -- output --
'switch (x) {\n' +
'case -1:\n' +
' break;\n' +
'case !y: {\n' +
' break;\n' +
'}\n' +
'}')
# typical greasemonkey start
test_fragment(
'// comment 2\n' +
'(function ()')
bt(
'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function () {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function yoohoo() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function yoohoo() {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function() {},\n' +
'd = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function () {},\n' +
' d = \'\';')
bt(
'var o2=$.extend(a);function(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function () {\n' +
' alert(x);\n' +
'}')
bt(
'var o2=$.extend(a);function yoohoo(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function yoohoo() {\n' +
' alert(x);\n' +
'}')
bt(
'function*() {\n' +
' yield 1;\n' +
'}',
# -- output --
'function* () {\n' +
' yield 1;\n' +
'}')
bt(
'function* yoohoo() {\n' +
' yield 1;\n' +
'}')
bt(
'function* x() {\n' +
' yield 1;\n' +
'}')
bt(
'async x() {\n' +
' yield 1;\n' +
'}')
bt(
'var a={data(){},\n' +
'data2(){}}',
# -- output --
'var a = {\n' +
' data() {},\n' +
' data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'data(){},\n' +
'data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {data(){},\n' +
'data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'}')
bt(
'var a={*data(){},*data2(){}}',
# -- output --
'var a = {\n' +
' * data() {},\n' +
' * data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'*data(){},*data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {*data(){},*data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'}')
# jslint and space after anon function - (jslint_happy = "true", space_after_anon_function = "false")
self.reset_options()
self.options.jslint_happy = true
self.options.space_after_anon_function = false
bt(
'a=typeof(x)',
# -- output --
'a = typeof (x)')
bt(
'x();\n' +
'\n' +
'function(){}',
# -- output --
'x();\n' +
'\n' +
'function () {}')
bt(
'x();\n' +
'\n' +
'function y(){}',
# -- output --
'x();\n' +
'\n' +
'function y() {}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function () {}\n' +
'}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function y(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function y() {}\n' +
'}')
bt(
'function () {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}')
bt(
'switch(x) {case 0: case 1: a(); break; default: break}',
# -- output --
'switch (x) {\n' +
'case 0:\n' +
'case 1:\n' +
' a();\n' +
' break;\n' +
'default:\n' +
' break\n' +
'}')
bt(
'switch(x){case -1:break;case !y:break;}',
# -- output --
'switch (x) {\n' +
'case -1:\n' +
' break;\n' +
'case !y:\n' +
' break;\n' +
'}')
# Issue #1357
bt(
'switch(x) {case 0: case 1:{a(); break;} default: break}',
# -- output --
'switch (x) {\n' +
'case 0:\n' +
'case 1: {\n' +
' a();\n' +
' break;\n' +
'}\n' +
'default:\n' +
' break\n' +
'}')
# Issue #1357
bt(
'switch(x){case -1:break;case !y:{break;}}',
# -- output --
'switch (x) {\n' +
'case -1:\n' +
' break;\n' +
'case !y: {\n' +
' break;\n' +
'}\n' +
'}')
# typical greasemonkey start
test_fragment(
'// comment 2\n' +
'(function ()')
bt(
'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function () {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function yoohoo() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function yoohoo() {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function() {},\n' +
'd = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function () {},\n' +
' d = \'\';')
bt(
'var o2=$.extend(a);function(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function () {\n' +
' alert(x);\n' +
'}')
bt(
'var o2=$.extend(a);function yoohoo(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function yoohoo() {\n' +
' alert(x);\n' +
'}')
bt(
'function*() {\n' +
' yield 1;\n' +
'}',
# -- output --
'function* () {\n' +
' yield 1;\n' +
'}')
bt(
'function* yoohoo() {\n' +
' yield 1;\n' +
'}')
bt(
'function* x() {\n' +
' yield 1;\n' +
'}')
bt(
'async x() {\n' +
' yield 1;\n' +
'}')
bt(
'var a={data(){},\n' +
'data2(){}}',
# -- output --
'var a = {\n' +
' data() {},\n' +
' data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'data(){},\n' +
'data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {data(){},\n' +
'data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'}')
bt(
'var a={*data(){},*data2(){}}',
# -- output --
'var a = {\n' +
' * data() {},\n' +
' * data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'*data(){},*data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {*data(){},*data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'}')
# jslint and space after anon function - (jslint_happy = "false", space_after_anon_function = "true")
self.reset_options()
self.options.jslint_happy = false
self.options.space_after_anon_function = true
bt(
'a=typeof(x)',
# -- output --
'a = typeof (x)')
bt(
'x();\n' +
'\n' +
'function(){}',
# -- output --
'x();\n' +
'\n' +
'function () {}')
bt(
'x();\n' +
'\n' +
'function y(){}',
# -- output --
'x();\n' +
'\n' +
'function y() {}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function () {}\n' +
'}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function y(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function y() {}\n' +
'}')
bt(
'function () {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}')
bt(
'switch(x) {case 0: case 1: a(); break; default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1:\n' +
' a();\n' +
' break;\n' +
' default:\n' +
' break\n' +
'}')
bt(
'switch(x){case -1:break;case !y:break;}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y:\n' +
' break;\n' +
'}')
# Issue #1357
bt(
'switch(x) {case 0: case 1:{a(); break;} default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1: {\n' +
' a();\n' +
' break;\n' +
' }\n' +
' default:\n' +
' break\n' +
'}')
# Issue #1357
bt(
'switch(x){case -1:break;case !y:{break;}}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y: {\n' +
' break;\n' +
' }\n' +
'}')
# typical greasemonkey start
test_fragment(
'// comment 2\n' +
'(function ()')
bt(
'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function () {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function yoohoo() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function yoohoo() {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function() {},\n' +
'd = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function () {},\n' +
' d = \'\';')
bt(
'var o2=$.extend(a);function(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function () {\n' +
' alert(x);\n' +
'}')
bt(
'var o2=$.extend(a);function yoohoo(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function yoohoo() {\n' +
' alert(x);\n' +
'}')
bt(
'function*() {\n' +
' yield 1;\n' +
'}',
# -- output --
'function* () {\n' +
' yield 1;\n' +
'}')
bt(
'function* yoohoo() {\n' +
' yield 1;\n' +
'}')
bt(
'function* x() {\n' +
' yield 1;\n' +
'}')
bt(
'async x() {\n' +
' yield 1;\n' +
'}')
bt(
'var a={data(){},\n' +
'data2(){}}',
# -- output --
'var a = {\n' +
' data() {},\n' +
' data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'data(){},\n' +
'data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {data(){},\n' +
'data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'}')
bt(
'var a={*data(){},*data2(){}}',
# -- output --
'var a = {\n' +
' * data() {},\n' +
' * data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'*data(){},*data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {*data(){},*data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'}')
# jslint and space after anon function - (jslint_happy = "false", space_after_anon_function = "false")
self.reset_options()
self.options.jslint_happy = false
self.options.space_after_anon_function = false
bt(
'a=typeof(x)',
# -- output --
'a = typeof(x)')
bt(
'x();\n' +
'\n' +
'function(){}',
# -- output --
'x();\n' +
'\n' +
'function() {}')
bt(
'x();\n' +
'\n' +
'function y(){}',
# -- output --
'x();\n' +
'\n' +
'function y() {}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function() {}\n' +
'}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function y(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function y() {}\n' +
'}')
bt(
'function () {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}',
# -- output --
'function() {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}')
bt(
'switch(x) {case 0: case 1: a(); break; default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1:\n' +
' a();\n' +
' break;\n' +
' default:\n' +
' break\n' +
'}')
bt(
'switch(x){case -1:break;case !y:break;}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y:\n' +
' break;\n' +
'}')
# Issue #1357
bt(
'switch(x) {case 0: case 1:{a(); break;} default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1: {\n' +
' a();\n' +
' break;\n' +
' }\n' +
' default:\n' +
' break\n' +
'}')
# Issue #1357
bt(
'switch(x){case -1:break;case !y:{break;}}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y: {\n' +
' break;\n' +
' }\n' +
'}')
# typical greasemonkey start
test_fragment(
'// comment 2\n' +
'(function()')
bt(
'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function() {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function yoohoo() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function yoohoo() {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function() {},\n' +
'd = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function() {},\n' +
' d = \'\';')
bt(
'var o2=$.extend(a);function(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function() {\n' +
' alert(x);\n' +
'}')
bt(
'var o2=$.extend(a);function yoohoo(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function yoohoo() {\n' +
' alert(x);\n' +
'}')
bt(
'function*() {\n' +
' yield 1;\n' +
'}')
bt(
'function* yoohoo() {\n' +
' yield 1;\n' +
'}')
bt(
'function* x() {\n' +
' yield 1;\n' +
'}')
bt(
'async x() {\n' +
' yield 1;\n' +
'}')
bt(
'var a={data(){},\n' +
'data2(){}}',
# -- output --
'var a = {\n' +
' data() {},\n' +
' data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'data(){},\n' +
'data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {data(){},\n' +
'data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' data() {},\n' +
' data2() {},\n' +
' a: 1\n' +
'}')
bt(
'var a={*data(){},*data2(){}}',
# -- output --
'var a = {\n' +
' * data() {},\n' +
' * data2() {}\n' +
'}')
bt(
'new Vue({\n' +
'*data(){},*data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'})')
bt(
'export default {*data(){},*data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' * data() {},\n' +
' * data2() {},\n' +
' a: 1\n' +
'}')
# jslint and space after anon function - (space_after_named_function = "true")
self.reset_options()
self.options.space_after_named_function = true
bt(
'a=typeof(x)',
# -- output --
'a = typeof(x)')
bt(
'x();\n' +
'\n' +
'function(){}',
# -- output --
'x();\n' +
'\n' +
'function() {}')
bt(
'x();\n' +
'\n' +
'function y(){}',
# -- output --
'x();\n' +
'\n' +
'function y () {}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function() {}\n' +
'}')
bt(
'x();\n' +
'\n' +
'var x = {\n' +
'x: function y(){}\n' +
'}',
# -- output --
'x();\n' +
'\n' +
'var x = {\n' +
' x: function y () {}\n' +
'}')
bt(
'function () {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}',
# -- output --
'function() {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}')
bt(
'switch(x) {case 0: case 1: a(); break; default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1:\n' +
' a();\n' +
' break;\n' +
' default:\n' +
' break\n' +
'}')
bt(
'switch(x){case -1:break;case !y:break;}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y:\n' +
' break;\n' +
'}')
# Issue #1357
bt(
'switch(x) {case 0: case 1:{a(); break;} default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1: {\n' +
' a();\n' +
' break;\n' +
' }\n' +
' default:\n' +
' break\n' +
'}')
# Issue #1357
bt(
'switch(x){case -1:break;case !y:{break;}}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y: {\n' +
' break;\n' +
' }\n' +
'}')
# typical greasemonkey start
test_fragment(
'// comment 2\n' +
'(function()')
bt(
'var a2, b2, c2, d2 = 0, c = function() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function() {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function yoohoo() {}, d = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function yoohoo () {},\n' +
' d = \'\';')
bt(
'var a2, b2, c2, d2 = 0, c = function() {},\n' +
'd = \'\';',
# -- output --
'var a2, b2, c2, d2 = 0,\n' +
' c = function() {},\n' +
' d = \'\';')
bt(
'var o2=$.extend(a);function(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function() {\n' +
' alert(x);\n' +
'}')
bt(
'var o2=$.extend(a);function yoohoo(){alert(x);}',
# -- output --
'var o2 = $.extend(a);\n' +
'\n' +
'function yoohoo () {\n' +
' alert(x);\n' +
'}')
bt(
'function*() {\n' +
' yield 1;\n' +
'}')
bt(
'function* yoohoo() {\n' +
' yield 1;\n' +
'}',
# -- output --
'function* yoohoo () {\n' +
' yield 1;\n' +
'}')
bt(
'function* x() {\n' +
' yield 1;\n' +
'}',
# -- output --
'function* x () {\n' +
' yield 1;\n' +
'}')
bt(
'async x() {\n' +
' yield 1;\n' +
'}',
# -- output --
'async x () {\n' +
' yield 1;\n' +
'}')
bt(
'var a={data(){},\n' +
'data2(){}}',
# -- output --
'var a = {\n' +
' data () {},\n' +
' data2 () {}\n' +
'}')
bt(
'new Vue({\n' +
'data(){},\n' +
'data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' data () {},\n' +
' data2 () {},\n' +
' a: 1\n' +
'})')
bt(
'export default {data(){},\n' +
'data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' data () {},\n' +
' data2 () {},\n' +
' a: 1\n' +
'}')
bt(
'var a={*data(){},*data2(){}}',
# -- output --
'var a = {\n' +
' * data () {},\n' +
' * data2 () {}\n' +
'}')
bt(
'new Vue({\n' +
'*data(){},*data2(){}, a:1})',
# -- output --
'new Vue({\n' +
' * data () {},\n' +
' * data2 () {},\n' +
' a: 1\n' +
'})')
bt(
'export default {*data(){},*data2(){},\n' +
'a:1}',
# -- output --
'export default {\n' +
' * data () {},\n' +
' * data2 () {},\n' +
' a: 1\n' +
'}')
#============================================================
# Regression tests
self.reset_options()
# Issue 241
bt(
'obj\n' +
' .last({\n' +
' foo: 1,\n' +
' bar: 2\n' +
' });\n' +
'var test = 1;')
# Issue #1663
bt(
'{\n' +
' /* howdy\n' +
' \n' +
' */\n' +
'}')
bt(
'obj\n' +
' .last(a, function() {\n' +
' var test;\n' +
' });\n' +
'var test = 1;')
bt(
'obj.first()\n' +
' .second()\n' +
' .last(function(err, response) {\n' +
' console.log(err);\n' +
' });')
# Issue 268 and 275
bt(
'obj.last(a, function() {\n' +
' var test;\n' +
'});\n' +
'var test = 1;')
bt(
'obj.last(a,\n' +
' function() {\n' +
' var test;\n' +
' });\n' +
'var test = 1;')
bt(
'(function() {if (!window.FOO) window.FOO || (window.FOO = function() {var b = {bar: "zort"};});})();',
# -- output --
'(function() {\n' +
' if (!window.FOO) window.FOO || (window.FOO = function() {\n' +
' var b = {\n' +
' bar: "zort"\n' +
' };\n' +
' });\n' +
'})();')
# Issue 281
bt(
'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",\n' +
' "dojo/_base/lang", "dojo/Deferred"\n' +
'], function(declare, Employee, Button, lang, Deferred) {\n' +
' return declare(Employee, {\n' +
' constructor: function() {\n' +
' new Button({\n' +
' onClick: lang.hitch(this, function() {\n' +
' new Deferred().then(lang.hitch(this, function() {\n' +
' this.salary * 0.25;\n' +
' }));\n' +
' })\n' +
' });\n' +
' }\n' +
' });\n' +
'});')
bt(
'define(["dojo/_base/declare", "my/Employee", "dijit/form/Button",\n' +
' "dojo/_base/lang", "dojo/Deferred"\n' +
' ],\n' +
' function(declare, Employee, Button, lang, Deferred) {\n' +
' return declare(Employee, {\n' +
' constructor: function() {\n' +
' new Button({\n' +
' onClick: lang.hitch(this, function() {\n' +
' new Deferred().then(lang.hitch(this, function() {\n' +
' this.salary * 0.25;\n' +
' }));\n' +
' })\n' +
' });\n' +
' }\n' +
' });\n' +
' });')
# Issue 459
bt(
'(function() {\n' +
' return {\n' +
' foo: function() {\n' +
' return "bar";\n' +
' },\n' +
' bar: ["bar"]\n' +
' };\n' +
'}());')
# Issue 505 - strings should end at newline unless continued by backslash
bt(
'var name = "a;\n' +
'name = "b";')
bt(
'var name = "a;\\\n' +
' name = b";')
# Issue 514 - some operators require spaces to distinguish them
bt('var c = "_ACTION_TO_NATIVEAPI_" + ++g++ + +new Date;')
bt('var c = "_ACTION_TO_NATIVEAPI_" - --g-- - -new Date;')
# Issue 440 - reserved words can be used as object property names
bt(
'a = {\n' +
' function: {},\n' +
' "function": {},\n' +
' throw: {},\n' +
' "throw": {},\n' +
' var: {},\n' +
' "var": {},\n' +
' set: {},\n' +
' "set": {},\n' +
' get: {},\n' +
' "get": {},\n' +
' if: {},\n' +
' "if": {},\n' +
' then: {},\n' +
' "then": {},\n' +
' else: {},\n' +
' "else": {},\n' +
' yay: {}\n' +
'};')
# Issue 331 - if-else with braces edge case
bt(
'if(x){a();}else{b();}if(y){c();}',
# -- output --
'if (x) {\n' +
' a();\n' +
'} else {\n' +
' b();\n' +
'}\n' +
'if (y) {\n' +
' c();\n' +
'}')
# Issue 485 - ensure function declarations behave the same in arrays as elsewhere
bt(
'var v = ["a",\n' +
' function() {\n' +
' return;\n' +
' }, {\n' +
' id: 1\n' +
' }\n' +
'];')
bt(
'var v = ["a", function() {\n' +
' return;\n' +
'}, {\n' +
' id: 1\n' +
'}];')
# Issue 382 - initial totally cursory support for es6 module export
bt(
'module "Even" {\n' +
' import odd from "Odd";\n' +
' export function sum(x, y) {\n' +
' return x + y;\n' +
' }\n' +
' export var pi = 3.141593;\n' +
' export default moduleName;\n' +
'}')
bt(
'module "Even" {\n' +
' export default function div(x, y) {}\n' +
'}')
# Issue 889 - export default { ... }
bt(
'export default {\n' +
' func1() {},\n' +
' func2() {}\n' +
' func3() {}\n' +
'}')
bt(
'export default {\n' +
' a() {\n' +
' return 1;\n' +
' },\n' +
' b() {\n' +
' return 2;\n' +
' },\n' +
' c() {\n' +
' return 3;\n' +
' }\n' +
'}')
# Issue 508
bt('set["name"]')
bt('get["name"]')
test_fragment(
'a = {\n' +
' set b(x) {},\n' +
' c: 1,\n' +
' d: function() {}\n' +
'};')
test_fragment(
'a = {\n' +
' get b() {\n' +
' retun 0;\n' +
' },\n' +
' c: 1,\n' +
' d: function() {}\n' +
'};')
# Issue 298 - do not under indent if/while/for condtionals experesions
bt(
'\'use strict\';\n' +
'if ([].some(function() {\n' +
' return false;\n' +
' })) {\n' +
' console.log("hello");\n' +
'}')
# Issue 298 - do not under indent if/while/for condtionals experesions
bt(
'\'use strict\';\n' +
'if ([].some(function() {\n' +
' return false;\n' +
' })) {\n' +
' console.log("hello");\n' +
'}')
# Issue 552 - Typescript? Okay... we didn't break it before, so try not to break it now.
bt(
'class Test {\n' +
' blah: string[];\n' +
' foo(): number {\n' +
' return 0;\n' +
' }\n' +
' bar(): number {\n' +
' return 0;\n' +
' }\n' +
'}')
# Issue 1544 - Typescript declare formatting (no newline).
bt(
'declare const require: any;\n' +
'declare function greet(greeting: string): void;\n' +
'declare var foo: number;\n' +
'declare namespace myLib {\n' +
' function makeGreeting(s: string): string;\n' +
' let numberOfGreetings: number;\n' +
'}\n' +
'declare let test: any;')
bt(
'interface Test {\n' +
' blah: string[];\n' +
' foo(): number {\n' +
' return 0;\n' +
' }\n' +
' bar(): number {\n' +
' return 0;\n' +
' }\n' +
'}')
# Issue 583 - Functions with comments after them should still indent correctly.
bt(
'function exit(code) {\n' +
' setTimeout(function() {\n' +
' phantom.exit(code);\n' +
' }, 0);\n' +
' phantom.onError = function() {};\n' +
'}\n' +
'// Comment')
# Issue 806 - newline arrow functions
bt(
'a.b("c",\n' +
' () => d.e\n' +
')')
# Issue 810 - es6 object literal detection
bt(
'function badFormatting() {\n' +
' return {\n' +
' a,\n' +
' b: c,\n' +
' d: e,\n' +
' f: g,\n' +
' h,\n' +
' i,\n' +
' j: k\n' +
' }\n' +
'}\n' +
'\n' +
'function goodFormatting() {\n' +
' return {\n' +
' a: b,\n' +
' c,\n' +
' d: e,\n' +
' f: g,\n' +
' h,\n' +
' i,\n' +
' j: k\n' +
' }\n' +
'}')
# Issue 602 - ES6 object literal shorthand functions
bt(
'return {\n' +
' fn1() {},\n' +
' fn2() {}\n' +
'}')
bt(
'throw {\n' +
' fn1() {},\n' +
' fn2() {}\n' +
'}')
bt(
'foo({\n' +
' fn1(a) {}\n' +
' fn2(a) {}\n' +
'})')
bt(
'foo("text", {\n' +
' fn1(a) {}\n' +
' fn2(a) {}\n' +
'})')
bt(
'oneArg = {\n' +
' fn1(a) {\n' +
' do();\n' +
' },\n' +
' fn2() {}\n' +
'}')
bt(
'multiArg = {\n' +
' fn1(a, b, c) {\n' +
' do();\n' +
' },\n' +
' fn2() {}\n' +
'}')
bt(
'noArgs = {\n' +
' fn1() {\n' +
' do();\n' +
' },\n' +
' fn2() {}\n' +
'}')
bt(
'emptyFn = {\n' +
' fn1() {},\n' +
' fn2() {}\n' +
'}')
bt(
'nested = {\n' +
' fns: {\n' +
' fn1() {},\n' +
' fn2() {}\n' +
' }\n' +
'}')
bt(
'array = [{\n' +
' fn1() {},\n' +
' prop: val,\n' +
' fn2() {}\n' +
'}]')
bt(
'expr = expr ? expr : {\n' +
' fn1() {},\n' +
' fn2() {}\n' +
'}')
bt(
'strange = valid + {\n' +
' fn1() {},\n' +
' fn2() {\n' +
' return 1;\n' +
' }\n' +
'}.fn2()')
# Issue 854 - Arrow function with statement block
bt(
'test(() => {\n' +
' var a = {}\n' +
'\n' +
' a.what = () => true ? 1 : 2\n' +
'\n' +
' a.thing = () => {\n' +
' b();\n' +
' }\n' +
'})')
# Issue 406 - Multiline array
bt(
'var tempName = [\n' +
' "temp",\n' +
' process.pid,\n' +
' (Math.random() * 0x1000000000).toString(36),\n' +
' new Date().getTime()\n' +
'].join("-");')
# Issue 1374 - Parameters starting with ! or [ merged into single line
bt(
'fn(\n' +
' 1,\n' +
' !1,\n' +
' 1,\n' +
' [1]\n' +
')')
# Issue 1288 - Negative numbers remove newlines in array
bt(
'var array = [\n' +
' -1,\n' +
' 0,\n' +
' "a",\n' +
' -2,\n' +
' 1,\n' +
' -3,\n' +
'];')
# Issue 1229 - Negated expressions in array
bt(
'a = [\n' +
' true && 1,\n' +
' true && 1,\n' +
' true && 1\n' +
']\n' +
'a = [\n' +
' !true && 1,\n' +
' !true && 1,\n' +
' !true && 1\n' +
']')
# Issue #996 - Input ends with backslash throws exception
test_fragment(
'sd = 1;\n' +
'/')
# Issue #1079 - unbraced if with comments should still look right
bt(
'if (console.log)\n' +
' for (var i = 0; i < 20; ++i)\n' +
' if (i % 3)\n' +
' console.log(i);\n' +
'// all done\n' +
'console.log("done");')
# Issue #1085 - function should not have blank line in a number of cases
bt(
'var transformer =\n' +
' options.transformer ||\n' +
' globalSettings.transformer ||\n' +
' function(x) {\n' +
' return x;\n' +
' };')
# Issue #569 - function should not have blank line in a number of cases
bt(
'(function(global) {\n' +
' "use strict";\n' +
'\n' +
' /* jshint ignore:start */\n' +
' include "somefile.js"\n' +
' /* jshint ignore:end */\n' +
'}(this));')
bt(
'function bindAuthEvent(eventName) {\n' +
' self.auth.on(eventName, function(event, meta) {\n' +
' self.emit(eventName, event, meta);\n' +
' });\n' +
'}\n' +
'["logged_in", "logged_out", "signed_up", "updated_user"].forEach(bindAuthEvent);\n' +
'\n' +
'function bindBrowserEvent(eventName) {\n' +
' browser.on(eventName, function(event, meta) {\n' +
' self.emit(eventName, event, meta);\n' +
' });\n' +
'}\n' +
'["navigating"].forEach(bindBrowserEvent);')
# Issue #892 - new line between chained methods
bt(
'foo\n' +
' .who()\n' +
'\n' +
' .knows()\n' +
' // comment\n' +
' .nothing() // comment\n' +
'\n' +
' .more()')
# Issue #1107 - Missing space between words for label
bt(
'function f(a) {c: do if (x) {} else if (y) {} while(0); return 0;}',
# -- output --
'function f(a) {\n' +
' c: do\n' +
' if (x) {} else if (y) {}\n' +
' while (0);\n' +
' return 0;\n' +
'}')
bt(
'function f(a) {c: if (x) {} else if (y) {} return 0;}',
# -- output --
'function f(a) {\n' +
' c: if (x) {} else if (y) {}\n' +
' return 0;\n' +
'}')
#============================================================
# Test non-positionable-ops
self.reset_options()
bt('a += 2;')
bt('a -= 2;')
bt('a *= 2;')
bt('a /= 2;')
bt('a %= 2;')
bt('a &= 2;')
bt('a ^= 2;')
bt('a |= 2;')
bt('a **= 2;')
bt('a <<= 2;')
bt('a >>= 2;')
#============================================================
#
self.reset_options()
# exponent literals
bt('a = 1e10')
bt('a = 1.3e10')
bt('a = 1.3e-10')
bt('a = -12345.3e-10')
bt('a = .12345e-10')
bt('a = 06789e-10')
bt('a = e - 10')
bt('a = 1.3e+10')
bt('a = 1.e-7')
bt('a = -12345.3e+10')
bt('a = .12345e+10')
bt('a = 06789e+10')
bt('a = e + 10')
bt('a=0e-12345.3e-10', 'a = 0e-12345 .3e-10')
bt('a=0.e-12345.3e-10', 'a = 0.e-12345 .3e-10')
bt('a=0x.e-12345.3e-10', 'a = 0x.e - 12345.3e-10')
bt('a=0x0.e-12345.3e-10', 'a = 0x0.e - 12345.3e-10')
bt('a=0x0.0e-12345.3e-10', 'a = 0x0 .0e-12345 .3e-10')
bt('a=0g-12345.3e-10', 'a = 0 g - 12345.3e-10')
bt('a=0.g-12345.3e-10', 'a = 0. g - 12345.3e-10')
bt('a=0x.g-12345.3e-10', 'a = 0x.g - 12345.3e-10')
bt('a=0x0.g-12345.3e-10', 'a = 0x0.g - 12345.3e-10')
bt('a=0x0.0g-12345.3e-10', 'a = 0x0 .0 g - 12345.3e-10')
# Decimal literals
bt('a = 0123456789;')
bt('a = 9876543210;')
bt('a = 5647308291;')
bt('a=030e-5', 'a = 030e-5')
bt('a=00+4', 'a = 00 + 4')
bt('a=32+4', 'a = 32 + 4')
bt('a=0.6g+4', 'a = 0.6 g + 4')
bt('a=01.10', 'a = 01.10')
bt('a=a.10', 'a = a .10')
bt('a=00B0x0', 'a = 00 B0x0')
bt('a=00B0xb0', 'a = 00 B0xb0')
bt('a=00B0x0b0', 'a = 00 B0x0b0')
bt('a=0090x0', 'a = 0090 x0')
bt('a=0g0b0o0', 'a = 0 g0b0o0')
# Hexadecimal literals
bt('a = 0x0123456789abcdef;')
bt('a = 0X0123456789ABCDEF;')
bt('a = 0xFeDcBa9876543210;')
bt('a=0x30e-5', 'a = 0x30e - 5')
bt('a=0xF0+4', 'a = 0xF0 + 4')
bt('a=0Xff+4', 'a = 0Xff + 4')
bt('a=0Xffg+4', 'a = 0Xff g + 4')
bt('a=0x01.10', 'a = 0x01 .10')
bt('a = 0xb0ce;')
bt('a = 0x0b0;')
bt('a=0x0B0x0', 'a = 0x0B0 x0')
bt('a=0x0B0xb0', 'a = 0x0B0 xb0')
bt('a=0x0B0x0b0', 'a = 0x0B0 x0b0')
bt('a=0X090x0', 'a = 0X090 x0')
bt('a=0Xg0b0o0', 'a = 0X g0b0o0')
# Octal literals
bt('a = 0o01234567;')
bt('a = 0O01234567;')
bt('a = 0o34120675;')
bt('a=0o30e-5', 'a = 0o30 e - 5')
bt('a=0o70+4', 'a = 0o70 + 4')
bt('a=0O77+4', 'a = 0O77 + 4')
bt('a=0O778+4', 'a = 0O77 8 + 4')
bt('a=0O77a+4', 'a = 0O77 a + 4')
bt('a=0o01.10', 'a = 0o01 .10')
bt('a=0o0B0x0', 'a = 0o0 B0x0')
bt('a=0o0B0xb0', 'a = 0o0 B0xb0')
bt('a=0o0B0x0b0', 'a = 0o0 B0x0b0')
bt('a=0O090x0', 'a = 0O0 90 x0')
bt('a=0Og0b0o0', 'a = 0O g0b0o0')
# Binary literals
bt('a = 0b010011;')
bt('a = 0B010011;')
bt('a = 0b01001100001111;')
bt('a=0b10e-5', 'a = 0b10 e - 5')
bt('a=0b10+4', 'a = 0b10 + 4')
bt('a=0B11+4', 'a = 0B11 + 4')
bt('a=0B112+4', 'a = 0B11 2 + 4')
bt('a=0B11a+4', 'a = 0B11 a + 4')
bt('a=0b01.10', 'a = 0b01 .10')
bt('a=0b0B0x0', 'a = 0b0 B0x0')
bt('a=0b0B0xb0', 'a = 0b0 B0xb0')
bt('a=0b0B0x0b0', 'a = 0b0 B0x0b0')
bt('a=0B090x0', 'a = 0B0 90 x0')
bt('a=0Bg0b0o0', 'a = 0B g0b0o0')
# BigInt literals
bt('a = 1n;')
bt('a = 1234567890123456789n;')
bt('a = -1234567890123456789n;')
bt('a = 1234567890123456789 N;')
bt('a=0b10e-5n', 'a = 0b10 e - 5n')
bt('a=.0n', 'a = .0 n')
bt('a=1.0n', 'a = 1.0 n')
bt('a=1e0n', 'a = 1e0 n')
bt('a=0n11a+4', 'a = 0n 11 a + 4')
#============================================================
# brace_style ,preserve-inline tests - (brace_style = ""collapse,preserve-inline"")
self.reset_options()
self.options.brace_style = 'collapse,preserve-inline'
bt('import { asdf } from "asdf";')
bt('import { get } from "asdf";')
bt('function inLine() { console.log("oh em gee"); }')
bt('if (cancer) { console.log("Im sorry but you only have so long to live..."); }')
bt('if (ding) { console.log("dong"); } else { console.log("dang"); }')
bt(
'function kindaComplex() {\n' +
' var a = 2;\n' +
' var obj = {};\n' +
' var obj2 = { a: "a", b: "b" };\n' +
' var obj3 = {\n' +
' c: "c",\n' +
' d: "d",\n' +
' e: "e"\n' +
' };\n' +
'}')
bt(
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}',
# -- output --
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}')
# brace_style ,preserve-inline tests - (brace_style = ""expand,preserve-inline"")
self.reset_options()
self.options.brace_style = 'expand,preserve-inline'
bt('import { asdf } from "asdf";')
bt('import { get } from "asdf";')
bt('function inLine() { console.log("oh em gee"); }')
bt('if (cancer) { console.log("Im sorry but you only have so long to live..."); }')
bt(
'if (ding) { console.log("dong"); } else { console.log("dang"); }',
# -- output --
'if (ding) { console.log("dong"); }\n' +
'else { console.log("dang"); }')
bt(
'function kindaComplex() {\n' +
' var a = 2;\n' +
' var obj = {};\n' +
' var obj2 = { a: "a", b: "b" };\n' +
' var obj3 = {\n' +
' c: "c",\n' +
' d: "d",\n' +
' e: "e"\n' +
' };\n' +
'}',
# -- output --
'function kindaComplex()\n' +
'{\n' +
' var a = 2;\n' +
' var obj = {};\n' +
' var obj2 = { a: "a", b: "b" };\n' +
' var obj3 = {\n' +
' c: "c",\n' +
' d: "d",\n' +
' e: "e"\n' +
' };\n' +
'}')
bt(
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}',
# -- output --
'function complex()\n' +
'{\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b()\n' +
' {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}')
# brace_style ,preserve-inline tests - (brace_style = ""end-expand,preserve-inline"")
self.reset_options()
self.options.brace_style = 'end-expand,preserve-inline'
bt('import { asdf } from "asdf";')
bt('import { get } from "asdf";')
bt('function inLine() { console.log("oh em gee"); }')
bt('if (cancer) { console.log("Im sorry but you only have so long to live..."); }')
bt(
'if (ding) { console.log("dong"); } else { console.log("dang"); }',
# -- output --
'if (ding) { console.log("dong"); }\n' +
'else { console.log("dang"); }')
bt(
'function kindaComplex() {\n' +
' var a = 2;\n' +
' var obj = {};\n' +
' var obj2 = { a: "a", b: "b" };\n' +
' var obj3 = {\n' +
' c: "c",\n' +
' d: "d",\n' +
' e: "e"\n' +
' };\n' +
'}')
bt(
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}',
# -- output --
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}')
# brace_style ,preserve-inline tests - (brace_style = ""none,preserve-inline"")
self.reset_options()
self.options.brace_style = 'none,preserve-inline'
bt('import { asdf } from "asdf";')
bt('import { get } from "asdf";')
bt('function inLine() { console.log("oh em gee"); }')
bt('if (cancer) { console.log("Im sorry but you only have so long to live..."); }')
bt('if (ding) { console.log("dong"); } else { console.log("dang"); }')
bt(
'function kindaComplex() {\n' +
' var a = 2;\n' +
' var obj = {};\n' +
' var obj2 = { a: "a", b: "b" };\n' +
' var obj3 = {\n' +
' c: "c",\n' +
' d: "d",\n' +
' e: "e"\n' +
' };\n' +
'}')
bt(
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}',
# -- output --
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}')
# brace_style ,preserve-inline tests - (brace_style = ""collapse-preserve-inline"")
self.reset_options()
self.options.brace_style = 'collapse-preserve-inline'
bt('import { asdf } from "asdf";')
bt('import { get } from "asdf";')
bt('function inLine() { console.log("oh em gee"); }')
bt('if (cancer) { console.log("Im sorry but you only have so long to live..."); }')
bt('if (ding) { console.log("dong"); } else { console.log("dang"); }')
bt(
'function kindaComplex() {\n' +
' var a = 2;\n' +
' var obj = {};\n' +
' var obj2 = { a: "a", b: "b" };\n' +
' var obj3 = {\n' +
' c: "c",\n' +
' d: "d",\n' +
' e: "e"\n' +
' };\n' +
'}')
bt(
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}',
# -- output --
'function complex() {\n' +
' console.log("wowe");\n' +
' (function() { var a = 2; var b = 3; })();\n' +
' $.each(arr, function(el, idx) { return el; });\n' +
' var obj = {\n' +
' a: function() { console.log("test"); },\n' +
' b() {\n' +
' console.log("test2");\n' +
' }\n' +
' };\n' +
'}')
#============================================================
# Destructured and related
self.reset_options()
self.options.brace_style = 'collapse,preserve-inline'
# Issue 382 - import destructured
bt(
'module "Even" {\n' +
' import { odd, oddly } from "Odd";\n' +
'}')
bt(
'import defaultMember from "module-name";\n' +
'import * as name from "module-name";\n' +
'import { member } from "module-name";\n' +
'import { member as alias } from "module-name";\n' +
'import { member1, member2 } from "module-name";\n' +
'import { member1, member2 as alias2 } from "module-name";\n' +
'import defaultMember, { member, member2 } from "module-name";\n' +
'import defaultMember, * as name from "module-name";\n' +
'import "module-name";\n' +
'import("module-name")')
# Issue #1393 - dynamic import()
bt(
'if (from < to) {\n' +
' import(`dynamic${library}`);\n' +
'} else {\n' +
' import("otherdynamic");\n' +
'}')
# Issue #1197 - dynamic import() arrow syntax
bt('frontend = Async(() => import("../frontend").then(m => m.default ))', 'frontend = Async(() => import("../frontend").then(m => m.default))')
# Issue 858 - from is a keyword only after import
bt(
'if (from < to) {\n' +
' from++;\n' +
'} else {\n' +
' from--;\n' +
'}')
# Issue 511 - destrutured
bt(
'var { b, c } = require("../stores");\n' +
'var { ProjectStore } = require("../stores");\n' +
'\n' +
'function takeThing({ prop }) {\n' +
' console.log("inner prop", prop)\n' +
'}')
# Issue 315 - Short objects
bt('var a = { b: { c: { d: e } } };')
bt(
'var a = {\n' +
' b: {\n' +
' c: { d: e }\n' +
' c3: { d: e }\n' +
' },\n' +
' b2: { c: { d: e } }\n' +
'};')
# Issue 370 - Short objects in array
bt(
'var methods = [\n' +
' { name: "to" },\n' +
' { name: "step" },\n' +
' { name: "move" },\n' +
' { name: "min" },\n' +
' { name: "max" }\n' +
'];')
# Issue 838 - Short objects in array
bt(
'function(url, callback) {\n' +
' var script = document.createElement("script")\n' +
' if (true) script.onreadystatechange = function() {\n' +
' foo();\n' +
' }\n' +
' else script.onload = callback;\n' +
'}')
# Issue 578 - Odd indenting after function
bt(
'function bindAuthEvent(eventName) {\n' +
' self.auth.on(eventName, function(event, meta) {\n' +
' self.emit(eventName, event, meta);\n' +
' });\n' +
'}\n' +
'["logged_in", "logged_out", "signed_up", "updated_user"].forEach(bindAuthEvent);')
# Issue #487 - some short expressions examples
bt(
'if (a == 1) { a++; }\n' +
'a = { a: a };\n' +
'UserDB.findOne({ username: "xyz" }, function(err, user) {});\n' +
'import { fs } from "fs";')
# Issue #982 - Fixed return expression collapse-preserve-inline
bt(
'function foo(arg) {\n' +
' if (!arg) { a(); }\n' +
' if (!arg) { return false; }\n' +
' if (!arg) { throw "inline"; }\n' +
' return true;\n' +
'}')
# Issue #338 - Short expressions
bt(
'if (someCondition) { return something; }\n' +
'if (someCondition) {\n' +
' return something;\n' +
'}\n' +
'if (someCondition) { break; }\n' +
'if (someCondition) {\n' +
' return something;\n' +
'}')
# Issue #1283 - Javascript ++ Operator get wrong indent
bt(
'{this.foo++\n' +
'bar}',
# -- output --
'{\n' +
' this.foo++\n' +
' bar\n' +
'}')
# Issue #1283 - Javascript ++ Operator get wrong indent (2)
bt(
'axios.interceptors.request.use(\n' +
' config => {\n' +
' // loading\n' +
' window.store.loading++\n' +
' let extraParams = {}\n' +
' }\n' +
')')
#============================================================
# keep_array_indentation false
self.reset_options()
self.options.keep_array_indentation = false
bt(
'a = ["a", "b", "c",\n' +
' "d", "e", "f"]',
# -- output --
'a = ["a", "b", "c",\n' +
' "d", "e", "f"\n' +
']')
bt(
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"]',
# -- output --
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"\n' +
']')
bt(
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"]',
# -- output --
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"\n' +
']')
bt(
'var x = [{}\n' +
']',
# -- output --
'var x = [{}]')
bt(
'var x = [{foo:bar}\n' +
']',
# -- output --
'var x = [{\n' +
' foo: bar\n' +
'}]')
bt(
'a = ["something",\n' +
' "completely",\n' +
' "different"];\n' +
'if (x);',
# -- output --
'a = ["something",\n' +
' "completely",\n' +
' "different"\n' +
'];\n' +
'if (x);')
bt('a = ["a","b","c"]', 'a = ["a", "b", "c"]')
bt('a = ["a", "b","c"]', 'a = ["a", "b", "c"]')
bt(
'x = [{"a":0}]',
# -- output --
'x = [{\n' +
' "a": 0\n' +
'}]')
bt(
'{a([[a1]], {b;});}',
# -- output --
'{\n' +
' a([\n' +
' [a1]\n' +
' ], {\n' +
' b;\n' +
' });\n' +
'}')
bt(
'a ();\n' +
' [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ].toString();',
# -- output --
'a();\n' +
'[\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
'].toString();')
bt(
'a ();\n' +
'a = [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ].toString();',
# -- output --
'a();\n' +
'a = [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
'].toString();')
bt(
'function() {\n' +
' Foo([\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ]);\n' +
'}',
# -- output --
'function() {\n' +
' Foo([\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ]);\n' +
'}')
bt(
'function foo() {\n' +
' return [\n' +
' "one",\n' +
' "two"\n' +
' ];\n' +
'}',
# -- output --
'function foo() {\n' +
' return [\n' +
' "one",\n' +
' "two"\n' +
' ];\n' +
'}')
bt(
'function foo() {\n' +
' return [\n' +
' {\n' +
' one: "x",\n' +
' two: [\n' +
' {\n' +
' id: "a",\n' +
' name: "apple"\n' +
' }, {\n' +
' id: "b",\n' +
' name: "banana"\n' +
' }\n' +
' ]\n' +
' }\n' +
' ];\n' +
'}',
# -- output --
'function foo() {\n' +
' return [{\n' +
' one: "x",\n' +
' two: [{\n' +
' id: "a",\n' +
' name: "apple"\n' +
' }, {\n' +
' id: "b",\n' +
' name: "banana"\n' +
' }]\n' +
' }];\n' +
'}')
bt(
'function foo() {\n' +
' return [\n' +
' {\n' +
' one: "x",\n' +
' two: [\n' +
' {\n' +
' id: "a",\n' +
' name: "apple"\n' +
' }, {\n' +
' id: "b",\n' +
' name: "banana"\n' +
' }\n' +
' ]\n' +
' }\n' +
' ];\n' +
'}',
# -- output --
'function foo() {\n' +
' return [{\n' +
' one: "x",\n' +
' two: [{\n' +
' id: "a",\n' +
' name: "apple"\n' +
' }, {\n' +
' id: "b",\n' +
' name: "banana"\n' +
' }]\n' +
' }];\n' +
'}')
#============================================================
# keep_array_indentation true
self.reset_options()
self.options.keep_array_indentation = true
bt(
'a = ["a", "b", "c",\n' +
' "d", "e", "f"]',
# -- output --
'a = ["a", "b", "c",\n' +
' "d", "e", "f"]')
bt(
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"]',
# -- output --
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"]')
bt(
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"]',
# -- output --
'a = ["a", "b", "c",\n' +
' "d", "e", "f",\n' +
' "g", "h", "i"]')
bt(
'var x = [{}\n' +
']',
# -- output --
'var x = [{}\n' +
']')
bt(
'var x = [{foo:bar}\n' +
']',
# -- output --
'var x = [{\n' +
' foo: bar\n' +
' }\n' +
']')
bt(
'a = ["something",\n' +
' "completely",\n' +
' "different"];\n' +
'if (x);',
# -- output --
'a = ["something",\n' +
' "completely",\n' +
' "different"];\n' +
'if (x);')
bt('a = ["a","b","c"]', 'a = ["a", "b", "c"]')
bt('a = ["a", "b","c"]', 'a = ["a", "b", "c"]')
bt(
'x = [{"a":0}]',
# -- output --
'x = [{\n' +
' "a": 0\n' +
'}]')
bt(
'{a([[a1]], {b;});}',
# -- output --
'{\n' +
' a([[a1]], {\n' +
' b;\n' +
' });\n' +
'}')
bt(
'a ();\n' +
' [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ].toString();',
# -- output --
'a();\n' +
' [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ].toString();')
bt(
'a ();\n' +
'a = [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ].toString();',
# -- output --
'a();\n' +
'a = [\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ].toString();')
bt(
'function() {\n' +
' Foo([\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ]);\n' +
'}',
# -- output --
'function() {\n' +
' Foo([\n' +
' ["sdfsdfsd"],\n' +
' ["sdfsdfsdf"]\n' +
' ]);\n' +
'}')
bt(
'function foo() {\n' +
' return [\n' +
' "one",\n' +
' "two"\n' +
' ];\n' +
'}',
# -- output --
'function foo() {\n' +
' return [\n' +
' "one",\n' +
' "two"\n' +
' ];\n' +
'}')
bt(
'function foo() {\n' +
' return [\n' +
' {\n' +
' one: "x",\n' +
' two: [\n' +
' {\n' +
' id: "a",\n' +
' name: "apple"\n' +
' }, {\n' +
' id: "b",\n' +
' name: "banana"\n' +
' }\n' +
' ]\n' +
' }\n' +
' ];\n' +
'}',
# -- output --
'function foo() {\n' +
' return [\n' +
' {\n' +
' one: "x",\n' +
' two: [\n' +
' {\n' +
' id: "a",\n' +
' name: "apple"\n' +
' }, {\n' +
' id: "b",\n' +
' name: "banana"\n' +
' }\n' +
' ]\n' +
' }\n' +
' ];\n' +
'}')
#============================================================
# indent_empty_lines true
self.reset_options()
self.options.indent_empty_lines = true
test_fragment(
'var a = 1;\n' +
'\n' +
'var b = 1;')
test_fragment(
'var a = 1;\n' +
' \n' +
'var b = 1;',
# -- output --
'var a = 1;\n' +
'\n' +
'var b = 1;')
test_fragment(
'{\n' +
' var a = 1;\n' +
' \n' +
' var b = 1;\n' +
'\n' +
'}',
# -- output --
'{\n' +
' var a = 1;\n' +
' \n' +
' var b = 1;\n' +
' \n' +
'}')
test_fragment(
'{\n' +
'\n' +
' var a = 1;\n' +
'\n' +
'\n' +
'\n' +
' var b = 1;\n' +
'\n' +
'}',
# -- output --
'{\n' +
' \n' +
' var a = 1;\n' +
' \n' +
' \n' +
' \n' +
' var b = 1;\n' +
' \n' +
'}')
test_fragment(
'{\n' +
'\n' +
' var a = 1;\n' +
'\n' +
'function A() {\n' +
'\n' +
'}\n' +
'\n' +
' var b = 1;\n' +
'\n' +
'}',
# -- output --
'{\n' +
' \n' +
' var a = 1;\n' +
' \n' +
' function A() {\n' +
' \n' +
' }\n' +
' \n' +
' var b = 1;\n' +
' \n' +
'}')
#============================================================
# indent_empty_lines false
self.reset_options()
self.options.indent_empty_lines = false
test_fragment(
'var a = 1;\n' +
'\n' +
'var b = 1;')
test_fragment(
'var a = 1;\n' +
' \n' +
'var b = 1;',
# -- output --
'var a = 1;\n' +
'\n' +
'var b = 1;')
test_fragment(
'{\n' +
' var a = 1;\n' +
' \n' +
' var b = 1;\n' +
'\n' +
'}',
# -- output --
'{\n' +
' var a = 1;\n' +
'\n' +
' var b = 1;\n' +
'\n' +
'}')
test_fragment(
'{\n' +
'\n' +
' var a = 1;\n' +
'\n' +
'\n' +
'\n' +
' var b = 1;\n' +
'\n' +
'}')
test_fragment(
'{\n' +
'\n' +
' var a = 1;\n' +
'\n' +
'function A() {\n' +
'\n' +
'}\n' +
'\n' +
' var b = 1;\n' +
'\n' +
'}',
# -- output --
'{\n' +
'\n' +
' var a = 1;\n' +
'\n' +
' function A() {\n' +
'\n' +
' }\n' +
'\n' +
' var b = 1;\n' +
'\n' +
'}')
#============================================================
# Old tests
self.reset_options()
bt('')
test_fragment(' return .5')
test_fragment(
' return .5;\n' +
' a();')
test_fragment(
' return .5;\n' +
' a();')
test_fragment(
' return .5;\n' +
' a();')
test_fragment(' < div')
bt('a = 1', 'a = 1')
bt('a=1', 'a = 1')
bt('(3) / 2')
bt('["a", "b"].join("")')
bt(
'a();\n' +
'\n' +
'b();')
bt(
'var a = 1 var b = 2',
# -- output --
'var a = 1\n' +
'var b = 2')
bt(
'var a=1, b=c[d], e=6;',
# -- output --
'var a = 1,\n' +
' b = c[d],\n' +
' e = 6;')
bt(
'var a,\n' +
' b,\n' +
' c;')
bt(
'let a = 1 let b = 2',
# -- output --
'let a = 1\n' +
'let b = 2')
bt(
'let a=1, b=c[d], e=6;',
# -- output --
'let a = 1,\n' +
' b = c[d],\n' +
' e = 6;')
bt(
'let a,\n' +
' b,\n' +
' c;')
bt(
'const a = 1 const b = 2',
# -- output --
'const a = 1\n' +
'const b = 2')
bt(
'const a=1, b=c[d], e=6;',
# -- output --
'const a = 1,\n' +
' b = c[d],\n' +
' e = 6;')
bt(
'const a,\n' +
' b,\n' +
' c;')
bt('a = " 12345 "')
bt('a = \' 12345 \'')
bt('if (a == 1) b = 2;')
bt(
'if(1){2}else{3}',
# -- output --
'if (1) {\n' +
' 2\n' +
'} else {\n' +
' 3\n' +
'}')
bt('if(1||2);', 'if (1 || 2);')
bt('(a==1)||(b==2)', '(a == 1) || (b == 2)')
bt(
'var a = 1 if (2) 3;',
# -- output --
'var a = 1\n' +
'if (2) 3;')
bt('a = a + 1')
bt('a = a == 1')
bt('/12345[^678]*9+/.match(a)')
bt('a /= 5')
bt('a = 0.5 * 3')
bt('a *= 10.55')
bt('a < .5')
bt('a <= .5')
bt('a<.5', 'a < .5')
bt('a<=.5', 'a <= .5')
bt('a = [1, 2, 3, 4]')
bt('F*(g/=f)*g+b', 'F * (g /= f) * g + b')
bt(
'a.b({c:d})',
# -- output --
'a.b({\n' +
' c: d\n' +
'})')
bt(
'a.b\n' +
'(\n' +
'{\n' +
'c:\n' +
'd\n' +
'}\n' +
')',
# -- output --
'a.b({\n' +
' c: d\n' +
'})')
bt(
'a.b({c:"d"})',
# -- output --
'a.b({\n' +
' c: "d"\n' +
'})')
bt(
'a.b\n' +
'(\n' +
'{\n' +
'c:\n' +
'"d"\n' +
'}\n' +
')',
# -- output --
'a.b({\n' +
' c: "d"\n' +
'})')
bt('a=!b', 'a = !b')
bt('a=!!b', 'a = !!b')
bt('a?b:c', 'a ? b : c')
bt('a?1:2', 'a ? 1 : 2')
bt('a?(b):c', 'a ? (b) : c')
bt(
'x={a:1,b:w=="foo"?x:y,c:z}',
# -- output --
'x = {\n' +
' a: 1,\n' +
' b: w == "foo" ? x : y,\n' +
' c: z\n' +
'}')
bt('x=a?b?c?d:e:f:g;', 'x = a ? b ? c ? d : e : f : g;')
bt(
'x=a?b?c?d:{e1:1,e2:2}:f:g;',
# -- output --
'x = a ? b ? c ? d : {\n' +
' e1: 1,\n' +
' e2: 2\n' +
'} : f : g;')
bt('function void(void) {}')
bt('if(!a)foo();', 'if (!a) foo();')
bt('a=~a', 'a = ~a')
bt(
'a;/*comment*/b;',
# -- output --
'a; /*comment*/\n' +
'b;')
bt(
'a;/* comment */b;',
# -- output --
'a; /* comment */\n' +
'b;')
# simple comments don't get touched at all
test_fragment(
'a;/*\n' +
'comment\n' +
'*/b;',
# -- output --
'a;\n' +
'/*\n' +
'comment\n' +
'*/\n' +
'b;')
bt(
'a;/**\n' +
'* javadoc\n' +
'*/b;',
# -- output --
'a;\n' +
'/**\n' +
' * javadoc\n' +
' */\n' +
'b;')
test_fragment(
'a;/**\n' +
'\n' +
'no javadoc\n' +
'*/b;',
# -- output --
'a;\n' +
'/**\n' +
'\n' +
'no javadoc\n' +
'*/\n' +
'b;')
# comment blocks detected and reindented even w/o javadoc starter
bt(
'a;/*\n' +
'* javadoc\n' +
'*/b;',
# -- output --
'a;\n' +
'/*\n' +
' * javadoc\n' +
' */\n' +
'b;')
bt('if(a)break;', 'if (a) break;')
bt(
'if(a){break}',
# -- output --
'if (a) {\n' +
' break\n' +
'}')
bt('if((a))foo();', 'if ((a)) foo();')
bt('for(var i=0;;) a', 'for (var i = 0;;) a')
bt(
'for(var i=0;;)\n' +
'a',
# -- output --
'for (var i = 0;;)\n' +
' a')
bt('a++;')
bt('for(;;i++)a()', 'for (;; i++) a()')
bt(
'for(;;i++)\n' +
'a()',
# -- output --
'for (;; i++)\n' +
' a()')
bt('for(;;++i)a', 'for (;; ++i) a')
bt('return(1)', 'return (1)')
bt(
'try{a();}catch(b){c();}finally{d();}',
# -- output --
'try {\n' +
' a();\n' +
'} catch (b) {\n' +
' c();\n' +
'} finally {\n' +
' d();\n' +
'}')
# magic function call
bt('(xx)()')
# another magic function call
bt('a[1]()')
bt(
'if(a){b();}else if(c) foo();',
# -- output --
'if (a) {\n' +
' b();\n' +
'} else if (c) foo();')
bt(
'switch(x) {case 0: case 1: a(); break; default: break}',
# -- output --
'switch (x) {\n' +
' case 0:\n' +
' case 1:\n' +
' a();\n' +
' break;\n' +
' default:\n' +
' break\n' +
'}')
bt(
'switch(x) {default: case 1: a(); break; case 0: break}',
# -- output --
'switch (x) {\n' +
' default:\n' +
' case 1:\n' +
' a();\n' +
' break;\n' +
' case 0:\n' +
' break\n' +
'}')
bt(
'switch(x){case -1:break;case !y:break;}',
# -- output --
'switch (x) {\n' +
' case -1:\n' +
' break;\n' +
' case !y:\n' +
' break;\n' +
'}')
bt('a !== b')
bt(
'if (a) b(); else c();',
# -- output --
'if (a) b();\n' +
'else c();')
# typical greasemonkey start
bt(
'// comment\n' +
'(function something() {})')
# duplicating newlines
bt(
'{\n' +
'\n' +
' x();\n' +
'\n' +
'}')
bt('if (a in b) foo();')
bt('if (a of b) foo();')
bt('if (a of [1, 2, 3]) foo();')
bt(
'if(X)if(Y)a();else b();else c();',
# -- output --
'if (X)\n' +
' if (Y) a();\n' +
' else b();\n' +
'else c();')
bt(
'if (foo) bar();\n' +
'else break')
bt('var a, b;')
bt('var a = new function();')
test_fragment('new function')
bt('var a, b')
bt(
'{a:1, b:2}',
# -- output --
'{\n' +
' a: 1,\n' +
' b: 2\n' +
'}')
bt(
'a={1:[-1],2:[+1]}',
# -- output --
'a = {\n' +
' 1: [-1],\n' +
' 2: [+1]\n' +
'}')
bt(
'var l = {\'a\':\'1\', \'b\':\'2\'}',
# -- output --
'var l = {\n' +
' \'a\': \'1\',\n' +
' \'b\': \'2\'\n' +
'}')
bt('if (template.user[n] in bk) foo();')
bt('return 45')
bt(
'return this.prevObject ||\n' +
'\n' +
' this.constructor(null);')
bt('If[1]')
bt('Then[1]')
bt('a = 1;// comment', 'a = 1; // comment')
bt('a = 1; // comment')
bt(
'a = 1;\n' +
' // comment',
# -- output --
'a = 1;\n' +
'// comment')
bt('a = [-1, -1, -1]')
bt(
'// a\n' +
'// b\n' +
'\n' +
'\n' +
'\n' +
'// c\n' +
'// d')
bt(
'// func-comment\n' +
'\n' +
'function foo() {}\n' +
'\n' +
'// end-func-comment')
# The exact formatting these should have is open for discussion, but they are at least reasonable
bt(
'a = [ // comment\n' +
' -1, -1, -1\n' +
']')
bt(
'var a = [ // comment\n' +
' -1, -1, -1\n' +
']')
bt(
'a = [ // comment\n' +
' -1, // comment\n' +
' -1, -1\n' +
']')
bt(
'var a = [ // comment\n' +
' -1, // comment\n' +
' -1, -1\n' +
']')
bt(
'o = [{a:b},{c:d}]',
# -- output --
'o = [{\n' +
' a: b\n' +
'}, {\n' +
' c: d\n' +
'}]')
# was: extra space appended
bt(
'if (a) {\n' +
' do();\n' +
'}')
# if/else statement with empty body
bt(
'if (a) {\n' +
'// comment\n' +
'}else{\n' +
'// comment\n' +
'}',
# -- output --
'if (a) {\n' +
' // comment\n' +
'} else {\n' +
' // comment\n' +
'}')
# multiple comments indentation
bt(
'if (a) {\n' +
'// comment\n' +
'// comment\n' +
'}',
# -- output --
'if (a) {\n' +
' // comment\n' +
' // comment\n' +
'}')
bt(
'if (a) b() else c();',
# -- output --
'if (a) b()\n' +
'else c();')
bt(
'if (a) b() else if c() d();',
# -- output --
'if (a) b()\n' +
'else if c() d();')
bt('{}')
bt(
'{\n' +
'\n' +
'}')
bt(
'do { a(); } while ( 1 );',
# -- output --
'do {\n' +
' a();\n' +
'} while (1);')
bt('do {} while (1);')
bt(
'do {\n' +
'} while (1);',
# -- output --
'do {} while (1);')
bt(
'do {\n' +
'\n' +
'} while (1);')
bt('var a = x(a, b, c)')
bt(
'delete x if (a) b();',
# -- output --
'delete x\n' +
'if (a) b();')
bt(
'delete x[x] if (a) b();',
# -- output --
'delete x[x]\n' +
'if (a) b();')
bt('for(var a=1,b=2)d', 'for (var a = 1, b = 2) d')
bt('for(var a=1,b=2,c=3) d', 'for (var a = 1, b = 2, c = 3) d')
bt(
'for(var a=1,b=2,c=3;d<3;d++)\n' +
'e',
# -- output --
'for (var a = 1, b = 2, c = 3; d < 3; d++)\n' +
' e')
bt(
'function x(){(a||b).c()}',
# -- output --
'function x() {\n' +
' (a || b).c()\n' +
'}')
bt(
'function x(){return - 1}',
# -- output --
'function x() {\n' +
' return -1\n' +
'}')
bt(
'function x(){return ! a}',
# -- output --
'function x() {\n' +
' return !a\n' +
'}')
bt('x => x')
bt('(x) => x')
bt(
'x => { x }',
# -- output --
'x => {\n' +
' x\n' +
'}')
bt(
'(x) => { x }',
# -- output --
'(x) => {\n' +
' x\n' +
'}')
# a common snippet in jQuery plugins
bt(
'settings = $.extend({},defaults,settings);',
# -- output --
'settings = $.extend({}, defaults, settings);')
bt('$http().then().finally().default()')
bt(
'$http()\n' +
'.then()\n' +
'.finally()\n' +
'.default()',
# -- output --
'$http()\n' +
' .then()\n' +
' .finally()\n' +
' .default()')
bt('$http().when.in.new.catch().throw()')
bt(
'$http()\n' +
'.when\n' +
'.in\n' +
'.new\n' +
'.catch()\n' +
'.throw()',
# -- output --
'$http()\n' +
' .when\n' +
' .in\n' +
' .new\n' +
' .catch()\n' +
' .throw()')
bt(
'{xxx;}()',
# -- output --
'{\n' +
' xxx;\n' +
'}()')
bt(
'a = \'a\'\n' +
'b = \'b\'')
bt('a = /reg/exp')
bt('a = /reg/')
bt('/abc/.test()')
bt('/abc/i.test()')
bt(
'{/abc/i.test()}',
# -- output --
'{\n' +
' /abc/i.test()\n' +
'}')
bt('var x=(a)/a;', 'var x = (a) / a;')
bt('x != -1')
bt('for (; s-->0;)t', 'for (; s-- > 0;) t')
bt('for (; s++>0;)u', 'for (; s++ > 0;) u')
bt('a = s++>s--;', 'a = s++ > s--;')
bt('a = s++>--s;', 'a = s++ > --s;')
bt(
'{x=#1=[]}',
# -- output --
'{\n' +
' x = #1=[]\n' +
'}')
bt(
'{a:#1={}}',
# -- output --
'{\n' +
' a: #1={}\n' +
'}')
bt(
'{a:#1#}',
# -- output --
'{\n' +
' a: #1#\n' +
'}')
test_fragment('"incomplete-string')
test_fragment('\'incomplete-string')
test_fragment('/incomplete-regex')
test_fragment('`incomplete-template-string')
test_fragment(
'{a:1},{a:2}',
# -- output --
'{\n' +
' a: 1\n' +
'}, {\n' +
' a: 2\n' +
'}')
test_fragment(
'var ary=[{a:1}, {a:2}];',
# -- output --
'var ary = [{\n' +
' a: 1\n' +
'}, {\n' +
' a: 2\n' +
'}];')
# incomplete
test_fragment(
'{a:#1',
# -- output --
'{\n' +
' a: #1')
# incomplete
test_fragment(
'{a:#',
# -- output --
'{\n' +
' a: #')
# incomplete
test_fragment(
'}}}',
# -- output --
'}\n' +
'}\n' +
'}')
test_fragment(
'')
# incomplete regexp
test_fragment('a=/regexp', 'a = /regexp')
bt(
'{a:#1=[],b:#1#,c:#999999#}',
# -- output --
'{\n' +
' a: #1=[],\n' +
' b: #1#,\n' +
' c: #999999#\n' +
'}')
bt(
'do{x()}while(a>1)',
# -- output --
'do {\n' +
' x()\n' +
'} while (a > 1)')
bt(
'x(); /reg/exp.match(something)',
# -- output --
'x();\n' +
'/reg/exp.match(something)')
test_fragment(
'something();(',
# -- output --
'something();\n' +
'(')
test_fragment(
'#!she/bangs, she bangs\n' +
'f=1',
# -- output --
'#!she/bangs, she bangs\n' +
'\n' +
'f = 1')
test_fragment(
'#!she/bangs, she bangs\n' +
'\n' +
'f=1',
# -- output --
'#!she/bangs, she bangs\n' +
'\n' +
'f = 1')
test_fragment(
'#!she/bangs, she bangs\n' +
'\n' +
'/* comment */')
test_fragment(
'#!she/bangs, she bangs\n' +
'\n' +
'\n' +
'/* comment */')
test_fragment('#')
test_fragment('#!')
test_fragment('#include')
test_fragment('#include "settings.jsxinc"')
test_fragment(
'#include "settings.jsxinc"\n' +
'\n' +
'\n' +
'/* comment */')
test_fragment(
'#include "settings.jsxinc"\n' +
'\n' +
'\n' +
'#include "settings.jsxinc"\n' +
'\n' +
'\n' +
'/* comment */')
bt('function namespace::something()')
test_fragment(
'')
test_fragment(
'',
# -- output --
'')
bt(
'{foo();--bar;}',
# -- output --
'{\n' +
' foo();\n' +
' --bar;\n' +
'}')
bt(
'{foo();++bar;}',
# -- output --
'{\n' +
' foo();\n' +
' ++bar;\n' +
'}')
bt(
'{--bar;}',
# -- output --
'{\n' +
' --bar;\n' +
'}')
bt(
'{++bar;}',
# -- output --
'{\n' +
' ++bar;\n' +
'}')
bt('if(true)++a;', 'if (true) ++a;')
bt(
'if(true)\n' +
'++a;',
# -- output --
'if (true)\n' +
' ++a;')
bt('if(true)--a;', 'if (true) --a;')
bt(
'if(true)\n' +
'--a;',
# -- output --
'if (true)\n' +
' --a;')
bt('elem[array]++;')
bt('elem++ * elem[array]++;')
bt('elem-- * -elem[array]++;')
bt('elem-- + elem[array]++;')
bt('elem-- - elem[array]++;')
bt('elem-- - -elem[array]++;')
bt('elem-- - +elem[array]++;')
# Handling of newlines around unary ++ and -- operators
bt(
'{foo\n' +
'++bar;}',
# -- output --
'{\n' +
' foo\n' +
' ++bar;\n' +
'}')
bt(
'{foo++\n' +
'bar;}',
# -- output --
'{\n' +
' foo++\n' +
' bar;\n' +
'}')
# This is invalid, but harder to guard against. Issue #203.
bt(
'{foo\n' +
'++\n' +
'bar;}',
# -- output --
'{\n' +
' foo\n' +
' ++\n' +
' bar;\n' +
'}')
# regexps
bt(
'a(/abc\\/\\/def/);b()',
# -- output --
'a(/abc\\/\\/def/);\n' +
'b()')
bt(
'a(/a[b\\[\\]c]d/);b()',
# -- output --
'a(/a[b\\[\\]c]d/);\n' +
'b()')
# incomplete char class
test_fragment('a(/a[b\\[')
# allow unescaped / in char classes
bt(
'a(/[a/b]/);b()',
# -- output --
'a(/[a/b]/);\n' +
'b()')
bt('typeof /foo\\//;')
bt('throw /foo\\//;')
bt('do /foo\\//;')
bt('return /foo\\//;')
bt(
'switch (a) {\n' +
' case /foo\\//:\n' +
' b\n' +
'}')
bt(
'if (a) /foo\\//\n' +
'else /foo\\//;')
bt('if (foo) /regex/.test();')
bt('for (index in [1, 2, 3]) /^test$/i.test(s)')
bt(
'function foo() {\n' +
' return [\n' +
' "one",\n' +
' "two"\n' +
' ];\n' +
'}')
bt(
'a=[[1,2],[4,5],[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' function() {},\n' +
' [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' function() {},\n' +
' function() {},\n' +
' [7, 8]\n' +
']')
bt(
'a=[[1,2],[4,5],function(){},[7,8]]',
# -- output --
'a = [\n' +
' [1, 2],\n' +
' [4, 5],\n' +
' function() {},\n' +
' [7, 8]\n' +
']')
bt('a=[b,c,function(){},function(){},d]', 'a = [b, c, function() {}, function() {}, d]')
bt(
'a=[b,c,\n' +
'function(){},function(){},d]',
# -- output --
'a = [b, c,\n' +
' function() {},\n' +
' function() {},\n' +
' d\n' +
']')
bt('a=[a[1],b[4],c[d[7]]]', 'a = [a[1], b[4], c[d[7]]]')
bt('[1,2,[3,4,[5,6],7],8]', '[1, 2, [3, 4, [5, 6], 7], 8]')
bt(
'[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
# -- output --
'[\n' +
' [\n' +
' ["1", "2"],\n' +
' ["3", "4"]\n' +
' ],\n' +
' [\n' +
' ["5", "6", "7"],\n' +
' ["8", "9", "0"]\n' +
' ],\n' +
' [\n' +
' ["1", "2", "3"],\n' +
' ["4", "5", "6", "7"],\n' +
' ["8", "9", "0"]\n' +
' ]\n' +
']')
bt(
'{[x()[0]];indent;}',
# -- output --
'{\n' +
' [x()[0]];\n' +
' indent;\n' +
'}')
bt(
'/*\n' +
' foo trailing space \n' +
' * bar trailing space \n' +
'**/')
bt(
'{\n' +
' /*\n' +
' foo \n' +
' * bar \n' +
' */\n' +
'}')
bt('return ++i')
bt(
'obj.num++\n' +
'foo()\n' +
'bar()\n' +
'\n' +
'obj.num--\n' +
'foo()\n' +
'bar()')
bt('return !!x')
bt('return !x')
bt('return [1,2]', 'return [1, 2]')
bt('return;')
bt(
'return\n' +
'func')
bt('catch(e)', 'catch (e)')
bt(
'var a=1,b={foo:2,bar:3},{baz:4,wham:5},c=4;',
# -- output --
'var a = 1,\n' +
' b = {\n' +
' foo: 2,\n' +
' bar: 3\n' +
' },\n' +
' {\n' +
' baz: 4,\n' +
' wham: 5\n' +
' }, c = 4;')
bt(
'var a=1,b={foo:2,bar:3},{baz:4,wham:5},\n' +
'c=4;',
# -- output --
'var a = 1,\n' +
' b = {\n' +
' foo: 2,\n' +
' bar: 3\n' +
' },\n' +
' {\n' +
' baz: 4,\n' +
' wham: 5\n' +
' },\n' +
' c = 4;')
# inline comment
bt(
'function x(/*int*/ start, /*string*/ foo)',
# -- output --
'function x( /*int*/ start, /*string*/ foo)')
# javadoc comment
bt(
'/**\n' +
'* foo\n' +
'*/',
# -- output --
'/**\n' +
' * foo\n' +
' */')
bt(
'{\n' +
'/**\n' +
'* foo\n' +
'*/\n' +
'}',
# -- output --
'{\n' +
' /**\n' +
' * foo\n' +
' */\n' +
'}')
# starless block comment
bt(
'/**\n' +
'foo\n' +
'*/')
bt(
'/**\n' +
'foo\n' +
'**/')
bt(
'/**\n' +
'foo\n' +
'bar\n' +
'**/')
bt(
'/**\n' +
'foo\n' +
'\n' +
'bar\n' +
'**/')
bt(
'/**\n' +
'foo\n' +
' bar\n' +
'**/')
bt(
'{\n' +
'/**\n' +
'foo\n' +
'*/\n' +
'}',
# -- output --
'{\n' +
' /**\n' +
' foo\n' +
' */\n' +
'}')
bt(
'{\n' +
'/**\n' +
'foo\n' +
'**/\n' +
'}',
# -- output --
'{\n' +
' /**\n' +
' foo\n' +
' **/\n' +
'}')
bt(
'{\n' +
'/**\n' +
'foo\n' +
'bar\n' +
'**/\n' +
'}',
# -- output --
'{\n' +
' /**\n' +
' foo\n' +
' bar\n' +
' **/\n' +
'}')
bt(
'{\n' +
'/**\n' +
'foo\n' +
'\n' +
'bar\n' +
'**/\n' +
'}',
# -- output --
'{\n' +
' /**\n' +
' foo\n' +
'\n' +
' bar\n' +
' **/\n' +
'}')
bt(
'{\n' +
'/**\n' +
'foo\n' +
' bar\n' +
'**/\n' +
'}',
# -- output --
'{\n' +
' /**\n' +
' foo\n' +
' bar\n' +
' **/\n' +
'}')
bt(
'{\n' +
' /**\n' +
' foo\n' +
'bar\n' +
' **/\n' +
'}')
bt(
'var a,b,c=1,d,e,f=2;',
# -- output --
'var a, b, c = 1,\n' +
' d, e, f = 2;')
bt(
'var a,b,c=[],d,e,f=2;',
# -- output --
'var a, b, c = [],\n' +
' d, e, f = 2;')
bt(
'function() {\n' +
' var a, b, c, d, e = [],\n' +
' f;\n' +
'}')
bt(
'do/regexp/;\n' +
'while(1);',
# -- output --
'do /regexp/;\n' +
'while (1);')
bt(
'var a = a,\n' +
'a;\n' +
'b = {\n' +
'b\n' +
'}',
# -- output --
'var a = a,\n' +
' a;\n' +
'b = {\n' +
' b\n' +
'}')
bt(
'var a = a,\n' +
' /* c */\n' +
' b;')
bt(
'var a = a,\n' +
' // c\n' +
' b;')
# weird element referencing
bt('foo.("bar");')
bt(
'if (a) a()\n' +
'else b()\n' +
'newline()')
bt(
'if (a) a()\n' +
'newline()')
bt('a=typeof(x)', 'a = typeof(x)')
bt(
'var a = function() {\n' +
' return null;\n' +
' },\n' +
' b = false;')
bt(
'var a = function() {\n' +
' func1()\n' +
'}')
bt(
'var a = function() {\n' +
' func1()\n' +
'}\n' +
'var b = function() {\n' +
' func2()\n' +
'}')
# code with and without semicolons
bt(
'var whatever = require("whatever");\n' +
'function() {\n' +
' a = 6;\n' +
'}',
# -- output --
'var whatever = require("whatever");\n' +
'\n' +
'function() {\n' +
' a = 6;\n' +
'}')
bt(
'var whatever = require("whatever")\n' +
'function() {\n' +
' a = 6\n' +
'}',
# -- output --
'var whatever = require("whatever")\n' +
'\n' +
'function() {\n' +
' a = 6\n' +
'}')
bt(
'{"x":[{"a":1,"b":3},\n' +
'7,8,8,8,8,{"b":99},{"a":11}]}',
# -- output --
'{\n' +
' "x": [{\n' +
' "a": 1,\n' +
' "b": 3\n' +
' },\n' +
' 7, 8, 8, 8, 8, {\n' +
' "b": 99\n' +
' }, {\n' +
' "a": 11\n' +
' }\n' +
' ]\n' +
'}')
bt(
'{"x":[{"a":1,"b":3},7,8,8,8,8,{"b":99},{"a":11}]}',
# -- output --
'{\n' +
' "x": [{\n' +
' "a": 1,\n' +
' "b": 3\n' +
' }, 7, 8, 8, 8, 8, {\n' +
' "b": 99\n' +
' }, {\n' +
' "a": 11\n' +
' }]\n' +
'}')
bt(
'{"1":{"1a":"1b"},"2"}',
# -- output --
'{\n' +
' "1": {\n' +
' "1a": "1b"\n' +
' },\n' +
' "2"\n' +
'}')
bt(
'{a:{a:b},c}',
# -- output --
'{\n' +
' a: {\n' +
' a: b\n' +
' },\n' +
' c\n' +
'}')
bt(
'{[y[a]];keep_indent;}',
# -- output --
'{\n' +
' [y[a]];\n' +
' keep_indent;\n' +
'}')
bt(
'if (x) {y} else { if (x) {y}}',
# -- output --
'if (x) {\n' +
' y\n' +
'} else {\n' +
' if (x) {\n' +
' y\n' +
' }\n' +
'}')
bt(
'if (foo) one()\n' +
'two()\n' +
'three()')
bt(
'if (1 + foo() && bar(baz()) / 2) one()\n' +
'two()\n' +
'three()')
bt(
'if (1 + foo() && bar(baz()) / 2) one();\n' +
'two();\n' +
'three();')
bt(
'var a=1,b={bang:2},c=3;',
# -- output --
'var a = 1,\n' +
' b = {\n' +
' bang: 2\n' +
' },\n' +
' c = 3;')
bt(
'var a={bing:1},b=2,c=3;',
# -- output --
'var a = {\n' +
' bing: 1\n' +
' },\n' +
' b = 2,\n' +
' c = 3;')
def test_beautifier_unconverted(self):
test_fragment = self.decodesto
bt = self.bt
self.reset_options()
#============================================================
bt(None, "")
self.reset_options()
#============================================================
# Test user pebkac protection, converts dash names to underscored names
setattr(self.options, 'end-with-newline', True)
test_fragment(None, '\n')
self.reset_options()
#============================================================
# Test passing dictionary or tuple
self.options = {'end_with_newline': True, 'eol': '\r\n' }
test_fragment(None, '\r\n')
self.options = {'end-with-newline': True}
test_fragment(None, '\n')
self.options = {'end-with-newline': False}
test_fragment(None, '')
self.options = ( ('end-with-newline', True), ('eol', '\r') )
test_fragment(None, '\r')
self.reset_options()
#============================================================
self.options.indent_size = 1
self.options.indent_char = ' '
bt('{ one_char() }', "{\n one_char()\n}")
bt('var a,b=1,c=2', 'var a, b = 1,\n c = 2')
self.options.indent_size = 4
self.options.indent_char = ' '
bt('{ one_char() }', "{\n one_char()\n}")
self.options.indent_size = 1
self.options.indent_char = "\t"
bt('{ one_char() }', "{\n\tone_char()\n}")
bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;')
#set to something else than it should change to, but with tabs on, should override
self.options.indent_size = 5
self.options.indent_char = ' '
self.options.indent_with_tabs = True
bt('{ one_char() }', "{\n\tone_char()\n}")
bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;')
self.reset_options()
#============================================================
self.options.preserve_newlines = False
bt('var\na=dont_preserve_newlines;', 'var a = dont_preserve_newlines;')
# make sure the blank line between function definitions stays
# even when preserve_newlines = False
bt('function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}')
bt('function foo() {\n return 1;\n}\nfunction foo() {\n return 1;\n}',
'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
)
bt('function foo() {\n return 1;\n}\n\n\nfunction foo() {\n return 1;\n}',
'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
)
self.options.preserve_newlines = True
bt('var\na=do_preserve_newlines;', 'var\n a = do_preserve_newlines;')
bt('if (foo) // comment\n{\n bar();\n}')
self.reset_options()
#============================================================
# START tests for brace positioning
# If this is ever supported, update tests for each brace style.
# test_fragment('return\n{', 'return\n{') # can't support this?, but that's an improbable and extreme case anyway.
self.options.brace_style = 'expand'
bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}')
bt('if(1){2}else{3}', "if (1)\n{\n 2\n}\nelse\n{\n 3\n}")
bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
"try\n{\n a();\n}\ncatch (b)\n{\n c();\n}\ncatch (d)\n{}\nfinally\n{\n e();\n}")
bt('if(a){b();}else if(c) foo();',
"if (a)\n{\n b();\n}\nelse if (c) foo();")
bt("if (a) {\n// comment\n}else{\n// comment\n}",
"if (a)\n{\n // comment\n}\nelse\n{\n // comment\n}") # if/else statement with empty body
bt('if (x) {y} else { if (x) {y}}',
'if (x)\n{\n y\n}\nelse\n{\n if (x)\n {\n y\n }\n}')
bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
'if (a)\n{\n b;\n}\nelse\n{\n c;\n}')
test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
' /*\n * xx\n */\n // xx\n if (foo)\n {\n bar();\n }')
bt('if (foo)\n{}\nelse /regex/.test();')
test_fragment('if (foo) {', 'if (foo)\n{')
test_fragment('foo {', 'foo\n{')
test_fragment('return {', 'return {') # return needs the brace.
test_fragment('return /* inline */ {', 'return /* inline */ {')
test_fragment('return;\n{', 'return;\n{')
bt("throw {}")
bt("throw {\n foo;\n}")
bt('var foo = {}')
bt('function x() {\n foo();\n}zzz', 'function x()\n{\n foo();\n}\nzzz')
test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
bt('var a = new function() {};')
bt('var a = new function a() {};', 'var a = new function a()\n{};')
bt('var a = new function()\n{};', 'var a = new function() {};')
bt('var a = new function a()\n{};')
bt('var a = new function a()\n {},\n b = new function b()\n {};')
bt("foo({\n 'a': 1\n},\n10);",
"foo(\n {\n 'a': 1\n },\n 10);")
bt('(["foo","bar"]).each(function(i) {return i;});',
'(["foo", "bar"]).each(function(i)\n{\n return i;\n});')
bt('(function(i) {return i;})();',
'(function(i)\n{\n return i;\n})();')
bt( "test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test(\n" +
"/*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"},\n" +
"/*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test(\n" +
" /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test( /*Argument 1*/\n" +
"{\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */\n" +
"{\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
self.options.brace_style = 'collapse'
bt('//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}")
bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
"try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}")
bt('if(a){b();}else if(c) foo();',
"if (a) {\n b();\n} else if (c) foo();")
bt("if (a) {\n// comment\n}else{\n// comment\n}",
"if (a) {\n // comment\n} else {\n // comment\n}") # if/else statement with empty body
bt('if (x) {y} else { if (x) {y}}',
'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}')
bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
'if (a) {\n b;\n} else {\n c;\n}')
test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
bt('if (foo) {} else /regex/.test();')
test_fragment('if (foo) {', 'if (foo) {')
test_fragment('foo {', 'foo {')
test_fragment('return {', 'return {') # return needs the brace.
test_fragment('return /* inline */ {', 'return /* inline */ {')
test_fragment('return;\n{', 'return; {')
bt("throw {}")
bt("throw {\n foo;\n}")
bt('var foo = {}')
bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz')
test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
bt('var a = new function() {};')
bt('var a = new function a() {};')
bt('var a = new function()\n{};', 'var a = new function() {};')
bt('var a = new function a()\n{};', 'var a = new function a() {};')
bt('var a = new function a()\n {},\n b = new function b()\n {};', 'var a = new function a() {},\n b = new function b() {};')
bt("foo({\n 'a': 1\n},\n10);",
"foo({\n 'a': 1\n },\n 10);")
bt('(["foo","bar"]).each(function(i) {return i;});',
'(["foo", "bar"]).each(function(i) {\n return i;\n});')
bt('(function(i) {return i;})();',
'(function(i) {\n return i;\n})();')
bt( "test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test(\n" +
"/*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"},\n" +
"/*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test(\n" +
" /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test( /*Argument 1*/\n" +
"{\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */\n" +
"{\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
self.options.brace_style = "end-expand"
bt('//case 1\nif (a == 1) {}\n//case 2\nelse if (a == 2) {}')
bt('if(1){2}else{3}', "if (1) {\n 2\n}\nelse {\n 3\n}")
bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
"try {\n a();\n}\ncatch (b) {\n c();\n}\ncatch (d) {}\nfinally {\n e();\n}")
bt('if(a){b();}else if(c) foo();',
"if (a) {\n b();\n}\nelse if (c) foo();")
bt("if (a) {\n// comment\n}else{\n// comment\n}",
"if (a) {\n // comment\n}\nelse {\n // comment\n}") # if/else statement with empty body
bt('if (x) {y} else { if (x) {y}}',
'if (x) {\n y\n}\nelse {\n if (x) {\n y\n }\n}')
bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
'if (a) {\n b;\n}\nelse {\n c;\n}')
test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
bt('if (foo) {}\nelse /regex/.test();')
test_fragment('if (foo) {', 'if (foo) {')
test_fragment('foo {', 'foo {')
test_fragment('return {', 'return {') # return needs the brace.
test_fragment('return /* inline */ {', 'return /* inline */ {')
test_fragment('return;\n{', 'return; {')
bt("throw {}")
bt("throw {\n foo;\n}")
bt('var foo = {}')
bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz')
test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
bt('var a = new function() {};')
bt('var a = new function a() {};')
bt('var a = new function()\n{};', 'var a = new function() {};')
bt('var a = new function a()\n{};', 'var a = new function a() {};')
bt('var a = new function a()\n {},\n b = new function b()\n {};', 'var a = new function a() {},\n b = new function b() {};')
bt("foo({\n 'a': 1\n},\n10);",
"foo({\n 'a': 1\n },\n 10);")
bt('(["foo","bar"]).each(function(i) {return i;});',
'(["foo", "bar"]).each(function(i) {\n return i;\n});')
bt('(function(i) {return i;})();',
'(function(i) {\n return i;\n})();')
bt( "test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test(\n" +
"/*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"},\n" +
"/*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test(\n" +
" /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test( /*Argument 1*/\n" +
"{\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */\n" +
"{\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
self.options.brace_style = 'none'
bt('//case 1\nif (a == 1)\n{}\n//case 2\nelse if (a == 2)\n{}')
bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}")
bt('try{a();}catch(b){c();}catch(d){}finally{e();}',
"try {\n a();\n} catch (b) {\n c();\n} catch (d) {} finally {\n e();\n}")
bt('if(a){b();}else if(c) foo();',
"if (a) {\n b();\n} else if (c) foo();")
bt("if (a) {\n// comment\n}else{\n// comment\n}",
"if (a) {\n // comment\n} else {\n // comment\n}") # if/else statement with empty body
bt('if (x) {y} else { if (x) {y}}',
'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}')
bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}',
'if (a)\n{\n b;\n}\nelse\n{\n c;\n}')
test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}',
' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
bt('if (foo)\n{}\nelse /regex/.test();')
test_fragment('if (foo) {')
test_fragment('foo {')
test_fragment('return {') # return needs the brace.
test_fragment('return /* inline */ {')
test_fragment('return;\n{')
bt("throw {}")
bt("throw {\n foo;\n}")
bt('var foo = {}')
bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz')
test_fragment('a: do {} while (); xxx', 'a: do {} while ();\nxxx')
bt('{a: do {} while (); xxx}', '{\n a: do {} while ();xxx\n}')
bt('var a = new function() {};')
bt('var a = new function a() {};')
bt('var a = new function()\n{};', 'var a = new function() {};')
bt('var a = new function a()\n{};')
bt('var a = new function a()\n {},\n b = new function b()\n {};')
bt("foo({\n 'a': 1\n},\n10);",
"foo({\n 'a': 1\n },\n 10);")
bt('(["foo","bar"]).each(function(i) {return i;});',
'(["foo", "bar"]).each(function(i) {\n return i;\n});')
bt('(function(i) {return i;})();',
'(function(i) {\n return i;\n})();')
bt( "test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test(\n" +
"/*Argument 1*/ {\n" +
" 'Value1': '1'\n" +
"},\n" +
"/*Argument 2\n" +
" */ {\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test(\n" +
" /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
bt( "test( /*Argument 1*/\n" +
"{\n" +
" 'Value1': '1'\n" +
"}, /*Argument 2\n" +
" */\n" +
"{\n" +
" 'Value2': '2'\n" +
"});",
# expected
"test( /*Argument 1*/\n" +
" {\n" +
" 'Value1': '1'\n" +
" },\n" +
" /*Argument 2\n" +
" */\n" +
" {\n" +
" 'Value2': '2'\n" +
" });")
# END tests for brace position
self.reset_options()
#============================================================
self.options.preserve_newlines = True
bt("var a = 'foo' +\n 'bar';")
bt('"foo""bar""baz"', '"foo"\n"bar"\n"baz"')
bt("'foo''bar''baz'", "'foo'\n'bar'\n'baz'")
bt("{\n get foo() {}\n}")
bt("{\n var a = get\n foo();\n}")
bt("{\n set foo() {}\n}")
bt("{\n var a = set\n foo();\n}")
bt("var x = {\n get function()\n}")
bt("var x = {\n set function()\n}")
# According to my current research get/set have no special meaning outside of an object literal
bt("var x = set\n\na() {}", "var x = set\n\na() {}")
bt("var x = set\n\nfunction() {}", "var x = set\n\nfunction() {}")
bt('for () /abc/.test()')
bt('if (k) /aaa/m.test(v) && l();')
bt('switch (true) {\n case /swf/i.test(foo):\n bar();\n}')
bt('createdAt = {\n type: Date,\n default: Date.now\n}')
bt('switch (createdAt) {\n case a:\n Date,\n default:\n Date.now\n}')
self.reset_options()
#============================================================
def decodesto(self, input, expectation=None):
if expectation is None:
expectation = input
self.assertMultiLineEqual(
jsbeautifier.beautify(input, self.options), expectation)
# if the expected is different from input, run it again
# expected output should be unchanged when run twice.
if not expectation is None:
self.assertMultiLineEqual(
jsbeautifier.beautify(expectation, self.options), expectation)
if self.options is None or not isinstance(self.options, (dict, tuple)):
# Everywhere we do newlines, they should be replaced with opts.eol
self.options.eol = '\r\\n'
expectation = expectation.replace('\n', '\r\n')
self.options.disabled = True
self.assertMultiLineEqual(
jsbeautifier.beautify(input, self.options), input or '')
self.assertMultiLineEqual(
jsbeautifier.beautify('\n\n' + expectation, self.options), '\n\n' + expectation)
self.options.disabled = False;
self.assertMultiLineEqual(
jsbeautifier.beautify(input, self.options), expectation)
if input and input.find('\n') != -1:
input = input.replace('\n', '\r\n')
self.assertMultiLineEqual(
jsbeautifier.beautify(input, self.options), expectation)
# Ensure support for auto eol detection
self.options.eol = 'auto'
self.assertMultiLineEqual(
jsbeautifier.beautify(input, self.options), expectation)
self.options.eol = '\n'
def wrap(self, text):
return self.wrapregex.sub(' \\1', text)
def bt(self, input, expectation=None):
if expectation is None:
expectation = input
self.decodesto(input, expectation)
# If we set raw, input should be unchanged
self.options.test_output_raw = True
if self.options.end_with_newline:
self.decodesto(input, input)
self.options.test_output_raw = False
current_indent_size = None
if self.options.js and self.options.js['indent_size']:
current_indent_size = self.options.js['indent_size']
if not current_indent_size:
current_indent_size = self.options.indent_size
if current_indent_size == 4 and input:
wrapped_input = '{\n%s\n foo = bar;\n}' % self.wrap(input)
wrapped_expect = '{\n%s\n foo = bar;\n}' % self.wrap(expectation)
self.decodesto(wrapped_input, wrapped_expect)
# If we set raw, input should be unchanged
self.options.test_output_raw = True
if self.options.end_with_newline:
self.decodesto(wrapped_input, wrapped_input)
self.options.test_output_raw = False
if __name__ == '__main__':
unittest.main()
jsbeautifier-1.10.3/jsbeautifier/tests/testindentation.py 0000644 0000765 0000024 00000002604 13476247317 025161 0 ustar bitwiseman staff 0000000 0000000 import re
import unittest
import jsbeautifier
class TestJSBeautifierIndentation(unittest.TestCase):
def test_tabs(self):
test_fragment = self.decodesto
self.options.indent_with_tabs = 1
test_fragment('{tabs()}', "{\n\ttabs()\n}")
def test_function_indent(self):
test_fragment = self.decodesto
self.options.indent_with_tabs = 1
self.options.keep_function_indentation = 1
test_fragment(
'var foo = function(){ bar() }();',
"var foo = function() {\n\tbar()\n}();")
self.options.tabs = 1
self.options.keep_function_indentation = 0
test_fragment(
'var foo = function(){ baz() }();',
"var foo = function() {\n\tbaz()\n}();")
def decodesto(self, input, expectation=None):
self.assertEqual(
jsbeautifier.beautify(input, self.options), expectation or input)
@classmethod
def setUpClass(cls):
options = jsbeautifier.default_options()
options.indent_size = 4
options.indent_char = ' '
options.preserve_newlines = True
options.jslint_happy = False
options.keep_array_indentation = False
options.brace_style = 'collapse'
options.indent_level = 0
cls.options = options
cls.wrapregex = re.compile('^(.+)$', re.MULTILINE)
if __name__ == '__main__':
unittest.main()
jsbeautifier-1.10.3/jsbeautifier/unpackers/ 0000755 0000765 0000024 00000000000 13607410064 022205 5 ustar bitwiseman staff 0000000 0000000 jsbeautifier-1.10.3/jsbeautifier/unpackers/__init__.py 0000644 0000765 0000024 00000004417 13476247317 024341 0 ustar bitwiseman staff 0000000 0000000 #
# General code for JSBeautifier unpackers infrastructure. See README.specs
# written by Stefano Sanfilippo
#
"""General code for JSBeautifier unpackers infrastructure."""
import pkgutil
import re
from jsbeautifier.unpackers import evalbased
# NOTE: AT THE MOMENT, IT IS DEACTIVATED FOR YOUR SECURITY: it runs js!
BLACKLIST = ['jsbeautifier.unpackers.evalbased']
class UnpackingError(Exception):
"""Badly packed source or general error. Argument is a
meaningful description."""
pass
def getunpackers():
"""Scans the unpackers dir, finds unpackers and add them to UNPACKERS list.
An unpacker will be loaded only if it is a valid python module (name must
adhere to naming conventions) and it is not blacklisted (i.e. inserted
into BLACKLIST."""
path = __path__
prefix = __name__ + '.'
unpackers = []
interface = ['unpack', 'detect', 'PRIORITY']
for _importer, modname, _ispkg in pkgutil.iter_modules(path, prefix):
if 'tests' not in modname and modname not in BLACKLIST:
try:
module = __import__(modname, fromlist=interface)
except ImportError:
raise UnpackingError('Bad unpacker: %s' % modname)
else:
unpackers.append(module)
return sorted(unpackers, key=lambda mod: mod.PRIORITY)
UNPACKERS = getunpackers()
def run(source, evalcode=False):
"""Runs the applicable unpackers and return unpacked source as a string."""
for unpacker in [mod for mod in UNPACKERS if mod.detect(source)]:
source = unpacker.unpack(source)
if evalcode and evalbased.detect(source):
source = evalbased.unpack(source)
return source
def filtercomments(source):
"""NOT USED: strips trailing comments and put them at the top."""
trailing_comments = []
comment = True
while comment:
if re.search(r'^\s*\/\*', source):
comment = source[0, source.index('*/') + 2]
elif re.search(r'^\s*\/\/', source):
comment = re.search(r'^\s*\/\/', source).group(0)
else:
comment = None
if comment:
source = re.sub(r'^\s+', '', source[len(comment):])
trailing_comments.append(comment)
return '\n'.join(trailing_comments) + source
jsbeautifier-1.10.3/jsbeautifier/unpackers/evalbased.py 0000644 0000765 0000024 00000002224 13476247317 024522 0 ustar bitwiseman staff 0000000 0000000 #
# Unpacker for eval() based packers, a part of javascript beautifier
# by Einar Lielmanis
#
# written by Stefano Sanfilippo
#
# usage:
#
# if detect(some_string):
# unpacked = unpack(some_string)
#
"""Unpacker for eval() based packers: runs JS code and returns result.
Works only if a JS interpreter (e.g. Mozilla's Rhino) is installed and
properly set up on host."""
from subprocess import PIPE, Popen
PRIORITY = 3
def detect(source):
"""Detects if source is likely to be eval() packed."""
return source.strip().lower().startswith('eval(function(')
def unpack(source):
"""Runs source and return resulting code."""
return jseval('print %s;' % source[4:]) if detect(source) else source
# In case of failure, we'll just return the original, without crashing on user.
def jseval(script):
"""Run code in the JS interpreter and return output."""
try:
interpreter = Popen(['js'], stdin=PIPE, stdout=PIPE)
except OSError:
return script
result, errors = interpreter.communicate(script)
if interpreter.poll() or errors:
return script
return result
jsbeautifier-1.10.3/jsbeautifier/unpackers/javascriptobfuscator.py 0000644 0000765 0000024 00000003377 13476247317 027044 0 ustar bitwiseman staff 0000000 0000000 #
# simple unpacker/deobfuscator for scripts messed up with
# javascriptobfuscator.com
#
# written by Einar Lielmanis
# rewritten in Python by Stefano Sanfilippo
#
# Will always return valid javascript: if `detect()` is false, `code` is
# returned, unmodified.
#
# usage:
#
# if javascriptobfuscator.detect(some_string):
# some_string = javascriptobfuscator.unpack(some_string)
#
"""deobfuscator for scripts messed up with JavascriptObfuscator.com"""
import re
PRIORITY = 1
def smartsplit(code):
"""Split `code` at " symbol, only if it is not escaped."""
strings = []
pos = 0
while pos < len(code):
if code[pos] == '"':
word = '' # new word
pos += 1
while pos < len(code):
if code[pos] == '"':
break
if code[pos] == '\\':
word += '\\'
pos += 1
word += code[pos]
pos += 1
strings.append('"%s"' % word)
pos += 1
return strings
def detect(code):
"""Detects if `code` is JavascriptObfuscator.com packed."""
# prefer `is not` idiom, so that a true boolean is returned
return (re.search(r'^var _0x[a-f0-9]+ ?\= ?\[', code) is not None)
def unpack(code):
"""Unpacks JavascriptObfuscator.com packed code."""
if detect(code):
matches = re.search(r'var (_0x[a-f\d]+) ?\= ?\[(.*?)\];', code)
if matches:
variable = matches.group(1)
dictionary = smartsplit(matches.group(2))
code = code[len(matches.group(0)):]
for key, value in enumerate(dictionary):
code = code.replace(r'%s[%s]' % (variable, key), value)
return code
jsbeautifier-1.10.3/jsbeautifier/unpackers/myobfuscate.py 0000644 0000765 0000024 00000005337 13476247317 025125 0 ustar bitwiseman staff 0000000 0000000 #
# deobfuscator for scripts messed up with myobfuscate.com
# by Einar Lielmanis
#
# written by Stefano Sanfilippo
#
# usage:
#
# if detect(some_string):
# unpacked = unpack(some_string)
#
# CAVEAT by Einar Lielmanis
#
# You really don't want to obfuscate your scripts there: they're tracking
# your unpackings, your script gets turned into something like this,
# as of 2011-08-26:
#
# var _escape = 'your_script_escaped';
# var _111 = document.createElement('script');
# _111.src = 'http://api.www.myobfuscate.com/?getsrc=ok' +
# '&ref=' + encodeURIComponent(document.referrer) +
# '&url=' + encodeURIComponent(document.URL);
# var 000 = document.getElementsByTagName('head')[0];
# 000.appendChild(_111);
# document.write(unescape(_escape));
#
"""Deobfuscator for scripts messed up with MyObfuscate.com"""
import re
import base64
# Python 2 retrocompatibility
# pylint: disable=F0401
# pylint: disable=E0611
try:
from urllib import unquote
except ImportError:
from urllib.parse import unquote
from jsbeautifier.unpackers import UnpackingError
PRIORITY = 1
CAVEAT = """//
// Unpacker warning: be careful when using myobfuscate.com for your projects:
// scripts obfuscated by the free online version call back home.
//
"""
SIGNATURE = (
r'["\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F'
r'\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x61\x62\x63\x64\x65'
r'\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75'
r'\x76\x77\x78\x79\x7A\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2B'
r'\x2F\x3D","","\x63\x68\x61\x72\x41\x74","\x69\x6E\x64\x65\x78'
r'\x4F\x66","\x66\x72\x6F\x6D\x43\x68\x61\x72\x43\x6F\x64\x65","'
r'\x6C\x65\x6E\x67\x74\x68"]')
def detect(source):
"""Detects MyObfuscate.com packer."""
return SIGNATURE in source
def unpack(source):
"""Unpacks js code packed with MyObfuscate.com"""
if not detect(source):
return source
payload = unquote(_filter(source))
match = re.search(r"^var _escape\='