This commit is contained in:
chrosey
2017-09-13 07:52:34 +02:00
parent a1f16c37f4
commit 2340b0226b
24621 changed files with 2912161 additions and 149 deletions
+13
View File
@@ -0,0 +1,13 @@
engines:
eslint:
enabled: true
pep8:
enabled: true
ratings:
paths:
- "**.js"
- "**.py"
exclude_paths:
- test/resources/**
- web/third-party/**
- "**/generated/*"
+9
View File
@@ -0,0 +1,9 @@
js/bin/**
js/test/resources/**
node_modules/**
python/**
target/**
tools/**
test/resources/underscore-min.js
test/resources/underscore.js
web/third-party/**
+10
View File
@@ -0,0 +1,10 @@
{
"bitwise": true,
"curly": true,
"eqeqeq": true,
"noarg": true,
"nocomma": true,
"nonbsp": true,
"nonew": true,
"unused": true
}
+5
View File
@@ -0,0 +1,5 @@
Makefile
index.html
php/
python/
web/
+14
View File
@@ -0,0 +1,14 @@
language: python
python:
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "3.5"
node_js:
- "0.10"
script: "./build ci"
+542
View File
@@ -0,0 +1,542 @@
# Changelog
## v1.6.12
### Description
### Closed Issues
* CSS: Preserve Newlines ([#537](https://github.com/beautify-web/js-beautify/issues/537))
## v1.6.11
### Description
Reverted #1117 - Preserve newlines broken
### Closed Issues
* On beautify, new line before next CSS selector ([#1142](https://github.com/beautify-web/js-beautify/issues/1142))
## v1.6.10
### Description
Added `preserver_newlines` to css beautifier
### Closed Issues
## v1.6.9
### Description
* Fixed html formatting issue with attribute wrap (Thanks, @HookyQR!)
* Fixed python package publishing
### Closed Issues
* Wrong HTML beautification starting with v1.6.5 ([#1115](https://github.com/beautify-web/js-beautify/issues/1115))
* Ignore linebreak when meet handlebar ([#1104](https://github.com/beautify-web/js-beautify/pull/1104))
* Lines are not un-indented correctly when attributes are wrapped ([#1103](https://github.com/beautify-web/js-beautify/issues/1103))
* force-aligned is not aligned when indenting with tabs ([#1102](https://github.com/beautify-web/js-beautify/issues/1102))
* Python package fails to publish ([#1101](https://github.com/beautify-web/js-beautify/issues/1101))
* Explaination of 'operator_position' is absent from README.md ([#1047](https://github.com/beautify-web/js-beautify/issues/1047))
## v1.6.8
### Description
* Fixed a batch of comment and semicolon-less code bugs
### Closed Issues
* Incorrect indentation after loop with comment ([#1090](https://github.com/beautify-web/js-beautify/issues/1090))
* Extra newline is inserted after beautifying code with anonymous function ([#1085](https://github.com/beautify-web/js-beautify/issues/1085))
* end brace with next comment line make bad indent ([#1043](https://github.com/beautify-web/js-beautify/issues/1043))
* Javascript comment in last line doesn't beautify well ([#964](https://github.com/beautify-web/js-beautify/issues/964))
* indent doesn't work with comment (jsdoc) ([#913](https://github.com/beautify-web/js-beautify/issues/913))
* Wrong indentation, when new line between chained methods ([#892](https://github.com/beautify-web/js-beautify/issues/892))
* Comments in a non-semicolon style have extra indent ([#815](https://github.com/beautify-web/js-beautify/issues/815))
* [bug] Incorrect indentation due to commented line(s) following a function call with a function argument. ([#713](https://github.com/beautify-web/js-beautify/issues/713))
* Wrong indent formatting ([#569](https://github.com/beautify-web/js-beautify/issues/569))
## v1.6.7
### Description
Added `content_unformatted` option (Thanks @arai-a)
### Closed Issues
* HTML pre code indentation ([#928](https://github.com/beautify-web/js-beautify/issues/928))
* Beautify script/style tags but ignore their inner JS/CSS content ([#906](https://github.com/beautify-web/js-beautify/issues/906))
## v1.6.6
### Description
* Added support for editorconfig from stdin
* Added js-beautify to cdnjs
* Fixed CRLF to LF for HTML and CSS on windows
* Added inheritance/overriding to config format (Thanks @DaniGuardiola and @HookyQR)
* Added `force-align` to `wrap-attributes` (Thanks @Lukinos)
* Added `force-expand-multiline` to `wrap-attributes` (Thanks @tobias-zucali)
* Added `preserve-inline` as independent brace setting (Thanks @Coburn37)
* Fixed handlebars with angle-braces (Thanks @mmsqe)
### Closed Issues
* Wrong indentation for comment after nested unbraced control constructs ([#1079](https://github.com/beautify-web/js-beautify/issues/1079))
* Should prefer breaking the line after operator ? instead of before operator < ([#1073](https://github.com/beautify-web/js-beautify/issues/1073))
* New option "force-expand-multiline" for "wrap_attributes" ([#1070](https://github.com/beautify-web/js-beautify/pull/1070))
* Breaks if html file starts with comment ([#1068](https://github.com/beautify-web/js-beautify/issues/1068))
* collapse-preserve-inline restricts users to collapse brace_style ([#1057](https://github.com/beautify-web/js-beautify/issues/1057))
* Parsing failure on numbers with "e" ([#1054](https://github.com/beautify-web/js-beautify/issues/1054))
* Issue with Browser Instructions ([#1053](https://github.com/beautify-web/js-beautify/issues/1053))
* Add preserve inline function for expand style braces ([#1052](https://github.com/beautify-web/js-beautify/issues/1052))
* Update years in LICENSE ([#1038](https://github.com/beautify-web/js-beautify/issues/1038))
* JS. Switch with template literals. Unexpected indentation. ([#1030](https://github.com/beautify-web/js-beautify/issues/1030))
* The object with spread object formatted not correctly ([#1023](https://github.com/beautify-web/js-beautify/issues/1023))
* Bad output generator function in class ([#1013](https://github.com/beautify-web/js-beautify/issues/1013))
* Support editorconfig for stdin ([#1012](https://github.com/beautify-web/js-beautify/issues/1012))
* Publish to cdnjs ([#992](https://github.com/beautify-web/js-beautify/issues/992))
* breaks if handlebars comments contain handlebars tags ([#930](https://github.com/beautify-web/js-beautify/issues/930))
* Using jsbeautifyrc is broken ([#929](https://github.com/beautify-web/js-beautify/issues/929))
* Option to put HTML attributes on their own lines, aligned ([#916](https://github.com/beautify-web/js-beautify/issues/916))
* Erroneously changes CRLF to LF on Windows in HTML and CSS ([#899](https://github.com/beautify-web/js-beautify/issues/899))
* Weird space in {get } vs { normal } ([#888](https://github.com/beautify-web/js-beautify/issues/888))
* Bad for-of formatting with constant Array ([#875](https://github.com/beautify-web/js-beautify/issues/875))
* Problems with filter property in css and scss ([#755](https://github.com/beautify-web/js-beautify/issues/755))
* Add "collapse-one-line" option for non-collapse brace styles ([#487](https://github.com/beautify-web/js-beautify/issues/487))
## v1.6.4
### Description
* Fixed JSX multi-line root element handling
* Fixed CSS Combinator spacing (NOTE: use `space_around_combinator` option)
* Fixed (more) CSS pseudo-class and pseudo-element selectors (Thanks @Konamiman!)
* Fixed Shorthand generator functions and `yield*` (Thanks @jgeurts!)
* Added EditorConfig support (Thanks @ethanluoyc!)
* Added indent_body_inner_html and indent_head_inner_html (Thanks @spontaliku-softaria!)
* Added js-beautify to https://cdn.rawgit.com (Thanks @zxqfox)
### Closed Issues
* css-beautify sibling combinator space issue ([#1001](https://github.com/beautify-web/js-beautify/issues/1001))
* Bug: Breaks when the source code it found an unclosed multiline comment. ([#996](https://github.com/beautify-web/js-beautify/issues/996))
* CSS: Preserve white space before pseudo-class and pseudo-element selectors ([#985](https://github.com/beautify-web/js-beautify/pull/985))
* Spelling error in token definition ([#984](https://github.com/beautify-web/js-beautify/issues/984))
* collapse-preserve-inline does not preserve simple, single line ("return") statements ([#982](https://github.com/beautify-web/js-beautify/issues/982))
* Publish the library via cdn ([#971](https://github.com/beautify-web/js-beautify/issues/971))
* Bug with css calc() function ([#957](https://github.com/beautify-web/js-beautify/issues/957))
* &:first-of-type:not(:last-child) when prettified insert erroneous white character ([#952](https://github.com/beautify-web/js-beautify/issues/952))
* Shorthand generator functions are formatting strangely ([#941](https://github.com/beautify-web/js-beautify/issues/941))
* Add handlebars support on cli for html ([#935](https://github.com/beautify-web/js-beautify/pull/935))
* Do not put a space within `yield*` generator functions. ([#920](https://github.com/beautify-web/js-beautify/issues/920))
* Possible to add an indent_inner_inner_html option? (Prevent indenting second-level tags) ([#917](https://github.com/beautify-web/js-beautify/issues/917))
* Messing up jsx formatting ([#914](https://github.com/beautify-web/js-beautify/issues/914))
* Bug report: Closing 'body' tag isn't formatted correctly ([#900](https://github.com/beautify-web/js-beautify/issues/900))
* { throw … } not working with collapse-preserve-inline ([#898](https://github.com/beautify-web/js-beautify/issues/898))
* ES6 concise method not propely indented ([#889](https://github.com/beautify-web/js-beautify/issues/889))
* CSS beautify changing symantics ([#883](https://github.com/beautify-web/js-beautify/issues/883))
* Dojo unsupported script types. ([#874](https://github.com/beautify-web/js-beautify/issues/874))
* Readme version comment ([#868](https://github.com/beautify-web/js-beautify/issues/868))
* Extra space after pseudo-elements within :not() ([#618](https://github.com/beautify-web/js-beautify/issues/618))
* space in media queries after colon &: selectors ([#565](https://github.com/beautify-web/js-beautify/issues/565))
* Integrating editor config ([#551](https://github.com/beautify-web/js-beautify/issues/551))
* Preserve short expressions/statements on single line ([#338](https://github.com/beautify-web/js-beautify/issues/338))
## v1.6.3
### Description
Bug fixes
### Closed Issues
* CLI broken when output path is not set ([#933](https://github.com/beautify-web/js-beautify/issues/933))
* huge memory leak ([#909](https://github.com/beautify-web/js-beautify/issues/909))
* don't print unpacking errors on stdout (python) ([#884](https://github.com/beautify-web/js-beautify/pull/884))
* Fix incomplete list of non-positionable operators (python lib) ([#878](https://github.com/beautify-web/js-beautify/pull/878))
* Fix Issue #844 ([#873](https://github.com/beautify-web/js-beautify/pull/873))
* assignment exponentiation operator ([#864](https://github.com/beautify-web/js-beautify/issues/864))
* Bug in Less mixins ([#844](https://github.com/beautify-web/js-beautify/issues/844))
* Can't Nest Conditionals ([#680](https://github.com/beautify-web/js-beautify/issues/680))
* ternary operations ([#670](https://github.com/beautify-web/js-beautify/issues/670))
* Support newline before logical or ternary operator ([#605](https://github.com/beautify-web/js-beautify/issues/605))
* Provide config files for format and linting ([#336](https://github.com/beautify-web/js-beautify/issues/336))
## v1.6.2
### Description
### Closed Issues
* Add missing 'collapse-preserve-inline' option to js module ([#861](https://github.com/beautify-web/js-beautify/pull/861))
## v1.6.1
### Description
Fixes for regressions found in 1.6.0
### Closed Issues
* Inconsistent formatting for arrays of objects ([#860](https://github.com/beautify-web/js-beautify/issues/860))
* Publish v1.6.1 ([#859](https://github.com/beautify-web/js-beautify/issues/859))
* Space added to "from++" due to ES6 keyword ([#858](https://github.com/beautify-web/js-beautify/issues/858))
* Changelog generator doesn't sort versions above 9 right ([#778](https://github.com/beautify-web/js-beautify/issues/778))
* space-after-anon-function not applied to object properties ([#761](https://github.com/beautify-web/js-beautify/issues/761))
* Separating 'input' elements adds whitespace ([#580](https://github.com/beautify-web/js-beautify/issues/580))
* Inline Format ([#572](https://github.com/beautify-web/js-beautify/issues/572))
* Preserve attributes line break in HTML ([#455](https://github.com/beautify-web/js-beautify/issues/455))
* Multiline Array ([#406](https://github.com/beautify-web/js-beautify/issues/406))
## v1.6.0
### Description
* Inline/short object and json preservation (all rejoice!)
* ES6 annotations, module import/export, arrow functions, concise methods, and more
* JSX spread attributes
* HTML wrap attributes, inline element fixes, doctype and php fixes
* Test framework hardening
* Windows build fixed and covered by appveyor continuous integration
### Closed Issues
* Individual tests pollute options object ([#855](https://github.com/beautify-web/js-beautify/issues/855))
* Object attribute assigned fat arrow function with implicit return of a ternary causes next line to indent ([#854](https://github.com/beautify-web/js-beautify/issues/854))
* Treat php tags as single in html ([#850](https://github.com/beautify-web/js-beautify/pull/850))
* Read piped input by default ([#849](https://github.com/beautify-web/js-beautify/pull/849))
* Replace makefile dependency with bash script ([#848](https://github.com/beautify-web/js-beautify/pull/848))
* list of HTML inline elements incomplete; wraps inappropriately ([#840](https://github.com/beautify-web/js-beautify/issues/840))
* Beautifying bracket-less if/elses ([#838](https://github.com/beautify-web/js-beautify/issues/838))
* <col> elements within a <colgroup> are getting indented incorrectly ([#836](https://github.com/beautify-web/js-beautify/issues/836))
* single attribute breaks jsx beautification ([#834](https://github.com/beautify-web/js-beautify/issues/834))
* Improve Python packaging ([#831](https://github.com/beautify-web/js-beautify/pull/831))
* Erroneously changes CRLF to LF on Windows. ([#829](https://github.com/beautify-web/js-beautify/issues/829))
* Can't deal with XHTML5 ([#828](https://github.com/beautify-web/js-beautify/issues/828))
* HTML after PHP is indented ([#826](https://github.com/beautify-web/js-beautify/issues/826))
* exponentiation operator ([#825](https://github.com/beautify-web/js-beautify/issues/825))
* Add support for script type "application/ld+json" ([#821](https://github.com/beautify-web/js-beautify/issues/821))
* package.json: Remove "preferGlobal" option ([#820](https://github.com/beautify-web/js-beautify/pull/820))
* Don't use array.indexOf() to support legacy browsers ([#816](https://github.com/beautify-web/js-beautify/pull/816))
* ES6 Object Shortand Indenting Weirdly Sometimes ([#810](https://github.com/beautify-web/js-beautify/issues/810))
* Implicit Return Function on New Line not Preserved ([#806](https://github.com/beautify-web/js-beautify/issues/806))
* Misformating "0b" Binary Strings ([#803](https://github.com/beautify-web/js-beautify/issues/803))
* Beautifier breaks ES6 nested template strings ([#797](https://github.com/beautify-web/js-beautify/issues/797))
* Misformating "0o" Octal Strings ([#792](https://github.com/beautify-web/js-beautify/issues/792))
* Do not use hardcoded directory for tests ([#788](https://github.com/beautify-web/js-beautify/pull/788))
* Handlebars {{else}} tag not given a newline ([#784](https://github.com/beautify-web/js-beautify/issues/784))
* Wrong indentation for XML header (<?xml version="1.0"?>) ([#783](https://github.com/beautify-web/js-beautify/issues/783))
* is_whitespace for loop incrementing wrong variable ([#777](https://github.com/beautify-web/js-beautify/pull/777))
* Newline is inserted after comment with comma_first ([#775](https://github.com/beautify-web/js-beautify/issues/775))
* Cannot copy more than 1000 characters out of CodeMirror buffer ([#768](https://github.com/beautify-web/js-beautify/issues/768))
* Missing 'var' in beautify-html.js; breaks strict mode ([#763](https://github.com/beautify-web/js-beautify/issues/763))
* Fix typo in the example javascript code of index.html ([#753](https://github.com/beautify-web/js-beautify/pull/753))
## v1.5.10
### Description
Hotfix for directives
Version jump due to release script tweaks
### Closed Issues
* Preserve directive doesn't work as intended ([#723](https://github.com/beautify-web/js-beautify/issues/723))
## v1.5.7
### Description
* Beautifier does not break PHP and Underscore.js templates
* Fix for SCSS pseudo classes and intperpolation/mixins
* Alternative Newline Characters in CSS and HTML
* Preserve formatting or completely ignore section of javascript using comments
### Closed Issues
* Support for legacy JavaScript versions (e.g. WSH+JScript & Co) ([#720](https://github.com/beautify-web/js-beautify/pull/720))
* Is \\n hard coded into CSS Beautifier logic? ([#715](https://github.com/beautify-web/js-beautify/issues/715))
* Spaces and linebreaks after # and around { } messing up interpolation/mixins (SASS/SCSS) ([#689](https://github.com/beautify-web/js-beautify/issues/689))
* Calls to functions get completely messed up in Sass (*.scss) ([#675](https://github.com/beautify-web/js-beautify/issues/675))
* No new line after selector in scss files ([#666](https://github.com/beautify-web/js-beautify/issues/666))
* using html-beautify on handlebars template deletes unclosed tag if on second line ([#623](https://github.com/beautify-web/js-beautify/issues/623))
* more Extra space after scss pseudo classes ([#557](https://github.com/beautify-web/js-beautify/issues/557))
* Unnecessary spaces in PHP code ([#490](https://github.com/beautify-web/js-beautify/issues/490))
* Some underscore.js template tags are broken ([#417](https://github.com/beautify-web/js-beautify/issues/417))
* Selective ignore using comments (feature request) ([#384](https://github.com/beautify-web/js-beautify/issues/384))
## v1.5.6
### Description
* JSX support!
* Alternative Newline Characters
* CSS and JS comment formatting fixes
* General bug fixing
### Closed Issues
* Fix tokenizer's bracket pairs' open stack ([#693](https://github.com/beautify-web/js-beautify/pull/693))
* Indentation is incorrect for HTML5 void tag <source> ([#692](https://github.com/beautify-web/js-beautify/issues/692))
* Line wrapping breaks at the wrong place when the line is indented. ([#691](https://github.com/beautify-web/js-beautify/issues/691))
* Publish v1.5.6 ([#687](https://github.com/beautify-web/js-beautify/issues/687))
* Replace existing file fails using python beautifier ([#686](https://github.com/beautify-web/js-beautify/issues/686))
* Pseudo-classes formatted incorrectly and inconsistently with @page ([#661](https://github.com/beautify-web/js-beautify/issues/661))
* doc: add end_with_newline option ([#650](https://github.com/beautify-web/js-beautify/pull/650))
* Improve support for xml parts of jsx (React) => spaces, spread attributes and nested objects break the process ([#646](https://github.com/beautify-web/js-beautify/issues/646))
* html-beautify formats handlebars comments but does not format html comments ([#635](https://github.com/beautify-web/js-beautify/issues/635))
* Support for ES7 async ([#630](https://github.com/beautify-web/js-beautify/issues/630))
* css beautify adding an extra newline after a comment line in a css block ([#609](https://github.com/beautify-web/js-beautify/issues/609))
* No option to "Indent with tabs" for HTML files ([#587](https://github.com/beautify-web/js-beautify/issues/587))
* Function body is indented when followed by a comment ([#583](https://github.com/beautify-web/js-beautify/issues/583))
* JSX support ([#425](https://github.com/beautify-web/js-beautify/issues/425))
* Alternative Newline Characters ([#260](https://github.com/beautify-web/js-beautify/issues/260))
## v1.5.5
### Description
* Initial implementation of comma-first formatting - Diff-friendly literals!
* CSS: Add newline between rules
* LESS: improved function parameter formatting
* HTML: options for wrapping attributes
* General bug fixing
### Closed Issues
* Add GUI support for `--indent-inner-html`. ([#633](https://github.com/beautify-web/js-beautify/pull/633))
* Publish v1.5.5 ([#629](https://github.com/beautify-web/js-beautify/issues/629))
* CSS: Updating the documentation for the 'newline_between_rules' ([#615](https://github.com/beautify-web/js-beautify/pull/615))
* Equal Sign Removed from Filter Properties Alpha Opacity Assignment ([#599](https://github.com/beautify-web/js-beautify/issues/599))
* Keep trailing spaces on comments ([#598](https://github.com/beautify-web/js-beautify/issues/598))
* only print the file names of changed files ([#597](https://github.com/beautify-web/js-beautify/issues/597))
* CSS: support add newline between rules ([#574](https://github.com/beautify-web/js-beautify/pull/574))
* elem[array]++ changes to elem[array] ++ inserting unnecessary gap ([#570](https://github.com/beautify-web/js-beautify/issues/570))
* add support to less functions paramters braces ([#568](https://github.com/beautify-web/js-beautify/pull/568))
* selector_separator_newline: true for Sass doesn't work ([#563](https://github.com/beautify-web/js-beautify/issues/563))
* yield statements are being beautified to their own newlines since 1.5.2 ([#560](https://github.com/beautify-web/js-beautify/issues/560))
* HTML beautifier inserts extra newline into `<li>`s ending with `<code>` ([#524](https://github.com/beautify-web/js-beautify/issues/524))
* Add wrap_attributes option ([#476](https://github.com/beautify-web/js-beautify/issues/476))
* Add or preserve empty line between CSS rules ([#467](https://github.com/beautify-web/js-beautify/issues/467))
* Support comma first style of variable declaration ([#245](https://github.com/beautify-web/js-beautify/issues/245))
## v1.5.4
### Description
* Fix for LESS/CSS pseudo/classes
* Fix for HTML img tag spaces
https://github.com/beautify-web/js-beautify/compare/v1.5.3...v1.5.4
### Closed Issues
* TypeScript oddly formatted with 1.5.3 ([#552](https://github.com/beautify-web/js-beautify/issues/552))
* HTML beautifier inserts double spaces between adjacent tags ([#525](https://github.com/beautify-web/js-beautify/issues/525))
* Keep space in font rule ([#491](https://github.com/beautify-web/js-beautify/issues/491))
* [Brackets plug in] Space after </a> disappears ([#454](https://github.com/beautify-web/js-beautify/issues/454))
* Support nested pseudo-classes and parent reference (LESS) ([#427](https://github.com/beautify-web/js-beautify/pull/427))
* Alternate approach: preserve single spacing and treat img as inline element ([#415](https://github.com/beautify-web/js-beautify/pull/415))
## v1.5.3
### Description
* High priority bug fixes
* Major fixes to css-beautifier to not blow up LESS/SCSS
* Lower priority bug fixes that were very ugly
https://github.com/beautify-web/js-beautify/compare/v1.5.2...v1.5.3
### Closed Issues
* [TypeError: Cannot read property 'type' of undefined] ([#548](https://github.com/beautify-web/js-beautify/issues/548))
* Bug with RegExp ([#547](https://github.com/beautify-web/js-beautify/issues/547))
* Odd behaviour on less ([#520](https://github.com/beautify-web/js-beautify/issues/520))
* css beauitify ([#506](https://github.com/beautify-web/js-beautify/issues/506))
* Extra space after scss pseudo classes. ([#500](https://github.com/beautify-web/js-beautify/issues/500))
* Generates invalid scss when formatting ampersand selectors ([#498](https://github.com/beautify-web/js-beautify/issues/498))
* bad formatting of .less files using @variable or &:hover syntax ([#489](https://github.com/beautify-web/js-beautify/issues/489))
* Incorrect beautifying of CSS comment including an url. ([#466](https://github.com/beautify-web/js-beautify/issues/466))
* Handle SASS parent reference &: ([#414](https://github.com/beautify-web/js-beautify/issues/414))
* Js-beautify breaking selectors in less code. ([#410](https://github.com/beautify-web/js-beautify/issues/410))
* Problem with "content" ([#364](https://github.com/beautify-web/js-beautify/issues/364))
* Space gets inserted between function and paren for function in Define ([#313](https://github.com/beautify-web/js-beautify/issues/313))
* beautify-html returns null on broken html ([#301](https://github.com/beautify-web/js-beautify/issues/301))
* Indentation of functions inside conditionals not passing jslint ([#298](https://github.com/beautify-web/js-beautify/issues/298))
## v1.5.2
### Description
* Improved indenting for statements, array, variable declaration, "Starless" block-comments
* Support for bitwise-not, yield, get, set, let, const, generator functions
* Reserved words can be used as object property names
* Added options: space_after_anon_function, end-with-newline
* Properly tokenize Numbers (including decimals and exponents)
* Do not break "x++ + y"
* function declaration inside array behaves the same as in expression
* Close String literals at newline
* Support handlebar syntax
* Check `<script>` "type"-attribute
* Allow `<style>` and `<script>` tags to be unformatted
* Port css nesting fix to python
* Fix python six dependency
* Initial very cursory support for ES6 module, export, and import
https://github.com/beautify-web/js-beautify/compare/v1.5.1...v1.5.2
### Closed Issues
* Allow custom elements to be unformatted ([#540](https://github.com/beautify-web/js-beautify/pull/540))
* Need option to ignore brace style ([#538](https://github.com/beautify-web/js-beautify/issues/538))
* Refactor to Output and OutputLine classes ([#536](https://github.com/beautify-web/js-beautify/pull/536))
* Recognize ObjectLiteral on open brace ([#535](https://github.com/beautify-web/js-beautify/pull/535))
* Refactor to fully tokenize before formatting ([#530](https://github.com/beautify-web/js-beautify/pull/530))
* Cleanup checked in six.py file ([#527](https://github.com/beautify-web/js-beautify/pull/527))
* Changelog.md? ([#526](https://github.com/beautify-web/js-beautify/issues/526))
* New line added between each css declaration ([#523](https://github.com/beautify-web/js-beautify/issues/523))
* Kendo Template scripts get messed up! ([#516](https://github.com/beautify-web/js-beautify/issues/516))
* SyntaxError: Unexpected token ++ ([#514](https://github.com/beautify-web/js-beautify/issues/514))
* space appears before open square bracket when the object name is "set" ([#508](https://github.com/beautify-web/js-beautify/issues/508))
* Unclosed string problem ([#505](https://github.com/beautify-web/js-beautify/issues/505))
* "--n" and "++n" are not indented like "n--" and "n++" are... ([#495](https://github.com/beautify-web/js-beautify/issues/495))
* Allow `<style>` and `<script>` tags to be unformatted ([#494](https://github.com/beautify-web/js-beautify/pull/494))
* Preserve new line at end of file ([#492](https://github.com/beautify-web/js-beautify/issues/492))
* Line wraps breaking numbers (causes syntax error) ([#488](https://github.com/beautify-web/js-beautify/issues/488))
* jsBeautify acts differently when handling different kinds of function expressions ([#485](https://github.com/beautify-web/js-beautify/issues/485))
* AttributeError: 'NoneType' object has no attribute 'groups' ([#479](https://github.com/beautify-web/js-beautify/issues/479))
* installation doco for python need update -- pip install six? ([#478](https://github.com/beautify-web/js-beautify/issues/478))
* Move einars/js-beautify to beautify-web/js-beautify ([#475](https://github.com/beautify-web/js-beautify/issues/475))
* Bring back space_after_anon_function ([#474](https://github.com/beautify-web/js-beautify/pull/474))
* fix for #453, Incompatible handlebar syntax ([#468](https://github.com/beautify-web/js-beautify/pull/468))
* Python: missing explicit dependency on "six" package ([#465](https://github.com/beautify-web/js-beautify/issues/465))
* function declaration inside array, adds extra line. ([#464](https://github.com/beautify-web/js-beautify/issues/464))
* [es6] yield a array ([#458](https://github.com/beautify-web/js-beautify/issues/458))
* Publish v1.5.2 ([#452](https://github.com/beautify-web/js-beautify/issues/452))
* Port css colon character fix to python ([#446](https://github.com/beautify-web/js-beautify/issues/446))
* Cannot declare object literal properties with unquoted reserved words ([#440](https://github.com/beautify-web/js-beautify/issues/440))
* Do not put a space within `function*` generator functions. ([#428](https://github.com/beautify-web/js-beautify/issues/428))
* beautification of "nth-child" css fails csslint ([#418](https://github.com/beautify-web/js-beautify/issues/418))
## v1.5.1
### Description
Highlights:
* Fixes var declaration of objects and arrays to indent correctly (#256, #430)
* Support keywords as IdentifierNames such as foo.catch() (#309, #351,#368, #378)
* Improved indenting for statements (#289)
* Improved ES6 support - let, const, template strings, and "fat arrow"
* Support for non-ASCII characters in variable names (#305)
* Multiple fixes to requirejs support and added tests to protect in future
* Improved LESS support (still plenty of room for improvement in this area)
* Do not add space after !!
https://github.com/einars/js-beautify/compare/v1.4.2...v1.5.1
### Closed Issues
* Nested if statements not displayed correctly ([#450](https://github.com/beautify-web/js-beautify/issues/450))
* preserve_newlines always true ([#449](https://github.com/beautify-web/js-beautify/issues/449))
* line wrapping breaks in weird places ([#438](https://github.com/beautify-web/js-beautify/issues/438))
* Update dependencies to current versions ([#437](https://github.com/beautify-web/js-beautify/pull/437))
* Add support for ES6 template strings ([#434](https://github.com/beautify-web/js-beautify/pull/434))
* Fix #402: support ES6 fat arrow ([#433](https://github.com/beautify-web/js-beautify/pull/433))
* Ending brace missaligned when part of first definition in var line ([#430](https://github.com/beautify-web/js-beautify/issues/430))
* fixing disabled line wrapping for HTML ([#429](https://github.com/beautify-web/js-beautify/pull/429))
* Missing semi colon ([#420](https://github.com/beautify-web/js-beautify/issues/420))
* Fixed require.js support ([#416](https://github.com/beautify-web/js-beautify/pull/416))
* should not split the es6 operator '=>' ([#402](https://github.com/beautify-web/js-beautify/issues/402))
* fixed relative paths for require.js ([#387](https://github.com/beautify-web/js-beautify/pull/387))
* Support reserved words as property names ([#378](https://github.com/beautify-web/js-beautify/issues/378))
* Make the AMD API match the rest of the APIs ([#376](https://github.com/beautify-web/js-beautify/pull/376))
* Preserve newlines in html related to issue #307 ([#375](https://github.com/beautify-web/js-beautify/pull/375))
* Multi-line statements ([#374](https://github.com/beautify-web/js-beautify/issues/374))
* Reserved words used as property/function/variable identifiers are formatted incorrectly ([#368](https://github.com/beautify-web/js-beautify/issues/368))
* fixed problems with colon character ([#363](https://github.com/beautify-web/js-beautify/pull/363))
* require.JS paths are hardcoded in beautify-html.js ([#359](https://github.com/beautify-web/js-beautify/issues/359))
* Regression in p.a.c.ked file detection ([#357](https://github.com/beautify-web/js-beautify/issues/357))
* Fix Issue #339 ([#354](https://github.com/beautify-web/js-beautify/pull/354))
* Added single line comment support in less/sass for javascript parser ([#353](https://github.com/beautify-web/js-beautify/pull/353))
* Function named 'in' not formatting correctly ([#351](https://github.com/beautify-web/js-beautify/issues/351))
* CSS Pseudo element ([#346](https://github.com/beautify-web/js-beautify/issues/346))
* array closing brace error for return statements with keep_array_indentation ([#340](https://github.com/beautify-web/js-beautify/issues/340))
* CSS Beautifier: breaks :before and :after (regression) ([#339](https://github.com/beautify-web/js-beautify/issues/339))
* Publish v1.5.0 ([#335](https://github.com/beautify-web/js-beautify/issues/335))
* "keep array indentation" not working ([#333](https://github.com/beautify-web/js-beautify/issues/333))
* CSS Beautifier: support LESS/SASS line comments ([#326](https://github.com/beautify-web/js-beautify/issues/326))
* Incorrect formating with semicolon-less code ([#323](https://github.com/beautify-web/js-beautify/issues/323))
## v1.4.2
### Description
Release quick fix for python errno error that has started being more heavily reported
Initial release of css beautifier ported to python
Additional minor fixes and enhancements
### Closed Issues
* global name 'errno' is not defined ([#352](https://github.com/beautify-web/js-beautify/issues/352))
* import errno for errno.EEXIST ([#349](https://github.com/beautify-web/js-beautify/pull/349))
* Added bower.json ([#343](https://github.com/beautify-web/js-beautify/pull/343))
* HTML wrap-line-length: 0 doesn't work ([#342](https://github.com/beautify-web/js-beautify/issues/342))
* Make beautify.js, beautify-html.js, beautify-css.js available in bower ([#341](https://github.com/beautify-web/js-beautify/issues/341))
* Making .jsbeautifyrc resolve work (in general and for Windows re home dir) ([#334](https://github.com/beautify-web/js-beautify/pull/334))
* windows 8 error: path.js:204 throw new TypeError('Arguments to path.join must be strings'); ([#300](https://github.com/beautify-web/js-beautify/issues/300))
* Port beautify-css to python ([#204](https://github.com/beautify-web/js-beautify/issues/204))
## v1.4.1
### Description
Incremental fixes and improvements
### Closed Issues
* Tests borked when running from web ([#332](https://github.com/beautify-web/js-beautify/issues/332))
* wrap_line_length isn't enforced for property values ([#331](https://github.com/beautify-web/js-beautify/issues/331))
* Have no empty line between comment and function ([#329](https://github.com/beautify-web/js-beautify/issues/329))
* Add new line at the end of the file (html-beautify) ([#325](https://github.com/beautify-web/js-beautify/issues/325))
* Space in empty parentheses ([#322](https://github.com/beautify-web/js-beautify/pull/322))
* Handlebars ([#321](https://github.com/beautify-web/js-beautify/pull/321))
* Space in empty parentheses ([#320](https://github.com/beautify-web/js-beautify/issues/320))
* The indent_with_tabs option did not work when required in node, only CLI. ([#319](https://github.com/beautify-web/js-beautify/pull/319))
* add option to indent "inner HTML"... ([#312](https://github.com/beautify-web/js-beautify/pull/312))
* Wrong format of HTML textnode containing multipe words ([#306](https://github.com/beautify-web/js-beautify/issues/306))
* Repair to work in windows ([#304](https://github.com/beautify-web/js-beautify/pull/304))
* make export object the same with common and amd methods ([#303](https://github.com/beautify-web/js-beautify/pull/303))
* jshint cleanup and make require.js optimizable ([#302](https://github.com/beautify-web/js-beautify/pull/302))
* E4X xml-literal allowed xml-characters ([#294](https://github.com/beautify-web/js-beautify/pull/294))
* Publish 1.4.1 ([#292](https://github.com/beautify-web/js-beautify/issues/292))
* Blank line inserted between function and preceding comment ([#291](https://github.com/beautify-web/js-beautify/issues/291))
* Add tests for beautify-html.js ([#211](https://github.com/beautify-web/js-beautify/issues/211))
## v1.4.0
### Description
Given the breadth of the changes in the code and api, bump to 1.4.0 for the next release.
https://github.com/einars/js-beautify/compare/v1.3.4...v1.4.0
### Closed Issues
* Fix major performance degradation from minimal indenting ([#288](https://github.com/beautify-web/js-beautify/issues/288))
* Minimal indenting ([#286](https://github.com/beautify-web/js-beautify/pull/286))
* Empty lines are removed in HTML and CSS, and also adds trailing spaces ([#285](https://github.com/beautify-web/js-beautify/issues/285))
* npmjs cli options incomplete ([#283](https://github.com/beautify-web/js-beautify/issues/283))
* Publish 1.4.0 ([#282](https://github.com/beautify-web/js-beautify/issues/282))
* Blocks, arrays, and expressions over indented ([#281](https://github.com/beautify-web/js-beautify/issues/281))
* Keeping New lines inside markup ([#280](https://github.com/beautify-web/js-beautify/issues/280))
* E4X xml-literal small fixes ([#279](https://github.com/beautify-web/js-beautify/pull/279))
* Add support for Asynchronous Module Definition (AMD) API ([#274](https://github.com/beautify-web/js-beautify/pull/274))
* fixed broken run tests script ([#255](https://github.com/beautify-web/js-beautify/pull/255))
* Ending parenthesis in function call ([#239](https://github.com/beautify-web/js-beautify/issues/239))
* Preventing line breaks around Unformatted tags ([#105](https://github.com/beautify-web/js-beautify/issues/105))
* IE conditional HTML comments don't play well with the rest of the document ([#91](https://github.com/beautify-web/js-beautify/issues/91))
+139
View File
@@ -0,0 +1,139 @@
# Contributing
## Report Issues and Request Changes
If you find a bug, please report it, including environment and examples of current behavior and what you believe to be the correct behavior. The clearer your description and information, the more likely it is someone will be able to make progress on it. The default issue template will help guide you through this.
## How to Make Changes (Implement Fixes and New Features)
Fixes and enhancements are totally welcome. We prefer if you file an issue before filing a PR, as this gives us chance to discuss design details, but fee free to dive right in.
### 1. Build and Test Locally
While developing, you may build and test locally in JavaScript or Python implementation. The HTML beautifier is only implemented in JavaScript.
* Familiarize yourself with the folder structure and code style before you dive in.
* Make changes to the implemnation of your choice
* Add tests to `/test/data/*/test.js`.
* Run `./build jstest` or `./build pytest` to run style checks, and to generate and run tests.
* Include all changed files in your commit - The generated test files are checked in along with changes to the test data files.
### 2. Ensure Feature Parity
You must port changes to the other implementation. **This is required**. Every time we make an exception to this requirement the project becomes harder to maintain. If you find yourself making changes and find you cannot port them to the other implementation due to implmentations being out of sync, you will begin to understand why this is required. We made this a requirement several years ago and there are still a open issues for changes that people at the time promised to port "in the next week or two". The entire HTML beautifier is an example of this. :(
The implementations are already very similar and neither Python nor JavaScript are that hard to understand. Take the plunge, it is easier than you think. If you get stuck, move on to filing a Pull Request and we can discuss how to move forward.
* Run `./build` (with no parameters) to run style checks, and to generate and run tests on both implementations.
* Include all changed files in your commit - The generated test files are checked in along with changes to the test data files.
### 3. Update Documentation and Tools
Update documentation as needed. This such as the README.md, internal command-line help, and file comments.
Also, check your change needs any tooling updates. For example, the CDN urls required added scripting to update automatically for new releases.
### 4. Submit a Pull Request
* Run `./build full` locally after commit but before creation of Pull Request. You may start a Pull Request if this does not succeed, but the PR will not be accepted without additional changes.
* Include description of changes. Include examples of input and expected output if possible.
* Pull requests must pass build checks on all platforms before being accepted. We use travis-ci and appveyor to run tests on Linux and Windows, across multiple versions of Node.js and Python.
# Folders
## Root
Some files related to specific implementations or platforms are found in the root folder, but most are cross-project tools and configuration.
## js
Files related to the JavaScript implmentations of the beautifiers.
## python
Files related to the Python implmentations of the beautifiers.
## web
Files related to http://jsbeautifier.org/.
## test
Test data files and support files used to generate implmentation-specific test files from them.
# Branches
We use the `master` branch as the primrary development branch.
## Releases
Each platform has a branch that tracks to the latest release of that platform.
* `python-stable`
* `node-stable`
* `gh-pages`
## Functional Parity
Keeping the platforms in some semblance of functional parity is one of the key features of this project. As such, there branches for the last time synchronization occured and when it stablized.
* `sync`
* `sync-stable`
## Attic
This project has been around for a while. While some parts have improved significantly over time, others fell
into disrepair and were mothballed.
### PHP
There is an out-of-date version of the beautifier available on branch `attic-php`. If you're interested
in using it feel free. If you plan to enhance it, please consider joining this project, and updating this
version to match current functionality.
### Other Languages
Versions of the beautifier adapted to other languages are at least two years out-of-date and are
available on branch `attic-other`. Take a look and feel free to resurrect them, but know it's pretty
dusty back there.
### Generic Eval Unpacker
The `attic-genericeval` branch includes an unpacker that call `eval` on whatever source is passed to it.
Useful when working with source that unpacks itself when eval is called on it, but also unsafe. We keep
it on this separate branch to keep it from hurting the other children.
# Publishing a Release
Each platform has it's own release process.
NOTE: Before you do any of these make sure the latest changes have passed the travis-ci build!
##Web
Merge changes from `master` to `gh-pages` branch. This is very low cost and can be done whenever is convenient.
##Python
NOTE: For now, we'd like to keep python and node version numbers synchronized,
so if you publish a python release, you should publish a node release as well.
To perform these steps you will need:
1. A pypi user account from https://pypi.python.org/pypi?%3Aaction=register_form .
2. Permissions to the jsbeautifier package. File an issue here on github and the appropriate person will help you.
We basically follow the simplest release path found at http://docs.python.org/2/distutils/packageindex.html . :
```bash
git clean -xfd
# replace 0.0.1 with the actual version number you want to use
NEW_VERSION=0.0.1
echo "__version__ = '$NEW_VERSION'" > python/jsbeautifier/__version__.py
git commit -am "Python $NEW_VERSION"
cd python
python setup.py register
python setup.py sdist bdist_wininst upload
git push
```
##Node
NOTE: For now, we'd like to keep python and node version numbers synchronized,
so if you plan to publish a node release, you should publish a python release *first*,
then perform the steps below.
To perform these steps you will need:
1. An npmjs.org user account from https://npmjs.org/signup .
2. Permissions to the js-beautify module on npmjs.org. File an issue here on github and the appropriate person will help you.
Npm makes this process even simpler than python's and creates a tag for the release as well.
```bash
git clean -xfd
# replace 0.0.1 with the actual version number you want to use
NEW_VERSION=0.0.1
npm version $NEW_VERSION
npm publish .
git push --tags
```
+55
View File
@@ -0,0 +1,55 @@
# Description
> This is the default template for bug reports, if you have a more general
> issue, question, or request, you may ignore this template and write freeform.
>
> NOTE:
> * Do not include screenshots! This library is a text processor, we need text inputs and outputs for debugging and fixing issues.
> * Check the list of open issues before filing a new issue.
# Input
The code looked like this before beautification:
```
<INSERT CODE HERE>
```
# Expected Output
The code should have looked like this after beautification:
```
<INSERT CODE HERE>
```
# Actual Output
The code actually looked like this after beautification:
```
<INSERT CODE HERE>
```
# Steps to Reproduce
## Environment
OS:
## Settings
Example:
```json
{
"indent_size": 4,
"indent_char": " ",
"indent_level": 0,
"indent_with_tabs": false,
"preserve_newlines": true,
"max_preserve_newlines": 10,
"jslint_happy": false,
"space_after_anon_function": false,
"brace_style": "collapse,preserve-inline",
"keep_array_indentation": false,
"keep_function_indentation": false,
"space_before_conditional": true,
"break_chained_methods": false,
"eval_code": false,
"unescape_strings": false,
"wrap_line_length": 0
}
```
+9
View File
@@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright (c) 2007-2017 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.
+319
View File
@@ -0,0 +1,319 @@
# JS Beautifier
[![Build Status](https://img.shields.io/travis/beautify-web/js-beautify/master.svg)](http://travis-ci.org/beautify-web/js-beautify)
[![Build status](https://ci.appveyor.com/api/projects/status/5bxmpvew5n3e58te/branch/master?svg=true)](https://ci.appveyor.com/project/beautify-web/js-beautify/branch/master)
[![CDNJS version](https://img.shields.io/cdnjs/v/js-beautify.svg)](https://cdnjs.com/libraries/js-beautify)
[![NPM version](https://img.shields.io/npm/v/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
[![Download stats](https://img.shields.io/npm/dm/js-beautify.svg)](https://www.npmjs.com/package/js-beautify)
[![Join the chat at https://gitter.im/beautify-web/js-beautify](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/beautify-web/js-beautify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![NPM stats](https://nodei.co/npm/js-beautify.svg?downloadRank=true&downloads=true)](https://www.npmjs.org/package/js-beautify)
This little beautifier will reformat and reindent bookmarklets, ugly
JavaScript, unpack scripts packed by Dean Edwards popular packer,
as well as deobfuscate scripts processed by
[javascriptobfuscator.com](http://javascriptobfuscator.com/).
# Usage
You can beautify javascript using JS Beautifier in your web browser, or on the command-line using node.js or python.
JS Beautifier is hosted on two CDN services: [cdnjs](https://cdnjs.com/libraries/js-beautify) and rawgit.
To pull from one of these services include one set of the script tags below in your document:
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.14/beautify.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.14/beautify-css.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.14/beautify-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.14/beautify.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.14/beautify-css.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.14/beautify-html.min.js"></script>
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.6.14/js/lib/beautify.js"></script>
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.6.14/js/lib/beautify-css.js"></script>
<script src="https://cdn.rawgit.com/beautify-web/js-beautify/v1.6.14/js/lib/beautify-html.js"></script>
```
Disclaimer: These are free services, so there are [no uptime or support guarantees](https://github.com/rgrove/rawgit/wiki/Frequently-Asked-Questions#i-need-guaranteed-100-uptime-should-i-use-cdnrawgitcom).
## Web Browser
Open [jsbeautifier.org](http://jsbeautifier.org/). Options are available via the UI.
## Python
To beautify using python:
```bash
$ pip install jsbeautifier
$ js-beautify file.js
```
Beautified output goes to `stdout`.
To use `jsbeautifier` as a library is simple:
``` python
import jsbeautifier
res = jsbeautifier.beautify('your javascript string')
res = jsbeautifier.beautify_file('some_file.js')
```
...or, to specify some options:
``` python
opts = jsbeautifier.default_options()
opts.indent_size = 2
res = jsbeautifier.beautify('some javascript', opts)
```
## JavaScript
As an alternative to the Python script, you may install the NPM package `js-beautify`. When installed globally, it provides an executable `js-beautify` script. As with the Python script, the beautified result is sent to `stdout` unless otherwise configured.
```bash
$ npm -g install js-beautify
$ js-beautify foo.js
```
You can also use `js-beautify` as a `node` library (install locally, the `npm` default):
```bash
$ npm install js-beautify
```
```js
var beautify = require('js-beautify').js_beautify,
fs = require('fs');
fs.readFile('foo.js', 'utf8', function (err, data) {
if (err) {
throw err;
}
console.log(beautify(data, { indent_size: 2 }));
});
```
## Options
These are the command-line flags for both Python and JS scripts:
```text
CLI Options:
-f, --file Input file(s) (Pass '-' for stdin)
-r, --replace Write output in-place, replacing input
-o, --outfile Write output to file (default stdout)
--config Path to config file
--type [js|css|html] ["js"]
-q, --quiet Suppress logging to stdout
-h, --help Show this help
-v, --version Show the version
Beautifier Options:
-s, --indent-size Indentation size [4]
-c, --indent-char Indentation character [" "]
-t, --indent-with-tabs Indent with tabs, overrides -s and -c
-e, --eol Character(s) to use as line terminators.
[first newline in file, otherwise "\n]
-n, --end-with-newline End output with newline
--editorconfig Use EditorConfig to set up the options
-l, --indent-level Initial indentation level [0]
-p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)
-m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]
-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 Enable jslint-stricter mode
-a, --space-after-anon-function Add a space before an anonymous function's parens, ie. function ()
-b, --brace-style [collapse|expand|end-expand|none][,preserve-inline] [collapse,preserve-inline]
-B, --break-chained-methods Break chained method calls across subsequent lines
-k, --keep-array-indentation Preserve array indentation
-x, --unescape-strings Decode printable characters encoded in xNN notation
-w, --wrap-line-length Wrap lines at next opportunity after N characters [0]
-X, --e4x Pass E4X xml literals through untouched
--good-stuff Warm the cockles of Crockford's heart
-C, --comma-first Put commas at the beginning of new line instead of end
-O, --operator-position Set operator position (before-newline|after-newline|preserve-newline) [before-newline]
```
Which correspond to the underscored option keys for both library interfaces
**defaults per CLI options**
```json
{
"indent_size": 4,
"indent_char": " ",
"indent_with_tabs": false,
"eol": "\n",
"end_with_newline": false,
"indent_level": 0,
"preserve_newlines": true,
"max_preserve_newlines": 10,
"space_in_paren": false,
"space_in_empty_paren": false,
"jslint_happy": false,
"space_after_anon_function": false,
"brace_style": "collapse",
"break_chained_methods": false,
"keep_array_indentation": false,
"unescape_strings": false,
"wrap_line_length": 0,
"e4x": false,
"comma_first": false,
"operator_position": "before-newline"
}
```
**defaults not exposed in the cli**
```json
{
"eval_code": false,
"space_before_conditional": true
}
```
Notice not all defaults are exposed via the CLI. Historically, the Python and
JS APIs have not been 100% identical. For example, `space_before_conditional` is
currently JS-only, and not addressable from the CLI script. There are still a
few other additional cases keeping us from 100% API-compatibility.
### Loading settings from environment or .jsbeautifyrc (JavaScript-Only)
In addition to CLI arguments, you may pass config to the JS executable via:
* any `jsbeautify_`-prefixed environment variables
* a `JSON`-formatted file indicated by the `--config` parameter
* a `.jsbeautifyrc` file containing `JSON` data at any level of the filesystem above `$PWD`
Configuration sources provided earlier in this stack will override later ones.
### Setting inheritance and Language-specific overrides
The settings are a shallow tree whose values are inherited for all languages, but
can be overridden. This works for settings passed directly to the API in either implementation.
In the Javascript implementation, settings loaded from a config file, such as .jsbeautifyrc,
can also use inheritance/overriding.
Below is an example configuration tree showing all the supported locations
for language override nodes. We'll use `indent_size` to discuss how this configuration
would behave, but any number of settings can be inherited or overridden:
```json
{
"indent_size": 4,
"html": {
"end_with_newline": true,
"js": {
"indent_size": 2
},
"css": {
"indent_size": 2
}
},
"css": {
"indent_size": 1
},
"js": {
"preserve-newlines": true
}
}
```
Using the above example would have the following result:
* HTML files
* Inherit `indent_size` of 4 spaces from the top-level setting.
* The files would also end with a newline.
* JavaScript and CSS inside HTML
* Inherit the HTML `end_with_newline` setting
* Override their indentation to 2 spaces
* CSS files
* Override the top-level setting to an `indent_size` of 1 space.
* JavaScript files
* Inherit `indent_size` of 4 spaces from the top-level setting
* Set `preserve-newlines` to `true`
### CSS & HTML
In addition to the `js-beautify` executable, `css-beautify` and `html-beautify`
are also provided as an easy interface into those scripts. Alternatively,
`js-beautify --css` or `js-beautify --html` will accomplish the same thing, respectively.
```js
// Programmatic access
var beautify_js = require('js-beautify'); // also available under "js" export
var beautify_css = require('js-beautify').css;
var beautify_html = require('js-beautify').html;
// All methods accept two arguments, the string to be beautified, and an options object.
```
The CSS & HTML beautifiers are much simpler in scope, and possess far fewer options.
```text
CSS Beautifier Options:
-s, --indent-size Indentation size [4]
-c, --indent-char Indentation character [" "]
-t, --indent-with-tabs Indent with tabs, overrides -s and -c
-e, --eol Character(s) to use as line terminators. (default newline - "\\n")
-n, --end-with-newline End output with newline
-L, --selector-separator-newline Add a newline between multiple selectors
-N, --newline-between-rules Add a newline between CSS rules
HTML Beautifier Options:
-s, --indent-size Indentation size [4]
-c, --indent-char Indentation character [" "]
-t, --indent-with-tabs Indent with tabs, overrides -s and -c
-e, --eol Character(s) to use as line terminators. (default newline - "\\n")
-n, --end-with-newline End output with newline
-p, --preserve-newlines Preserve existing line-breaks (--no-preserve-newlines disables)
-m, --max-preserve-newlines Maximum number of line-breaks to be preserved in one chunk [10]
-I, --indent-inner-html Indent <head> and <body> sections. Default is false.
-b, --brace-style [collapse-preserve-inline|collapse|expand|end-expand|none] ["collapse"]
-S, --indent-scripts [keep|separate|normal] ["normal"]
-w, --wrap-line-length Maximum characters per line (0 disables) [250]
-A, --wrap-attributes Wrap attributes to new lines [auto|force|force-aligned|force-expand-multiline] ["auto"]
-i, --wrap-attributes-indent-size Indent wrapped attributes to after N characters [indent-size] (ignored if wrap-attributes is "force-aligned")
-U, --unformatted List of tags (defaults to inline) that should not be reformatted
-T, --content_unformatted List of tags (defaults to pre) that its content should not be reformatted
-E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline before them.
--editorconfig Use EditorConfig to set up the options
```
## Directives to Ignore or Preserve sections (Javascript only)
Beautifier for supports directives in comments inside the file.
This allows you to tell the beautifier to preserve the formatting of or completely ignore part of a file.
The example input below will remain changed after beautification
```js
// Use preserve when the content is not javascript, but you don't want it reformatted.
/* beautify preserve:start */
{
browserName: 'internet explorer',
platform: 'Windows 7',
version: '8'
}
/* beautify preserve:end */
// Use ignore when the content is not parsable as javascript.
var a = 1;
/* beautify ignore:start */
{This is some strange{template language{using open-braces?
/* beautify ignore:end */
```
# License
You are free to use this in any way you want, in case you find this
useful or working for you but you must keep the copyright notice and license. (MIT)
# Credits
* Created by Einar Lielmanis, <einar@jsbeautifier.org>
* Python version flourished by Stefano Sanfilippo <a.little.coder@gmail.com>
* Command-line for node.js by Daniel Stockman <daniel.stockman@gmail.com>
* Maintained and expanded by Liam Newman <bitwiseman@gmail.com>
Thanks also to Jason Diamond, Patrick Hof, Nochum Sossonko, Andreas Schneider, Dave
Vasilevsky, Vital Batmanov, Ron Baldwin, Gabriel Harrison, Chris J. Shull,
Mathias Bynens, Vittorio Gambaletta and others.
(README.md: js-beautify@1.6.14)
+35
View File
@@ -0,0 +1,35 @@
version: 1.6+{build}
nuget:
disable_publish_on_pr: true
deploy: off
# Test against this version of Node.js
environment:
global:
nodejs_version: "0.12"
matrix:
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x"
PYTHON_ARCH: "32"
# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- pip --version
# Post-install test scripts.
test_script:
# Output useful info for debugging.
- node --version
- npm --version
- python --version
# run tests
- bash -c "./build ci"
# Don't actually build.
build: off
+11
View File
@@ -0,0 +1,11 @@
{
"name": "js-beautify",
"main": [
"./js/lib/beautify.js",
"./js/lib/beautify-css.js",
"./js/lib/beautify-html.js"
],
"ignore": [
"**/.*"
]
}
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
REL_SCRIPT_DIR="`dirname \"$0\"`"
SCRIPT_DIR="`( cd \"$REL_SCRIPT_DIR\" && pwd )`"
$SCRIPT_DIR/tools/build.sh $*
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env node
var cli = require('../lib/cli'); cli.interpret();
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env node
var cli = require('../lib/cli'); cli.interpret();
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env node
var cli = require('../lib/cli');
cli.interpret();
+18
View File
@@ -0,0 +1,18 @@
{
"indent_size": 4,
"indent_char": " ",
"indent_level": 0,
"indent_with_tabs": false,
"preserve_newlines": true,
"max_preserve_newlines": 10,
"jslint_happy": false,
"space_after_anon_function": false,
"brace_style": "collapse",
"keep_array_indentation": false,
"keep_function_indentation": false,
"space_before_conditional": true,
"break_chained_methods": false,
"eval_code": false,
"unescape_strings": false,
"wrap_line_length": 0
}
+81
View File
@@ -0,0 +1,81 @@
/*
The MIT License (MIT)
Copyright (c) 2007-2017 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.
*/
/**
The following batches are equivalent:
var beautify_js = require('js-beautify');
var beautify_js = require('js-beautify').js;
var beautify_js = require('js-beautify').js_beautify;
var beautify_css = require('js-beautify').css;
var beautify_css = require('js-beautify').css_beautify;
var beautify_html = require('js-beautify').html;
var beautify_html = require('js-beautify').html_beautify;
All methods returned accept two arguments, the source string and an options object.
**/
function get_beautify(js_beautify, css_beautify, html_beautify) {
// the default is js
var beautify = function(src, config) {
return js_beautify.js_beautify(src, config);
};
// short aliases
beautify.js = js_beautify.js_beautify;
beautify.css = css_beautify.css_beautify;
beautify.html = html_beautify.html_beautify;
// legacy aliases
beautify.js_beautify = js_beautify.js_beautify;
beautify.css_beautify = css_beautify.css_beautify;
beautify.html_beautify = html_beautify.html_beautify;
return beautify;
}
if (typeof define === "function" && define.amd) {
// Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
define([
"./lib/beautify",
"./lib/beautify-css",
"./lib/beautify-html"
], function(js_beautify, css_beautify, html_beautify) {
return get_beautify(js_beautify, css_beautify, html_beautify);
});
} else {
(function(mod) {
var js_beautify = require('./lib/beautify');
var css_beautify = require('./lib/beautify-css');
var html_beautify = require('./lib/beautify-html');
mod.exports = get_beautify(js_beautify, css_beautify, html_beautify);
})(module);
}
+571
View File
@@ -0,0 +1,571 @@
/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
/*
The MIT License (MIT)
Copyright (c) 2007-2017 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.
CSS Beautifier
---------------
Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)
Based on code initially developed by: Einar Lielmanis, <einar@jsbeautifier.org>
http://jsbeautifier.org/
Usage:
css_beautify(source_text);
css_beautify(source_text, options);
The options are (default in brackets):
indent_size (4) — indentation size,
indent_char (space) — character to indent with,
preserve_newlines (default false) - whether existing line breaks should be preserved,
selector_separator_newline (true) - separate selectors with newline or
not (e.g. "a,\nbr" or "a, br")
end_with_newline (false) - end with a newline
newline_between_rules (true) - add a new line after every css rule
space_around_selector_separator (false) - ensure space around selector separators:
'>', '+', '~' (e.g. "a>b" -> "a > b")
e.g
css_beautify(css_source_text, {
'indent_size': 1,
'indent_char': '\t',
'selector_separator': ' ',
'end_with_newline': false,
'newline_between_rules': true,
'space_around_selector_separator': true
});
*/
// http://www.w3.org/TR/CSS21/syndata.html#tokenization
// http://www.w3.org/TR/css3-syntax/
(function() {
function mergeOpts(allOptions, targetType) {
var finalOpts = {};
var name;
for (name in allOptions) {
if (name !== targetType) {
finalOpts[name] = allOptions[name];
}
}
//merge in the per type settings for the targetType
if (targetType in allOptions) {
for (name in allOptions[targetType]) {
finalOpts[name] = allOptions[targetType][name];
}
}
return finalOpts;
}
var lineBreak = /\r\n|[\n\r\u2028\u2029]/;
var allLineBreaks = new RegExp(lineBreak.source, 'g');
function css_beautify(source_text, options) {
options = options || {};
// Allow the setting of language/file-type specific options
// with inheritance of overall settings
options = mergeOpts(options, 'css');
source_text = source_text || '';
var newlinesFromLastWSEat = 0;
var indentSize = options.indent_size ? parseInt(options.indent_size, 10) : 4;
var indentCharacter = options.indent_char || ' ';
var preserve_newlines = (options.preserve_newlines === undefined) ? false : options.preserve_newlines;
var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
var space_around_combinator = (options.space_around_combinator === undefined) ? false : options.space_around_combinator;
space_around_combinator = space_around_combinator || ((options.space_around_selector_separator === undefined) ? false : options.space_around_selector_separator);
var eol = options.eol ? options.eol : 'auto';
if (options.indent_with_tabs) {
indentCharacter = '\t';
indentSize = 1;
}
if (eol === 'auto') {
eol = '\n';
if (source_text && lineBreak.test(source_text || '')) {
eol = source_text.match(lineBreak)[0];
}
}
eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
// HACK: newline parsing inconsistent. This brute force normalizes the input.
source_text = source_text.replace(allLineBreaks, '\n');
// tokenizer
var whiteRe = /^\s+$/;
var pos = -1,
ch;
var parenLevel = 0;
function next() {
ch = source_text.charAt(++pos);
return ch || '';
}
function peek(skipWhitespace) {
var result = '';
var prev_pos = pos;
if (skipWhitespace) {
eatWhitespace();
}
result = source_text.charAt(pos + 1) || '';
pos = prev_pos - 1;
next();
return result;
}
function eatString(endChars) {
var start = pos;
while (next()) {
if (ch === "\\") {
next();
} else if (endChars.indexOf(ch) !== -1) {
break;
} else if (ch === "\n") {
break;
}
}
return source_text.substring(start, pos + 1);
}
function peekString(endChar) {
var prev_pos = pos;
var str = eatString(endChar);
pos = prev_pos - 1;
next();
return str;
}
function eatWhitespace(preserve_newlines_local) {
var result = 0;
while (whiteRe.test(peek())) {
next();
if (ch === '\n' && preserve_newlines_local && preserve_newlines) {
print.newLine(true);
result++;
}
}
newlinesFromLastWSEat = result;
return result;
}
function skipWhitespace() {
var result = '';
if (ch && whiteRe.test(ch)) {
result = ch;
}
while (whiteRe.test(next())) {
result += ch;
}
return result;
}
function eatComment(singleLine) {
var start = pos;
singleLine = peek() === "/";
next();
while (next()) {
if (!singleLine && ch === "*" && peek() === "/") {
next();
break;
} else if (singleLine && ch === "\n") {
return source_text.substring(start, pos);
}
}
return source_text.substring(start, pos) + ch;
}
function lookBack(str) {
return source_text.substring(pos - str.length, pos).toLowerCase() ===
str;
}
// Nested pseudo-class if we are insideRule
// and the next special character found opens
// a new block
function foundNestedPseudoClass() {
var openParen = 0;
for (var i = pos + 1; i < source_text.length; i++) {
var ch = source_text.charAt(i);
if (ch === "{") {
return true;
} else if (ch === '(') {
// pseudoclasses can contain ()
openParen += 1;
} else if (ch === ')') {
if (openParen === 0) {
return false;
}
openParen -= 1;
} else if (ch === ";" || ch === "}") {
return false;
}
}
return false;
}
// printer
var basebaseIndentString = source_text.match(/^[\t ]*/)[0];
var singleIndent = new Array(indentSize + 1).join(indentCharacter);
var indentLevel = 0;
var nestedLevel = 0;
function indent() {
indentLevel++;
basebaseIndentString += singleIndent;
}
function outdent() {
indentLevel--;
basebaseIndentString = basebaseIndentString.slice(0, -indentSize);
}
var print = {};
print["{"] = function(ch) {
print.singleSpace();
output.push(ch);
if (!eatWhitespace(true)) {
print.newLine();
}
};
print["}"] = function(newline) {
if (newline) {
print.newLine();
}
output.push('}');
if (!eatWhitespace(true)) {
print.newLine();
}
};
print._lastCharWhitespace = function() {
return whiteRe.test(output[output.length - 1]);
};
print.newLine = function(keepWhitespace) {
if (output.length) {
if (!keepWhitespace && output[output.length - 1] !== '\n') {
print.trim();
} else if (output[output.length - 1] === basebaseIndentString) {
output.pop();
}
output.push('\n');
if (basebaseIndentString) {
output.push(basebaseIndentString);
}
}
};
print.singleSpace = function() {
if (output.length && !print._lastCharWhitespace()) {
output.push(' ');
}
};
print.preserveSingleSpace = function() {
if (isAfterSpace) {
print.singleSpace();
}
};
print.trim = function() {
while (print._lastCharWhitespace()) {
output.pop();
}
};
var output = [];
/*_____________________--------------------_____________________*/
var insideRule = false;
var insidePropertyValue = false;
var enteringConditionalGroup = false;
var top_ch = '';
var last_top_ch = '';
while (true) {
var whitespace = skipWhitespace();
var isAfterSpace = whitespace !== '';
var isAfterNewline = whitespace.indexOf('\n') !== -1;
last_top_ch = top_ch;
top_ch = ch;
if (!ch) {
break;
} else if (ch === '/' && peek() === '*') { /* css comment */
var header = indentLevel === 0;
if (isAfterNewline || header) {
print.newLine();
}
output.push(eatComment());
print.newLine();
if (header) {
print.newLine(true);
}
} else if (ch === '/' && peek() === '/') { // single line comment
if (!isAfterNewline && last_top_ch !== '{') {
print.trim();
}
print.singleSpace();
output.push(eatComment());
print.newLine();
} else if (ch === '@') {
print.preserveSingleSpace();
// deal with less propery mixins @{...}
if (peek() === '{') {
output.push(eatString('}'));
} else {
output.push(ch);
// strip trailing space, if present, for hash property checks
var variableOrRule = peekString(": ,;{}()[]/='\"");
if (variableOrRule.match(/[ :]$/)) {
// we have a variable or pseudo-class, add it and insert one space before continuing
next();
variableOrRule = eatString(": ").replace(/\s$/, '');
output.push(variableOrRule);
print.singleSpace();
}
variableOrRule = variableOrRule.replace(/\s$/, '');
// might be a nesting at-rule
if (variableOrRule in css_beautify.NESTED_AT_RULE) {
nestedLevel += 1;
if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) {
enteringConditionalGroup = true;
}
}
}
} else if (ch === '#' && peek() === '{') {
print.preserveSingleSpace();
output.push(eatString('}'));
} else if (ch === '{') {
if (peek(true) === '}') {
eatWhitespace();
next();
print.singleSpace();
output.push("{");
print['}'](false);
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
print.newLine(true);
}
} else {
indent();
print["{"](ch);
// when entering conditional groups, only rulesets are allowed
if (enteringConditionalGroup) {
enteringConditionalGroup = false;
insideRule = (indentLevel > nestedLevel);
} else {
// otherwise, declarations are also allowed
insideRule = (indentLevel >= nestedLevel);
}
}
} else if (ch === '}') {
outdent();
print["}"](true);
insideRule = false;
insidePropertyValue = false;
if (nestedLevel) {
nestedLevel--;
}
if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
print.newLine(true);
}
} else if (ch === ":") {
eatWhitespace();
if ((insideRule || enteringConditionalGroup) &&
!(lookBack("&") || foundNestedPseudoClass()) &&
!lookBack("(")) {
// 'property: value' delimiter
// which could be in a conditional group query
output.push(':');
if (!insidePropertyValue) {
insidePropertyValue = true;
print.singleSpace();
}
} else {
// sass/less parent reference don't use a space
// sass nested pseudo-class don't use a space
// preserve space before pseudoclasses/pseudoelements, as it means "in any child"
if (lookBack(" ") && output[output.length - 1] !== " ") {
output.push(" ");
}
if (peek() === ":") {
// pseudo-element
next();
output.push("::");
} else {
// pseudo-class
output.push(':');
}
}
} else if (ch === '"' || ch === '\'') {
print.preserveSingleSpace();
output.push(eatString(ch));
} else if (ch === ';') {
insidePropertyValue = false;
output.push(ch);
if (!eatWhitespace(true)) {
print.newLine();
}
} else if (ch === '(') { // may be a url
if (lookBack("url")) {
output.push(ch);
eatWhitespace();
if (next()) {
if (ch !== ')' && ch !== '"' && ch !== '\'') {
output.push(eatString(')'));
} else {
pos--;
}
}
} else {
parenLevel++;
print.preserveSingleSpace();
output.push(ch);
eatWhitespace();
}
} else if (ch === ')') {
output.push(ch);
parenLevel--;
} else if (ch === ',') {
output.push(ch);
if (!eatWhitespace(true) && selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
print.newLine();
} else {
print.singleSpace();
}
} else if ((ch === '>' || ch === '+' || ch === '~') &&
!insidePropertyValue && parenLevel < 1) {
//handle combinator spacing
if (space_around_combinator) {
print.singleSpace();
output.push(ch);
print.singleSpace();
} else {
output.push(ch);
eatWhitespace();
// squash extra whitespace
if (ch && whiteRe.test(ch)) {
ch = '';
}
}
} else if (ch === ']') {
output.push(ch);
} else if (ch === '[') {
print.preserveSingleSpace();
output.push(ch);
} else if (ch === '=') { // no whitespace before or after
eatWhitespace();
output.push('=');
if (whiteRe.test(ch)) {
ch = '';
}
} else {
print.preserveSingleSpace();
output.push(ch);
}
}
var sweetCode = '';
if (basebaseIndentString) {
sweetCode += basebaseIndentString;
}
sweetCode += output.join('').replace(/[\r\n\t ]+$/, '');
// establish end_with_newline
if (end_with_newline) {
sweetCode += '\n';
}
if (eol !== '\n') {
sweetCode = sweetCode.replace(/[\n]/g, eol);
}
return sweetCode;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
css_beautify.NESTED_AT_RULE = {
"@page": true,
"@font-face": true,
"@keyframes": true,
// also in CONDITIONAL_GROUP_RULE below
"@media": true,
"@supports": true,
"@document": true
};
css_beautify.CONDITIONAL_GROUP_RULE = {
"@media": true,
"@supports": true,
"@document": true
};
/*global define */
if (typeof define === "function" && define.amd) {
// Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
define([], function() {
return {
css_beautify: css_beautify
};
});
} else if (typeof exports !== "undefined") {
// Add support for CommonJS. Just put this file somewhere on your require.paths
// and you will be able to `var html_beautify = require("beautify").html_beautify`.
exports.css_beautify = css_beautify;
} else if (typeof window !== "undefined") {
// If we're running a web page and don't have either of the above, add our one global
window.css_beautify = css_beautify;
} else if (typeof global !== "undefined") {
// If we don't even have window, try global.
global.css_beautify = css_beautify;
}
}());
+1128
View File
File diff suppressed because it is too large Load Diff
+2481
View File
File diff suppressed because it is too large Load Diff
+620
View File
@@ -0,0 +1,620 @@
#!/usr/bin/env node
/*
The MIT License (MIT)
Copyright (c) 2007-2017 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.
Js-Beautify Command-line for node.js
-------------------------------------
Written by Daniel Stockman (daniel.stockman@gmail.com)
*/
var debug = process.env.DEBUG_JSBEAUTIFY || process.env.JSBEAUTIFY_DEBUG ? function() {
console.error.apply(console, arguments);
} : function() {};
var fs = require('fs'),
cc = require('config-chain'),
beautify = require('../index'),
mkdirp = require('mkdirp'),
nopt = require('nopt');
nopt.typeDefs.brace_style = {
type: "brace_style",
validate: function(data, key, val) {
data[key] = val;
// TODO: expand-strict is obsolete, now identical to expand. Remove in future version
// TODO: collapse-preserve-inline is obselete, now identical to collapse,preserve-inline = true. Remove in future version
var validVals = ["collapse", "collapse-preserve-inline", "expand", "end-expand", "expand-strict", "none"];
var valSplit = val.split(/[^a-zA-Z0-9_\-]+/);
for (var i = 0; i < validVals.length; i++) {
if (validVals[i] === val || validVals[i] === valSplit[0] && valSplit[1] === "preserve-inline") {
return true;
}
}
return false;
}
};
var path = require('path'),
editorconfig = require('editorconfig'),
knownOpts = {
// Beautifier
"indent_size": Number,
"indent_char": String,
"eol": String,
"indent_level": Number,
"indent_with_tabs": Boolean,
"preserve_newlines": Boolean,
"max_preserve_newlines": Number,
"space_in_paren": Boolean,
"space_in_empty_paren": Boolean,
"jslint_happy": Boolean,
"space_after_anon_function": Boolean,
"brace_style": "brace_style", //See above for validation
"break_chained_methods": Boolean,
"keep_array_indentation": Boolean,
"unescape_strings": Boolean,
"wrap_line_length": Number,
"wrap_attributes": ["auto", "force", "force-aligned"],
"wrap_attributes_indent_size": Number,
"e4x": Boolean,
"end_with_newline": Boolean,
"comma_first": Boolean,
"operator_position": ["before-newline", "after-newline", "preserve-newline"],
// CSS-only
"selector_separator_newline": Boolean,
"newline_between_rules": Boolean,
"space_around_combinator": Boolean,
//deprecated - replaced with space_around_combinator, remove in future version
"space_around_selector_separator": Boolean,
// HTML-only
"max_char": Number, // obsolete since 1.3.5
"unformatted": [String, Array],
"content_unformatted": [String, Array],
"indent_inner_html": [Boolean],
"indent_handlebars": [Boolean],
"indent_scripts": ["keep", "separate", "normal"],
"extra_liners": [String, Array],
// CLI
"version": Boolean,
"help": Boolean,
"files": [path, Array],
"outfile": path,
"replace": Boolean,
"quiet": Boolean,
"type": ["js", "css", "html"],
"config": path,
"editorconfig": Boolean
},
// dasherizeShorthands provides { "indent-size": ["--indent_size"] }
// translation, allowing more convenient dashes in CLI arguments
shortHands = dasherizeShorthands({
// Beautifier
"s": ["--indent_size"],
"c": ["--indent_char"],
"e": ["--eol"],
"l": ["--indent_level"],
"t": ["--indent_with_tabs"],
"p": ["--preserve_newlines"],
"m": ["--max_preserve_newlines"],
"P": ["--space_in_paren"],
"Q": ["--space_in_empty_paren"],
"j": ["--jslint_happy"],
"a": ["--space_after_anon_function"],
"b": ["--brace_style"],
"B": ["--break_chained_methods"],
"k": ["--keep_array_indentation"],
"x": ["--unescape_strings"],
"w": ["--wrap_line_length"],
"X": ["--e4x"],
"n": ["--end_with_newline"],
"C": ["--comma_first"],
"O": ["--operator_position"],
// CSS-only
"L": ["--selector_separator_newline"],
"N": ["--newline_between_rules"],
// HTML-only
"A": ["--wrap_attributes"],
"i": ["--wrap_attributes_indent_size"],
"W": ["--max_char"], // obsolete since 1.3.5
"U": ["--unformatted"],
"T": ["--content_unformatted"],
"I": ["--indent_inner_html"],
"H": ["--indent_handlebars"],
"S": ["--indent_scripts"],
"E": ["--extra_liners"],
// non-dasherized hybrid shortcuts
"good-stuff": [
"--keep_array_indentation",
"--keep_function_indentation",
"--jslint_happy"
],
"js": ["--type", "js"],
"css": ["--type", "css"],
"html": ["--type", "html"],
// CLI
"v": ["--version"],
"h": ["--help"],
"f": ["--files"],
"o": ["--outfile"],
"r": ["--replace"],
"q": ["--quiet"]
// no shorthand for "config"
// no shorthand for "editorconfig"
});
function verifyExists(fullPath) {
return fs.existsSync(fullPath) ? fullPath : null;
}
function findRecursive(dir, fileName) {
var fullPath = path.join(dir, fileName);
var nextDir = path.dirname(dir);
var result = verifyExists(fullPath);
if (!result && (nextDir !== dir)) {
result = findRecursive(nextDir, fileName);
}
return result;
}
function getUserHome() {
var user_home = '';
try {
user_home = process.env.USERPROFILE || process.env.HOME || '';
} catch (ex) {}
return user_home;
}
function set_file_editorconfig_opts(file, config) {
try {
var eConfigs = editorconfig.parseSync(file);
if (eConfigs.indent_style === "tab") {
config.indent_with_tabs = true;
} else if (eConfigs.indent_style === "space") {
config.indent_with_tabs = false;
}
if (eConfigs.indent_size) {
config.indent_size = eConfigs.indent_size;
}
if (eConfigs.max_line_length) {
if (eConfigs.max_line_length === "off") {
config.wrap_line_length = 0;
} else {
config.wrap_line_length = parseInt(eConfigs.max_line_length);
}
}
if (eConfigs.insert_final_newline === true) {
config.end_with_newline = true;
} else if (eConfigs.insert_final_newline === false) {
config.end_with_newline = false;
}
if (eConfigs.end_of_line) {
if (eConfigs.end_of_line === 'cr') {
config.eol = '\r';
} else if (eConfigs.end_of_line === 'lf') {
config.eol = '\n';
} else if (eConfigs.end_of_line === 'crlf') {
config.eol = '\r\n';
}
}
} catch (e) {
debug(e);
}
}
// var cli = require('js-beautify/cli'); cli.interpret();
var interpret = exports.interpret = function(argv, slice) {
var parsed = nopt(knownOpts, shortHands, argv, slice);
if (parsed.version) {
console.log(require('../../package.json').version);
process.exit(0);
} else if (parsed.help) {
usage();
process.exit(0);
}
var cfg;
var configRecursive = findRecursive(process.cwd(), '.jsbeautifyrc');
var configHome = verifyExists(path.join(getUserHome() || "", ".jsbeautifyrc"));
var configDefault = __dirname + '/../config/defaults.json';
try {
cfg = cc(
parsed,
cleanOptions(cc.env('jsbeautify_'), knownOpts),
parsed.config,
configRecursive,
configHome,
configDefault
).snapshot;
} catch (ex) {
debug(cfg);
// usage(ex);
console.error(ex);
console.error('Error while loading beautifier configuration.');
console.error('Configuration file chain included:');
if (parsed.config) {
console.error(parsed.config);
}
if (configRecursive) {
console.error(configRecursive);
}
if (configHome) {
console.error(configHome);
}
console.error(configDefault);
console.error('Run `' + getScriptName() + ' -h` for help.');
process.exit(1);
}
try {
// Verify arguments
checkType(cfg);
checkFiles(cfg);
debug(cfg);
// Process files synchronously to avoid EMFILE error
cfg.files.forEach(processInputSync, {
cfg: cfg
});
} catch (ex) {
debug(cfg);
// usage(ex);
console.error(ex);
console.error('Run `' + getScriptName() + ' -h` for help.');
process.exit(1);
}
};
// interpret args immediately when called as executable
if (require.main === module) {
interpret();
}
function usage(err) {
var scriptName = getScriptName();
var msg = [
scriptName + '@' + require('../../package.json').version,
'',
'CLI Options:',
' -f, --file Input file(s) (Pass \'-\' for stdin)',
' -r, --replace Write output in-place, replacing input',
' -o, --outfile Write output to file (default stdout)',
' --config Path to config file',
' --type [js|css|html] ["js"]',
' -q, --quiet Suppress logging to stdout',
' -h, --help Show this help',
' -v, --version Show the version',
'',
'Beautifier Options:',
' -s, --indent-size Indentation size [4]',
' -c, --indent-char Indentation character [" "]',
' -t, --indent-with-tabs Indent with tabs, overrides -s and -c',
' -e, --eol Character(s) to use as line terminators.',
' [first newline in file, otherwise "\\n]',
' -n, --end-with-newline End output with newline',
' --editorconfig Use EditorConfig to set up the options'
];
switch (scriptName.split('-').shift()) {
case "js":
msg.push(' -l, --indent-level Initial indentation level [0]');
msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)');
msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]');
msg.push(' -P, --space-in-paren Add padding spaces within paren, ie. f( a, b )');
msg.push(' -E, --space-in-empty-paren Add a single space inside empty paren, ie. f( )');
msg.push(' -j, --jslint-happy Enable jslint-stricter mode');
msg.push(' -a, --space-after-anon-function Add a space before an anonymous function\'s parens, ie. function ()');
msg.push(' -b, --brace-style [collapse|expand|end-expand|none][,preserve-inline] [collapse,preserve-inline]');
msg.push(' -B, --break-chained-methods Break chained method calls across subsequent lines');
msg.push(' -k, --keep-array-indentation Preserve array indentation');
msg.push(' -x, --unescape-strings Decode printable characters encoded in xNN notation');
msg.push(' -w, --wrap-line-length Wrap lines at next opportunity after N characters [0]');
msg.push(' -X, --e4x Pass E4X xml literals through untouched');
msg.push(' --good-stuff Warm the cockles of Crockford\'s heart');
msg.push(' -C, --comma-first Put commas at the beginning of new line instead of end');
msg.push(' -O, --operator-position Set operator position (before-newline|after-newline|preserve-newline) [before-newline]');
break;
case "html":
msg.push(' -b, --brace-style [collapse|expand|end-expand] ["collapse"]');
msg.push(' -I, --indent-inner-html Indent body and head sections. Default is false.');
msg.push(' -H, --indent-handlebars Indent handlebars. Default is false.');
msg.push(' -S, --indent-scripts [keep|separate|normal] ["normal"]');
msg.push(' -w, --wrap-line-length Wrap lines at next opportunity after N characters [0]');
msg.push(' -A, --wrap-attributes Wrap html tag attributes to new lines [auto|force] ["auto"]');
msg.push(' -i, --wrap-attributes-indent-size Indent wrapped tags to after N characters [indent-level]');
msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)');
msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]');
msg.push(' -U, --unformatted List of tags (defaults to inline) that should not be reformatted');
msg.push(' -T, --content_unformatted List of tags (defaults to pre) that its content should not be reformatted');
msg.push(' -E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline');
break;
case "css":
msg.push(' -L, --selector-separator-newline Add a newline between multiple selectors.');
msg.push(' -N, --newline-between-rules Add a newline between CSS rules.');
}
if (err) {
msg.push(err);
msg.push('');
console.error(msg.join('\n'));
} else {
console.log(msg.join('\n'));
}
}
// main iterator, {cfg} passed as thisArg of forEach call
function processInputSync(filepath) {
var data = '',
config = this.cfg,
outfile = config.outfile,
input;
// -o passed with no value overwrites
if (outfile === true || config.replace) {
outfile = filepath;
}
var fileType = getOutputType(outfile, filepath, config.type);
if (config.editorconfig) {
var editorconfig_filepath = filepath;
if (editorconfig_filepath === '-') {
if (outfile) {
editorconfig_filepath = outfile;
} else {
editorconfig_filepath = 'stdin.' + fileType;
}
}
debug("EditorConfig is enabled for ", editorconfig_filepath);
config = cc(config).snapshot;
set_file_editorconfig_opts(editorconfig_filepath, config);
debug(config);
}
if (filepath === '-') {
input = process.stdin;
input.resume();
input.setEncoding('utf8');
input.on('data', function(chunk) {
data += chunk;
});
input.on('end', function() {
makePretty(fileType, data, config, outfile, writePretty); // Where things get beautified
});
} else {
data = fs.readFileSync(filepath, 'utf8');
makePretty(fileType, data, config, outfile, writePretty);
}
}
function makePretty(fileType, code, config, outfile, callback) {
try {
var pretty = beautify[fileType](code, config);
callback(null, pretty, outfile, config);
} catch (ex) {
callback(ex);
}
}
function writePretty(err, pretty, outfile, config) {
debug('writing ' + outfile);
if (err) {
console.error(err);
process.exit(1);
}
if (outfile) {
mkdirp.sync(path.dirname(outfile));
if (isFileDifferent(outfile, pretty)) {
try {
fs.writeFileSync(outfile, pretty, 'utf8');
logToStdout('beautified ' + path.relative(process.cwd(), outfile), config);
} catch (ex) {
onOutputError(ex);
}
} else {
logToStdout('beautified ' + path.relative(process.cwd(), outfile) + ' - unchanged', config);
}
} else {
process.stdout.write(pretty);
}
}
function isFileDifferent(filePath, expected) {
try {
return fs.readFileSync(filePath, 'utf8') !== expected;
} catch (ex) {
// failing to read is the same as different
return true;
}
}
// workaround the fact that nopt.clean doesn't return the object passed in :P
function cleanOptions(data, types) {
nopt.clean(data, types);
return data;
}
// error handler for output stream that swallows errors silently,
// allowing the loop to continue over unwritable files.
function onOutputError(err) {
if (err.code === 'EACCES') {
console.error(err.path + " is not writable. Skipping!");
} else {
console.error(err);
process.exit(0);
}
}
// turn "--foo_bar" into "foo-bar"
function dasherizeFlag(str) {
return str.replace(/^\-+/, '').replace(/_/g, '-');
}
// translate weird python underscored keys into dashed argv,
// avoiding single character aliases.
function dasherizeShorthands(hash) {
// operate in-place
Object.keys(hash).forEach(function(key) {
// each key value is an array
var val = hash[key][0];
// only dasherize one-character shorthands
if (key.length === 1 && val.indexOf('_') > -1) {
hash[dasherizeFlag(val)] = val;
}
});
return hash;
}
function getOutputType(outfile, filepath, configType) {
if (outfile && /\.(js|css|html)$/.test(outfile)) {
return outfile.split('.').pop();
} else if (filepath !== '-' && /\.(js|css|html)$/.test(filepath)) {
return filepath.split('.').pop();
} else if (configType) {
return configType;
} else {
throw 'Could not determine appropriate beautifier from file paths: ' + filepath;
}
}
function getScriptName() {
return path.basename(process.argv[1]);
}
function checkType(parsed) {
var scriptType = getScriptName().split('-').shift();
if (!/^(js|css|html)$/.test(scriptType)) {
scriptType = null;
}
debug("executable type:", scriptType);
var parsedType = parsed.type;
debug("parsed type:", parsedType);
if (!parsedType) {
debug("type defaulted:", scriptType);
parsed.type = scriptType;
}
}
function checkFiles(parsed) {
var argv = parsed.argv;
var isTTY = true;
try {
isTTY = process.stdin.isTTY;
} catch (ex) {
debug("error querying for isTTY:", ex);
}
debug('isTTY: ' + isTTY);
if (!parsed.files) {
parsed.files = [];
} else {
if (argv.cooked.indexOf('-') > -1) {
// strip stdin path eagerly added by nopt in '-f -' case
parsed.files.some(removeDashedPath);
}
}
if (argv.remain.length) {
// assume any remaining args are files
argv.remain.forEach(function(f) {
if (f !== '-') {
parsed.files.push(path.resolve(f));
}
});
}
if ('string' === typeof parsed.outfile && isTTY && !parsed.files.length) {
// use outfile as input when no other files passed in args
parsed.files.push(parsed.outfile);
// operation is now an implicit overwrite
parsed.replace = true;
}
if (!parsed.files.length) {
// read stdin by default
parsed.files.push('-');
}
debug('files.length ' + parsed.files.length);
if (parsed.files.indexOf('-') > -1 && isTTY) {
throw 'Must pipe input or define at least one file.';
}
parsed.files.forEach(testFilePath);
return parsed;
}
function removeDashedPath(filepath, i, arr) {
var found = filepath.lastIndexOf('-') === (filepath.length - 1);
if (found) {
arr.splice(i, 1);
}
return found;
}
function testFilePath(filepath) {
try {
if (filepath !== "-") {
fs.statSync(filepath);
}
} catch (err) {
throw 'Unable to open path "' + filepath + '"';
}
}
function logToStdout(str, config) {
if (typeof config.quiet === "undefined" || !config.quiet) {
console.log(str);
}
}
@@ -0,0 +1,103 @@
//
// simple unpacker/deobfuscator for scripts messed up with javascriptobfuscator.com
// written by Einar Lielmanis <einar@jsbeautifier.org>
//
// usage:
//
// if (JavascriptObfuscator.detect(some_string)) {
// var unpacked = JavascriptObfuscator.unpack(some_string);
// }
//
//
var JavascriptObfuscator = {
detect: function(str) {
return /^var _0x[a-f0-9]+ ?\= ?\[/.test(str);
},
unpack: function(str) {
if (JavascriptObfuscator.detect(str)) {
var matches = /var (_0x[a-f\d]+) ?\= ?\[(.*?)\];/.exec(str);
if (matches) {
var var_name = matches[1];
var strings = JavascriptObfuscator._smart_split(matches[2]);
str = str.substring(matches[0].length);
for (var k in strings) {
str = str.replace(new RegExp(var_name + '\\[' + k + '\\]', 'g'),
JavascriptObfuscator._fix_quotes(JavascriptObfuscator._unescape(strings[k])));
}
}
}
return str;
},
_fix_quotes: function(str) {
var matches = /^"(.*)"$/.exec(str);
if (matches) {
str = matches[1];
str = "'" + str.replace(/'/g, "\\'") + "'";
}
return str;
},
_smart_split: function(str) {
var strings = [];
var pos = 0;
while (pos < str.length) {
if (str.charAt(pos) === '"') {
// new word
var word = '';
pos += 1;
while (pos < str.length) {
if (str.charAt(pos) === '"') {
break;
}
if (str.charAt(pos) === '\\') {
word += '\\';
pos++;
}
word += str.charAt(pos);
pos++;
}
strings.push('"' + word + '"');
}
pos += 1;
}
return strings;
},
_unescape: function(str) {
// inefficient if used repeatedly or on small strings, but wonderful on single large chunk of text
for (var i = 32; i < 128; i++) {
str = str.replace(new RegExp('\\\\x' + i.toString(16), 'ig'), String.fromCharCode(i));
}
str = str.replace(/\\x09/g, "\t");
return str;
},
run_tests: function(sanity_test) {
var t = sanity_test || new SanityTest();
t.test_function(JavascriptObfuscator._smart_split, "JavascriptObfuscator._smart_split");
t.expect('', []);
t.expect('"a", "b"', ['"a"', '"b"']);
t.expect('"aaa","bbbb"', ['"aaa"', '"bbbb"']);
t.expect('"a", "b\\\""', ['"a"', '"b\\\""']);
t.test_function(JavascriptObfuscator._unescape, 'JavascriptObfuscator._unescape');
t.expect('\\x40', '@');
t.expect('\\x10', '\\x10');
t.expect('\\x1', '\\x1');
t.expect("\\x61\\x62\\x22\\x63\\x64", 'ab"cd');
t.test_function(JavascriptObfuscator.detect, 'JavascriptObfuscator.detect');
t.expect('', false);
t.expect('abcd', false);
t.expect('var _0xaaaa', false);
t.expect('var _0xaaaa = ["a", "b"]', true);
t.expect('var _0xaaaa=["a", "b"]', true);
t.expect('var _0x1234=["a","b"]', true);
return t;
}
};
+90
View File
@@ -0,0 +1,90 @@
//
// simple unpacker/deobfuscator for scripts messed up with myobfuscate.com
// 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-04-25:
/*
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));
*/
//
// written by Einar Lielmanis <einar@jsbeautifier.org>
//
// usage:
//
// if (MyObfuscate.detect(some_string)) {
// var unpacked = MyObfuscate.unpack(some_string);
// }
//
//
var MyObfuscate = {
detect: function(str) {
if (/^var _?[0O1lI]{3}\=('|\[).*\)\)\);/.test(str)) {
return true;
}
if (/^function _?[0O1lI]{3}\(_/.test(str) && /eval\(/.test(str)) {
return true;
}
return false;
},
unpack: function(str) {
if (MyObfuscate.detect(str)) {
var __eval = eval;
try {
eval = function(unpacked) { // jshint ignore:line
if (MyObfuscate.starts_with(unpacked, 'var _escape')) {
// fetch the urlencoded stuff from the script,
var matches = /'([^']*)'/.exec(unpacked);
var unescaped = unescape(matches[1]);
if (MyObfuscate.starts_with(unescaped, '<script>')) {
unescaped = unescaped.substr(8, unescaped.length - 8);
}
if (MyObfuscate.ends_with(unescaped, '</script>')) {
unescaped = unescaped.substr(0, unescaped.length - 9);
}
unpacked = unescaped;
}
// throw to terminate the script
unpacked = "// Unpacker warning: be careful when using myobfuscate.com for your projects:\n" +
"// scripts obfuscated by the free online version may call back home.\n" +
"\n//\n" + unpacked;
throw unpacked;
}; // jshint ignore:line
__eval(str); // should throw
} catch (e) {
// well, it failed. we'll just return the original, instead of crashing on user.
if (typeof e === "string") {
str = e;
}
}
eval = __eval; // jshint ignore:line
}
return str;
},
starts_with: function(str, what) {
return str.substr(0, what.length) === what;
},
ends_with: function(str, what) {
return str.substr(str.length - what.length, what.length) === what;
},
run_tests: function(sanity_test) {
var t = sanity_test || new SanityTest();
return t;
}
};
+83
View File
@@ -0,0 +1,83 @@
//
// Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier
// written by Einar Lielmanis <einar@jsbeautifier.org>
//
// Coincidentally, it can defeat a couple of other eval-based compressors.
//
// usage:
//
// if (P_A_C_K_E_R.detect(some_string)) {
// var unpacked = P_A_C_K_E_R.unpack(some_string);
// }
//
//
var P_A_C_K_E_R = {
detect: function(str) {
return (P_A_C_K_E_R.get_chunks(str).length > 0);
},
get_chunks: function(str) {
var chunks = str.match(/eval\(\(?function\(.*?(,0,\{\}\)\)|split\('\|'\)\)\))($|\n)/g);
return chunks ? chunks : [];
},
unpack: function(str) {
var chunks = P_A_C_K_E_R.get_chunks(str),
chunk;
for (var i = 0; i < chunks.length; i++) {
chunk = chunks[i].replace(/\n$/, '');
str = str.split(chunk).join(P_A_C_K_E_R.unpack_chunk(chunk));
}
return str;
},
unpack_chunk: function(str) {
var unpacked_source = '';
var __eval = eval;
if (P_A_C_K_E_R.detect(str)) {
try {
eval = function(s) { // jshint ignore:line
unpacked_source += s;
return unpacked_source;
}; // jshint ignore:line
__eval(str);
if (typeof unpacked_source === 'string' && unpacked_source) {
str = unpacked_source;
}
} catch (e) {
// well, it failed. we'll just return the original, instead of crashing on user.
}
}
eval = __eval; // jshint ignore:line
return str;
},
run_tests: function(sanity_test) {
var t = sanity_test || new SanityTest();
var pk1 = "eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1',3,3,'var||a'.split('|'),0,{}))";
var unpk1 = 'var a=1';
var pk2 = "eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1',3,3,'foo||b'.split('|'),0,{}))";
var unpk2 = 'foo b=1';
var pk_broken = "eval(function(p,a,c,k,e,r){BORKBORK;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1',3,3,'var||a'.split('|'),0,{}))";
var pk3 = "eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1{}))',3,3,'var||a'.split('|'),0,{}))";
var unpk3 = 'var a=1{}))';
t.test_function(P_A_C_K_E_R.detect, "P_A_C_K_E_R.detect");
t.expect('', false);
t.expect('var a = b', false);
t.test_function(P_A_C_K_E_R.unpack, "P_A_C_K_E_R.unpack");
t.expect(pk_broken, pk_broken);
t.expect(pk1, unpk1);
t.expect(pk2, unpk2);
t.expect(pk3, unpk3);
var filler = '\nfiller\n';
t.expect(filler + pk1 + "\n" + pk_broken + filler + pk2 + filler, filler + unpk1 + "\n" + pk_broken + filler + unpk2 + filler);
return t;
}
};
+73
View File
@@ -0,0 +1,73 @@
/*global unescape */
/*jshint curly: false, scripturl: true */
//
// trivial bookmarklet/escaped script detector for the javascript beautifier
// written by Einar Lielmanis <einar@jsbeautifier.org>
//
// usage:
//
// if (Urlencoded.detect(some_string)) {
// var unpacked = Urlencoded.unpack(some_string);
// }
//
//
var isNode = (typeof module !== 'undefined' && module.exports);
if (isNode) {
var SanityTest = require(__dirname + '/../../test/sanitytest');
}
var Urlencoded = {
detect: function(str) {
// the fact that script doesn't contain any space, but has %20 instead
// should be sufficient check for now.
if (str.indexOf(' ') === -1) {
if (str.indexOf('%2') !== -1) return true;
if (str.replace(/[^%]+/g, '').length > 3) return true;
}
return false;
},
unpack: function(str) {
if (Urlencoded.detect(str)) {
if (str.indexOf('%2B') !== -1 || str.indexOf('%2b') !== -1) {
// "+" escaped as "%2B"
return unescape(str.replace(/\+/g, '%20'));
} else {
return unescape(str);
}
}
return str;
},
run_tests: function(sanity_test) {
var t = sanity_test || new SanityTest();
t.test_function(Urlencoded.detect, "Urlencoded.detect");
t.expect('', false);
t.expect('var a = b', false);
t.expect('var%20a+=+b', true);
t.expect('var%20a=b', true);
t.expect('var%20%21%22', true);
t.expect('javascript:(function(){var%20whatever={init:function(){alert(%22a%22+%22b%22)}};whatever.init()})();', true);
t.test_function(Urlencoded.unpack, 'Urlencoded.unpack');
t.expect('javascript:(function(){var%20whatever={init:function(){alert(%22a%22+%22b%22)}};whatever.init()})();',
'javascript:(function(){var whatever={init:function(){alert("a"+"b")}};whatever.init()})();'
);
t.expect('', '');
t.expect('abcd', 'abcd');
t.expect('var a = b', 'var a = b');
t.expect('var%20a=b', 'var a=b');
t.expect('var%20a=b+1', 'var a=b+1');
t.expect('var%20a=b%2b1', 'var a=b+1');
return t;
}
};
if (isNode) {
module.exports = Urlencoded;
}
+62
View File
@@ -0,0 +1,62 @@
/*jshint node:true */
var requirejs = require('requirejs'),
SanityTest = require('./sanitytest'),
Urlencoded = require('../lib/unpackers/urlencode_unpacker'),
run_javascript_tests = require('./generated/beautify-javascript-tests').run_javascript_tests,
run_css_tests = require('./generated/beautify-css-tests').run_css_tests,
run_html_tests = require('./generated/beautify-html-tests').run_html_tests;
requirejs.config({
paths: {
'beautify': "..",
'beautify-lib': "../lib"
}
});
function amd_beautifier_index_tests(name, test_runner) {
console.log('Testing ' + name + ' with node.js Require.js (index file)...');
var results = new SanityTest();
var beautify = requirejs('beautify/index');
test_runner(
results,
Urlencoded,
beautify.js,
beautify.html,
beautify.css);
console.log(results.results_raw());
return results;
}
function amd_beautifier_tests(name, test_runner) {
console.log('Testing ' + name + ' with node.js Require.js (separate file)...');
var results = new SanityTest();
var js_beautify = requirejs('beautify-lib/beautify'),
css_beautify = requirejs('beautify-lib/beautify-css'),
html_beautify = requirejs('beautify-lib/beautify-html');
test_runner(
results,
Urlencoded,
js_beautify.js_beautify,
html_beautify.html_beautify,
css_beautify.css_beautify);
console.log(results.results_raw());
return results;
}
if (require.main === module) {
process.exit(
amd_beautifier_tests('js-beautifier', run_javascript_tests).get_exitcode() +
amd_beautifier_index_tests('js-beautifier', run_javascript_tests).get_exitcode() +
amd_beautifier_tests('cs-beautifier', run_css_tests).get_exitcode() +
amd_beautifier_index_tests('css-beautifier', run_css_tests).get_exitcode() +
amd_beautifier_tests('html-beautifier', run_html_tests).get_exitcode() +
amd_beautifier_index_tests('html-beautifier', run_html_tests).get_exitcode()
);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
/*global js_beautify: true */
/*jshint node:true */
/*jshint unused:false */
var fs = require('fs'),
SanityTest = require('./sanitytest'),
Benchmark = require('benchmark'),
Urlencoded = require('../lib/unpackers/urlencode_unpacker'),
js_beautify = require('../index').js_beautify,
css_beautify = require('../index').css_beautify,
html_beautify = require('../index').html_beautify;
function node_beautifier_html_tests() {
console.log('Testing performance...');
var index_html = fs.readFileSync(__dirname + '/../../index.html', 'utf8');
var data_attr = fs.readFileSync(__dirname + '/../../test/resources/html-with-base64image.html', 'utf8');
var options = {
wrap_line_length: 80
};
//warm-up
html_beautify(index_html, options);
html_beautify(data_attr, options);
var suite = new Benchmark.Suite();
suite.add("html-beautify (index.html)", function() {
html_beautify(index_html, options);
})
.add("html-beautify (base64 image)", function() {
html_beautify(data_attr, options);
})
// add listeners
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('error', function(event) {
return 1;
})
.on('complete', function(event) {})
.run();
return 0;
}
if (require.main === module) {
process.exit(node_beautifier_html_tests());
}
+50
View File
@@ -0,0 +1,50 @@
/*global js_beautify: true */
/*jshint node:true */
/*jshint unused:false */
var fs = require('fs'),
SanityTest = require('./sanitytest'),
Benchmark = require('benchmark'),
Urlencoded = require('../lib/unpackers/urlencode_unpacker'),
js_beautify = require('../index').js_beautify,
css_beautify = require('../index').css_beautify,
html_beautify = require('../index').html_beautify;
function node_beautifier_tests() {
console.log('Testing performance...');
var data = fs.readFileSync(__dirname + '/../../test/resources/underscore.js', 'utf8');
var data_min = fs.readFileSync(__dirname + '/../../test/resources/underscore-min.js', 'utf8');
var options = {
wrap_line_length: 80
};
//warm-up
js_beautify(data, options);
js_beautify(data_min, options);
var suite = new Benchmark.Suite();
suite.add("js-beautify (underscore)", function() {
js_beautify(data, options);
})
.add("js-beautify (underscore-min)", function() {
js_beautify(data_min, options);
})
// add listeners
.on('cycle', function(event) {
console.log(String(event.target));
})
.on('error', function(event) {
return 1;
})
.on('complete', function(event) {})
.run();
return 0;
}
if (require.main === module) {
process.exit(node_beautifier_tests());
}
+45
View File
@@ -0,0 +1,45 @@
/*jshint node:true */
var SanityTest = require('./sanitytest'),
Urlencoded = require('../lib/unpackers/urlencode_unpacker'),
run_javascript_tests = require('./generated/beautify-javascript-tests').run_javascript_tests,
run_css_tests = require('./generated/beautify-css-tests').run_css_tests,
run_html_tests = require('./generated/beautify-html-tests').run_html_tests;
function test_legacy_names() {
var beautify = require('../index');
var results = new SanityTest();
console.log('First ensure that legacy import names equal the new ones');
results.expect(beautify.js, beautify.js_beautify);
results.expect(beautify.css, beautify.css_beautify);
results.expect(beautify.html, beautify.html_beautify);
console.log(results.results_raw());
return results;
}
function node_beautifier_tests(name, test_runner) {
console.log('Testing ' + name + ' with node.js CommonJS...');
var beautify = require('../index');
var results = new SanityTest();
test_runner(
results,
Urlencoded,
beautify.js,
beautify.html,
beautify.css);
console.log(results.results_raw());
return results;
}
if (require.main === module) {
process.exit(
test_legacy_names() +
node_beautifier_tests('js-beautifier', run_javascript_tests).get_exitcode() +
node_beautifier_tests('css-beautifier', run_css_tests).get_exitcode() +
node_beautifier_tests('html-beautifier', run_html_tests).get_exitcode()
);
}
+58
View File
@@ -0,0 +1,58 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
<script type="text/javascript">
require(["../lib/beautify-html"],function(html_beautify){
var input = document.getElementById("input").value;
var output = html_beautify.html_beautify(input);
document.getElementById("output").innerHTML = output;
});
</script>
<style type="text/css">
#output{
border: 1px solid black;
height: 300px;
width: 100%;
}
#input{
width: 100%;
height: 300px;
}
</style>
</head>
<body>
<h1>RequireJS test</h1>
<p>
This example loads the html-beautifier by using a relative path in the require call to the beautify-html.js file.
(also works works with absolute paths)
</p>
<pre>
require(["../lib/beautify-html"],function(html_beautify){
var input = document.getElementById("input").value;
var output = html_beautify.html_beautify(input);
document.getElementById("output").innerHTML = output;
});
</pre>
<h2>Input</h2>
<textarea name="" id="input">
<ul><li><a href="test"></a></li></ul>
</textarea>
<h2>Output</h2>
<textarea name="" id="output">
</textarea>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
{
"indent_size": 11,
"indent_char": " "
"indent_level": 0,
"indent_with_tabs": false
}
@@ -0,0 +1,6 @@
root = true
[*.js]
indent_style = space
indent_size = 2
insert_final_newline = false
@@ -0,0 +1,3 @@
[*.js]
end_of_line = cr
@@ -0,0 +1,3 @@
[*.js]
end_of_line = crlf
@@ -0,0 +1 @@
Random stuff in here to cause parse error
@@ -0,0 +1,3 @@
function indentMe() {
"no, me!"; // indent_size 4, will be beautified to 2 with editorconfig
}
+3
View File
@@ -0,0 +1,3 @@
function indentMe() {
"no, me!";
}
@@ -0,0 +1,6 @@
{
"indent_size": 11,
"indent_char": " ",
"indent_level": 0,
"indent_with_tabs": false
}
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/spidermonkey-1.7 -s
//#!/usr/bin/js
// a little helper for testing from command line
// just run it, it will output the test results
load('js/lib/beautify.js');
load('js/test/sanitytest.js')
load('js/test/beautify-tests.js')
load('js/lib/unpackers/urlencode_unpacker.js')
print(run_beautifier_tests(new SanityTest(), Urlencoded, js_beautify).results_raw())
// for nodejs use this from the command line from the main directory:
// node test/beautify-tests.js
+144
View File
@@ -0,0 +1,144 @@
//
// simple testing interface
// written by Einar Lielmanis, einar@jsbeautifier.org
//
// usage:
//
// var t = new SanityTest(function (x) { return x; }, 'my function');
// t.expect('input', 'output');
// t.expect('a', 'a');
// output_somewhere(t.results()); // good for <pre>, html safe-ish
// alert(t.results_raw()); // html unescaped
function SanityTest(func, name_of_test) {
var test_func = func || function(x) {
return x;
};
var test_name = name_of_test || '';
var n_failed = 0;
var n_succeeded = 0;
var failures = [];
this.test_function = function(func, name) {
test_func = func;
test_name = name || '';
};
this.get_exitcode = function() {
return n_succeeded === 0 || n_failed !== 0 ? 1 : 0;
};
this.expect = function(parameters, expected_value) {
// multi-parameter calls not supported (I don't need them now).
var result = test_func(parameters);
// proper array checking is a pain. i'll maybe do it later, compare strings representations instead
if ((result === expected_value) || (expected_value instanceof Array && result.join(', ') === expected_value.join(', '))) {
n_succeeded += 1;
} else {
n_failed += 1;
failures.push([test_name, parameters, expected_value, result]);
}
};
this.results_raw = function() {
var results = '';
if (n_failed === 0) {
if (n_succeeded === 0) {
results = 'No tests run.';
} else {
results = 'All ' + n_succeeded + ' tests passed.';
}
} else {
for (var i = 0; i < failures.length; i++) {
var f = failures[i];
if (f[0]) {
f[0] = f[0] + ' ';
}
results += '==== ' + f[0] + '============================================================\n';
results += '---- input -------\n' + this.prettyprint(f[1]) + '\n';
results += '---- expected ----\n' + this.prettyprint(f[2]) + '\n';
results += '---- output ------\n' + this.prettyprint(f[3]) + '\n';
results += '---- expected-ws ------\n' + this.prettyprint_whitespace(f[2]) + '\n';
results += '---- output-ws ------\n' + this.prettyprint_whitespace(f[3]) + '\n';
results += '================================================================\n\n';
}
results += n_failed + ' tests failed.\n';
}
return results;
};
this.results = function() {
return this.lazy_escape(this.results_raw());
};
this.prettyprint_whitespace = function(something, quote_strings) {
return (this.prettyprint(something, quote_strings)
.replace(/\r\n/g, '\\r\n')
.replace(/\n/g, '\\n\n')
.replace(/\r/g, '\\r\n')
.replace(/ /g, '_')
.replace(/\t/g, '===|'));
};
this.prettyprint = function(something, quote_strings) {
var type = typeof something;
switch (type.toLowerCase()) {
case 'string':
if (quote_strings) {
return "'" + something.replace("'", "\\'") + "'";
}
return something;
case 'number':
return '' + something;
case 'boolean':
return something ? 'true' : 'false';
case 'undefined':
return 'undefined';
case 'object':
if (something instanceof Array) {
var x = [];
var expected_index = 0;
for (var k in something) {
if (k === expected_index) {
x.push(this.prettyprint(something[k], true));
expected_index += 1;
} else {
x.push('\n' + k + ': ' + this.prettyprint(something[k], true));
}
}
return '[' + x.join(', ') + ']';
}
return 'object: ' + something;
default:
return type + ': ' + something;
}
};
this.lazy_escape = function(str) {
return str.replace(/</g, '&lt;').replace(/\>/g, '&gt;').replace(/\n/g, '<br />');
};
this.log = function() {
if (window.console) {
if (console.firebug) {
console.log.apply(console, Array.prototype.slice.call(arguments));
} else {
console.log.call(console, Array.prototype.slice.call(arguments));
}
}
};
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = SanityTest;
}
+383
View File
@@ -0,0 +1,383 @@
#!/usr/bin/env bash
REL_SCRIPT_DIR="`dirname \"$0\"`"
SCRIPT_DIR="`( cd \"$REL_SCRIPT_DIR\" && pwd )`"
test_cli_common()
{
echo ----------------------------------------
echo Testing common cli behavior...
CLI_SCRIPT_NAME=${1:?missing_param}.js
CLI_SCRIPT=$SCRIPT_DIR/../bin/$CLI_SCRIPT_NAME
echo Script: $CLI_SCRIPT
# should find the minimal help output
$CLI_SCRIPT 2>&1 | grep -q "Must pipe input or define at least one file\." || {
$CLI_SCRIPT 2>&1
echo "[$CLI_SCRIPT_NAME] Output should be help message."
exit 1
}
$CLI_SCRIPT 2> /dev/null && {
echo "[$CLI_SCRIPT_NAME (with no parameters)] Return code should be error."
exit 1
}
$CLI_SCRIPT -Z 2> /dev/null && {
echo "[$CLI_SCRIPT_NAME -Z] Return code for invalid parameter should be error."
exit 1
}
$CLI_SCRIPT -h > /dev/null || {
echo "[$CLI_SCRIPT_NAME -h] Return code should be success."
exit 1
}
$CLI_SCRIPT -v > /dev/null || {
echo "[$CLI_SCRIPT_NAME -v] Return code should be success."
exit 1
}
MISSING_FILE="$SCRIPT_DIR/../../../js/bin/missing_file"
MISSING_FILE_MESSAGE="Unable to open path"
$CLI_SCRIPT $MISSING_FILE 2> /dev/null && {
echo "[$CLI_SCRIPT_NAME $MISSING_FILE] Return code should be error."
exit 1
}
$CLI_SCRIPT $MISSING_FILE 2>&1 | grep -q "$MISSING_FILE_MESSAGE" || {
echo "[$CLI_SCRIPT_NAME $MISSING_FILE] Stderr should have useful message."
exit 1
}
if [ "`$CLI_SCRIPT $MISSING_FILE 2> /dev/null`" != "" ]; then
echo "[$CLI_SCRIPT_NAME $MISSING_FILE] Stdout should have no text."
exit 1
fi
}
setup_temp()
{
mkdir -p target
TEST_TEMP=$PWD/`mktemp -d target/test_temp_XXXX`
echo Created $TEST_TEMP...
}
cleanup()
{
rm -rf $TEST_TEMP && echo Removed $TEST_TEMP...
test -z $1 || exit $1
}
test_cli_js_beautify()
{
echo ----------------------------------------
echo Testing js-beautify cli behavior...
CLI_SCRIPT=$SCRIPT_DIR/../bin/js-beautify.js
$CLI_SCRIPT $SCRIPT_DIR/../bin/js-beautify.js > /dev/null || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js was expected succeed."
exit 1
}
$CLI_SCRIPT $SCRIPT_DIR/../bin/css-beautify.js > /dev/null || {
echo "js-beautify output for $SCRIPT_DIR/../bin/css-beautify.js was expected succeed."
exit 1
}
$CLI_SCRIPT $SCRIPT_DIR/../bin/js-beautify.js | diff $SCRIPT_DIR/../bin/js-beautify.js - || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js was expected to be unchanged."
exit 1
}
node $SCRIPT_DIR/../lib/cli.js $SCRIPT_DIR/../bin/js-beautify.js | diff $SCRIPT_DIR/../bin/js-beautify.js - || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js was expected to be unchanged."
exit 1
}
cat $SCRIPT_DIR/../bin/js-beautify.js | $CLI_SCRIPT | diff $SCRIPT_DIR/../bin/js-beautify.js - || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js was expected to be unchanged."
exit 1
}
cat $SCRIPT_DIR/../bin/js-beautify.js | $CLI_SCRIPT - | diff $SCRIPT_DIR/../bin/js-beautify.js - || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js was expected to be unchanged."
exit 1
}
setup_temp
cat $SCRIPT_DIR/../bin/js-beautify.js | $CLI_SCRIPT -o $TEST_TEMP/js-beautify-pipe.js - && diff $TEST_TEMP/js-beautify-pipe.js $SCRIPT_DIR/../bin/js-beautify.js || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js should have been created in $TEST_TEMP/js-beautify-pipe.js."
cleanup 1
}
$CLI_SCRIPT -o $TEST_TEMP/js-beautify.js $SCRIPT_DIR/../bin/js-beautify.js && diff $SCRIPT_DIR/../bin/js-beautify.js $TEST_TEMP/js-beautify.js || {
echo "js-beautify output for $SCRIPT_DIR/../bin/js-beautify.js should have been created in $TEST_TEMP/js-beautify.js."
cleanup 1
}
# ensure new line settings work
$CLI_SCRIPT -o $TEST_TEMP/js-beautify-n.js -e '\n' $SCRIPT_DIR/../bin/js-beautify.js
$CLI_SCRIPT -o $TEST_TEMP/js-beautify-rn.js -e '\r\n' $TEST_TEMP/js-beautify-n.js
# ensure eol processed correctly
$CLI_SCRIPT -o $TEST_TEMP/js-beautify-n-dash.js --indent-size 2 --eol '\n' $TEST_TEMP/js-beautify-n.js
$CLI_SCRIPT -o $TEST_TEMP/js-beautify-rn-dash.js --indent-size 2 --eol '\r\n' $TEST_TEMP/js-beautify-n.js
diff -q $TEST_TEMP/js-beautify-n-dash.js $TEST_TEMP/js-beautify-rn-dash.js && {
diff $TEST_TEMP/js-beautify-n-dash.js $TEST_TEMP/js-beautify-rn-dash.js | cat -t -e
echo "js-beautify output for $TEST_TEMP/js-beautify-n-dash.js and $TEST_TEMP/js-beautify-rn-dash.js was expected to be different."
cleanup 1
}
diff -q $TEST_TEMP/js-beautify-n.js $TEST_TEMP/js-beautify-rn.js && {
diff $TEST_TEMP/js-beautify-n.js $TEST_TEMP/js-beautify-rn.js | cat -t -e
echo "js-beautify output for $TEST_TEMP/js-beautify-n.js and $TEST_TEMP/js-beautify-rn.js was expected to be different."
cleanup 1
}
$CLI_SCRIPT $TEST_TEMP/js-beautify-n.js | diff -q $TEST_TEMP/js-beautify-n.js - || {
echo "js-beautify output for $TEST_TEMP/js-beautify-n.js was expected to be unchanged."
cleanup 1
}
$CLI_SCRIPT -e 'auto' $TEST_TEMP/js-beautify-rn.js | diff -q $TEST_TEMP/js-beautify-rn.js - || {
echo "js-beautify output for $TEST_TEMP/js-beautify-rn.js was expected to be unchanged."
cleanup 1
}
# EditorConfig related tests
cp -r js/test/resources/editorconfig $TEST_TEMP/
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/example.js --end-with-newline --indent-size 4 -e '\n' $TEST_TEMP/editorconfig/example-base.js
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/example-ec.js --indent-size 2 -e '\n' $TEST_TEMP/editorconfig/example-base.js
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/cr/example.js --end-with-newline --indent-size 4 -e '\n' $TEST_TEMP/editorconfig/example-base.js
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/cr/example-ec.js --indent-size 2 -e '\r' $TEST_TEMP/editorconfig/example-base.js
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/crlf/example.js --end-with-newline --indent-size 4 -e '\n' $TEST_TEMP/editorconfig/example-base.js
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/crlf/example-ec.js --indent-size 2 -e '\r\n' $TEST_TEMP/editorconfig/example-base.js
$CLI_SCRIPT -o $TEST_TEMP/editorconfig/error/example.js --end-with-newline --indent-size 4 -e '\n' $TEST_TEMP/editorconfig/example-base.js
pushd $TEST_TEMP/editorconfig
cd $TEST_TEMP/editorconfig/error
$CLI_SCRIPT --editorconfig $TEST_TEMP/js-beautify-n.js \
> /dev/null || {
echo "Invalid editorconfig file should not report error (consistent with the EditorConfig)."
cleanup 1
}
$CLI_SCRIPT --editorconfig example.js \
> /dev/null || {
echo "Invalid editorconfig file should not report error (consistent with the EditorConfig)."
cleanup 1
}
# TODO: EditorConfig setting should NOT overide cli setting, but that is
# the current by-design behavior, due to code limitations.
# file input scenario
SCENARIO=a
cd $TEST_TEMP/editorconfig || exit 1
$CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js example.js \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
cd $TEST_TEMP/editorconfig/crlf || exit 1
$CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js example.js \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
cd $TEST_TEMP/editorconfig/cr || exit 1
$CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js example.js \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
# stdin input to stdout scenario
SCENARIO=b
cd $TEST_TEMP/editorconfig || exit 1
echo "cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig > example-${SCENARIO}.js"
cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig > example-${SCENARIO}.js \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
cd $TEST_TEMP/editorconfig/crlf || exit 1
echo "cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig > example-${SCENARIO}.js"
cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig > example-${SCENARIO}.js \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
cd $TEST_TEMP/editorconfig/cr || exit 1
echo "cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig > example-${SCENARIO}.js"
cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig > example-${SCENARIO}.js \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
# stdin input to file scenario
SCENARIO=c
cd $TEST_TEMP/editorconfig || exit 1
echo "cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js"
cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js - \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
cd $TEST_TEMP/editorconfig/crlf || exit 1
cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js - \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
cd $TEST_TEMP/editorconfig/cr || exit 1
cat example.js | $CLI_SCRIPT --end-with-newline --indent-size 6 --editorconfig -o example-${SCENARIO}.js - \
&& diff -q example-${SCENARIO}.js example-ec.js || {
echo "EditorConfig setting should overide cli setting."
diff example-${SCENARIO}.js example-ec.js | cat -t -e
cleanup 1
}
popd
# End EditorConfig
# ensure unchanged files are not overwritten
$CLI_SCRIPT -o $TEST_TEMP/js-beautify.js $SCRIPT_DIR/../bin/js-beautify.js
cp -p $TEST_TEMP/js-beautify.js $TEST_TEMP/js-beautify-old.js
touch $TEST_TEMP/js-beautify.js
sleep 2
touch $TEST_TEMP/js-beautify-old.js
$CLI_SCRIPT -r $TEST_TEMP/js-beautify.js && test $TEST_TEMP/js-beautify.js -nt $TEST_TEMP/js-beautify-old.js && {
echo "js-beautify should not replace unchanged file $TEST_TEMP/js-beautify.js when using -r"
cleanup 1
}
$CLI_SCRIPT -o $TEST_TEMP/js-beautify.js $TEST_TEMP/js-beautify.js && test $TEST_TEMP/js-beautify.js -nt $TEST_TEMP/js-beautify-old.js && {
echo "js-beautify should not replace unchanged file $TEST_TEMP/js-beautify.js when using -o and same file name"
cleanup 1
}
$CLI_SCRIPT -o $TEST_TEMP/js-beautify.js $TEST_TEMP/js-beautify-old.js && test $TEST_TEMP/js-beautify.js -nt $TEST_TEMP/js-beautify-old.js && {
echo "js-beautify should not replace unchanged file $TEST_TEMP/js-beautify.js when using -o and different file name"
cleanup 1
}
$CLI_SCRIPT $SCRIPT_DIR/../bin/css-beautify.js | diff -q $SCRIPT_DIR/../bin/css-beautify.js - && {
echo "js-beautify output for $SCRIPT_DIR/../bin/css-beautify.js was expected to be different."
cleanup 1
}
unset HOME
unset USERPROFILE
$CLI_SCRIPT -o $TEST_TEMP/example1-default.js $SCRIPT_DIR/resources/example1.js || exit 1
$CLI_SCRIPT -o $TEST_TEMP/example1-sanity.js $TEST_TEMP/example1-default.js || exit 1
diff -q $TEST_TEMP/example1-default.js $TEST_TEMP/example1-sanity.js || {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be identical after no change in settings."
cleanup 1
}
cd $SCRIPT_DIR/resources/configerror
$CLI_SCRIPT $TEST_TEMP/example1-default.js 2>&1 | grep -q "Error while loading beautifier configuration\." || {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be configration load error message."
cleanup 1
}
cd $SCRIPT_DIR/resources/indent11chars
$CLI_SCRIPT $TEST_TEMP/example1-default.js | diff -q $TEST_TEMP/example1-default.js - && {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be different based on CWD settings."
cleanup 1
}
cd $SCRIPT_DIR/resources/indent11chars/subDir1/subDir2
$CLI_SCRIPT $TEST_TEMP/example1-default.js | diff -q $TEST_TEMP/example1-default.js - && {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be different based on CWD parent folder settings."
cleanup 1
}
cd $SCRIPT_DIR
export HOME=$SCRIPT_DIR/resources/indent11chars
$CLI_SCRIPT $TEST_TEMP/example1-default.js | diff -q $TEST_TEMP/example1-default.js - && {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be different based on HOME settings."
cleanup 1
}
$CLI_SCRIPT -o $TEST_TEMP/example1-indent11chars.js $TEST_TEMP/example1-default.js
unset HOME
export USERPROFILE=$SCRIPT_DIR/resources/indent11chars
# node -p 'process.env["USERPROFILE"] || process.env["HOME"] || "unset"'
$CLI_SCRIPT $TEST_TEMP/example1-default.js | diff -q $TEST_TEMP/example1-indent11chars.js - || {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be identical for same HOME and USERPROFILE settings."
cleanup 1
}
$CLI_SCRIPT $TEST_TEMP/example1-default.js | diff -q $TEST_TEMP/example1-default.js - && {
echo "js-beautify output for $TEST_TEMP/example1-default.js was expected to be different based on USERPROFILE settings."
cleanup 1
}
cleanup
}
test_smoke_js_beautify()
{
echo ----------------------------------------
echo Testing js-beautify functionality...
node $SCRIPT_DIR/node-beautify-tests.js || exit 1
node $SCRIPT_DIR/amd-beautify-tests.js || exit 1
}
test_performance_js_beautify()
{
echo ----------------------------------------
echo Testing js-beautify performance...
node $SCRIPT_DIR/node-beautify-perf-tests.js || exit 1
echo ----------------------------------------
}
test_performance_html_beautify()
{
echo ----------------------------------------
echo Testing html-beautify performance...
node $SCRIPT_DIR/node-beautify-html-perf-tests.js || exit 1
echo ----------------------------------------
}
test_cli_common css-beautify
test_cli_common html-beautify
test_cli_common js-beautify
test_cli_js_beautify
test_smoke_js_beautify
test_performance_js_beautify
test_performance_html_beautify
echo ----------------------------------------
echo $0 - PASSED.
echo ----------------------------------------
+18
View File
@@ -0,0 +1,18 @@
{
"indent_size": 4,
"indent_char": " ",
"indent_level": 0,
"indent_with_tabs": false,
"preserve_newlines": true,
"max_preserve_newlines": 10,
"jslint_happy": false,
"space_after_anon_function": false,
"brace_style": "collapse,preserve-inline",
"keep_array_indentation": false,
"keep_function_indentation": false,
"space_before_conditional": true,
"break_chained_methods": false,
"eval_code": false,
"unescape_strings": false,
"wrap_line_length": 0
}
+148
View File
@@ -0,0 +1,148 @@
{
"_args": [
[
{
"raw": "js-beautify@^1.6.3",
"scope": null,
"escapedName": "js-beautify",
"name": "js-beautify",
"rawSpec": "^1.6.3",
"spec": ">=1.6.3 <2.0.0",
"type": "range"
},
"c:\\xampp\\htdocs\\laravel\\node_modules\\vue-loader"
]
],
"_from": "js-beautify@>=1.6.3 <2.0.0",
"_id": "js-beautify@1.6.14",
"_inCache": true,
"_location": "/js-beautify",
"_nodeVersion": "7.9.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/js-beautify-1.6.14.tgz_1494569796780_0.9350249317940325"
},
"_npmUser": {
"name": "bitwiseman",
"email": "bitwiseman@gmail.com"
},
"_npmVersion": "4.2.0",
"_phantomChildren": {},
"_requested": {
"raw": "js-beautify@^1.6.3",
"scope": null,
"escapedName": "js-beautify",
"name": "js-beautify",
"rawSpec": "^1.6.3",
"spec": ">=1.6.3 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/vue-loader"
],
"_resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.6.14.tgz",
"_shasum": "d3b8f7322d02b9277d58bd238264c327e58044cd",
"_shrinkwrap": null,
"_spec": "js-beautify@^1.6.3",
"_where": "c:\\xampp\\htdocs\\laravel\\node_modules\\vue-loader",
"author": {
"name": "Einar Lielmanis",
"email": "einar@jsbeautifier.org"
},
"bin": {
"css-beautify": "./js/bin/css-beautify.js",
"html-beautify": "./js/bin/html-beautify.js",
"js-beautify": "./js/bin/js-beautify.js"
},
"bugs": {
"url": "https://github.com/beautify-web/js-beautify/issues"
},
"contributors": [
{
"name": "Vital Batmanov",
"email": "vital76@gmail.com"
},
{
"name": "Chris J. Shull",
"email": "chrisjshull@gmail.com"
},
{
"name": "Gian Marco Gherardi",
"email": "gianmarco.gherardi@gmail.com"
},
{
"name": "Stan",
"email": "stasson@orc.ru"
},
{
"name": "Vittorio Gambaletta",
"email": "VittGam@vittgam.net"
},
{
"name": "Daniel Stockman",
"email": "daniel.stockman@gmail.com"
},
{
"name": "Harutyun Amirjanyan",
"email": "amirjanyan@gmail.com"
},
{
"name": "Nochum Sossonko",
"email": "nsossonko@hotmail.com"
},
{
"name": "Liam Newman",
"email": "bitwiseman@gmail.com"
}
],
"dependencies": {
"config-chain": "~1.1.5",
"editorconfig": "^0.13.2",
"mkdirp": "~0.5.0",
"nopt": "~3.0.1"
},
"description": "jsbeautifier.org for node",
"devDependencies": {
"benchmark": "2.1.0",
"jshint": "~2.9.1",
"mustache": "~2.2.1",
"node-static": "~0.7.1",
"requirejs": "2.1.x"
},
"directories": {
"lib": "js/lib",
"test": "js/test"
},
"dist": {
"shasum": "d3b8f7322d02b9277d58bd238264c327e58044cd",
"tarball": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.6.14.tgz"
},
"gitHead": "ccc736a4421a5d5eb694b2e749d435945f105dc3",
"homepage": "http://jsbeautifier.org/",
"keywords": [
"beautify",
"beautifier",
"code-quality"
],
"license": "MIT",
"main": "js/index.js",
"maintainers": [
{
"name": "evocateur",
"email": "daniel.stockman@gmail.com"
},
{
"name": "bitwiseman",
"email": "bitwiseman@gmail.com"
}
],
"name": "js-beautify",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/beautify-web/js-beautify.git"
},
"scripts": {},
"version": "1.6.14"
}
+269
View File
@@ -0,0 +1,269 @@
/*
{{&header_text}}
The MIT License (MIT)
Copyright (c) 2007-2017 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.
*/
/*jshint unused:false */
function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_beautify)
{
var default_opts = {
indent_size: 4,
indent_char: ' ',
preserve_newlines: true,
jslint_happy: false,
keep_array_indentation: false,
brace_style: 'collapse',
space_before_conditional: true,
break_chained_methods: false,
selector_separator: '\n',
end_with_newline: false
};
var opts;
{{#default_options}} default_opts.{{name}} = {{&value}};
{{/default_options}}
function reset_options()
{
opts = JSON.parse(JSON.stringify(default_opts));
}
function test_css_beautifier(input)
{
return css_beautify(input, opts);
}
var sanitytest;
// test the input on beautifier with the current flag settings
// does not check the indentation / surroundings as bt() does
function test_fragment(input, expected)
{
expected = expected || expected === '' ? expected : input;
sanitytest.expect(input, expected);
// if the expected is different from input, run it again
// expected output should be unchanged when run twice.
if (expected !== input) {
sanitytest.expect(expected, expected);
}
// Everywhere we do newlines, they should be replaced with opts.eol
opts.eol = '\r\\n';
expected = expected.replace(/[\n]/g, '\r\n');
sanitytest.expect(input, expected);
if (input.indexOf('\n') !== -1) {
input = input.replace(/[\n]/g, '\r\n');
sanitytest.expect(input, expected);
// Ensure support for auto eol detection
opts.eol = 'auto';
sanitytest.expect(input, expected);
}
opts.eol = '\n';
}
// test css
function t(input, expectation)
{
var wrapped_input, wrapped_expectation;
expectation = expectation || expectation === '' ? expectation : input;
sanitytest.test_function(test_css_beautifier, 'css_beautify');
test_fragment(input, expectation);
}
function unicode_char(value) {
return String.fromCharCode(value);
}
function beautifier_tests()
{
sanitytest = test_obj;
reset_options();
//============================================================
t(".tabs {}");
{{#groups}}{{#set_mustache_tags}}.{{/set_mustache_tags}}
//============================================================
{{^matrix}}
// {{&name}}
reset_options();
{{#options}}
opts.{{name}} = {{&value}};
{{/options}}
{{#tests}}
{{#test_line}}.{{/test_line}};
{{/tests}}
{{/matrix}}
{{#matrix}}
// {{&name}} - ({{#matrix_context_string}}.{{/matrix_context_string}})
reset_options();
{{#options}}
opts.{{name}} = {{&value}};
{{/options}}
{{#tests}}
{{#test_line}}.{{/test_line}};
{{/tests}}
{{/matrix}}
{{#unset_mustache_tags}}.{{/unset_mustache_tags}}{{/groups}}
}
function beautifier_unconverted_tests()
{
sanitytest = test_obj;
reset_options();
//============================================================
// test basic css beautifier
t(".tabs {}");
t(".tabs{color:red;}", ".tabs {\n\tcolor: red;\n}");
t(".tabs{color:rgb(255, 255, 0)}", ".tabs {\n\tcolor: rgb(255, 255, 0)\n}");
t(".tabs{background:url('back.jpg')}", ".tabs {\n\tbackground: url('back.jpg')\n}");
t("#bla, #foo{color:red}", "#bla,\n#foo {\n\tcolor: red\n}");
t("@media print {.tab{}}", "@media print {\n\t.tab {}\n}");
t("@media print {.tab{background-image:url(foo@2x.png)}}", "@media print {\n\t.tab {\n\t\tbackground-image: url(foo@2x.png)\n\t}\n}");
t("a:before {\n" +
"\tcontent: 'a{color:black;}\"\"\\'\\'\"\\n\\n\\na{color:black}\';\n" +
"}");
//lead-in whitespace determines base-indent.
// lead-in newlines are stripped.
t("\n\na, img {padding: 0.2px}", "a,\nimg {\n\tpadding: 0.2px\n}");
t(" a, img {padding: 0.2px}", " a,\n img {\n \tpadding: 0.2px\n }");
t(" \t \na, img {padding: 0.2px}", " \t a,\n \t img {\n \t \tpadding: 0.2px\n \t }");
t("\n\n a, img {padding: 0.2px}", "a,\nimg {\n\tpadding: 0.2px\n}");
// separate selectors
t("#bla, #foo{color:red}", "#bla,\n#foo {\n\tcolor: red\n}");
t("a, img {padding: 0.2px}", "a,\nimg {\n\tpadding: 0.2px\n}");
// block nesting
t("#foo {\n\tbackground-image: url(foo@2x.png);\n\t@font-face {\n\t\tfont-family: 'Bitstream Vera Serif Bold';\n\t\tsrc: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');\n\t}\n}");
t("@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo@2x.png);\n\t}\n\t@font-face {\n\t\tfont-family: 'Bitstream Vera Serif Bold';\n\t\tsrc: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');\n\t}\n}");
/*
@font-face {
font-family: 'Bitstream Vera Serif Bold';
src: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');
}
@media screen {
#foo:hover {
background-image: url(foo.png);
}
@media screen and (min-device-pixel-ratio: 2) {
@font-face {
font-family: 'Helvetica Neue'
}
#foo:hover {
background-image: url(foo@2x.png);
}
}
}
*/
t("@font-face {\n\tfont-family: 'Bitstream Vera Serif Bold';\n\tsrc: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');\n}\n@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo.png);\n\t}\n\t@media screen and (min-device-pixel-ratio: 2) {\n\t\t@font-face {\n\t\t\tfont-family: 'Helvetica Neue'\n\t\t}\n\t\t#foo:hover {\n\t\t\tbackground-image: url(foo@2x.png);\n\t\t}\n\t}\n}");
// less-css cases
t('.well{@well-bg:@bg-color;@well-fg:@fg-color;}','.well {\n\t@well-bg: @bg-color;\n\t@well-fg: @fg-color;\n}');
t('.well {&.active {\nbox-shadow: 0 1px 1px @border-color, 1px 0 1px @border-color;}}',
'.well {\n' +
'\t&.active {\n' +
'\t\tbox-shadow: 0 1px 1px @border-color, 1px 0 1px @border-color;\n' +
'\t}\n' +
'}');
t('a {\n' +
'\tcolor: blue;\n' +
'\t&:hover {\n' +
'\t\tcolor: green;\n' +
'\t}\n' +
'\t& & &&&.active {\n' +
'\t\tcolor: green;\n' +
'\t}\n' +
'}');
// Not sure if this is sensible
// but I believe it is correct to not remove the space in "&: hover".
t('a {\n' +
'\t&: hover {\n' +
'\t\tcolor: green;\n' +
'\t}\n' +
'}');
// import
t('@import "test";');
// don't break nested pseudo-classes
t("a:first-child{color:red;div:first-child{color:black;}}",
"a:first-child {\n\tcolor: red;\n\tdiv:first-child {\n\t\tcolor: black;\n\t}\n}");
// handle SASS/LESS parent reference
t("div{&:first-letter {text-transform: uppercase;}}",
"div {\n\t&:first-letter {\n\t\ttext-transform: uppercase;\n\t}\n}");
//nested modifiers (&:hover etc)
t(".tabs{&:hover{width:10px;}}", ".tabs {\n\t&:hover {\n\t\twidth: 10px;\n\t}\n}");
t(".tabs{&.big{width:10px;}}", ".tabs {\n\t&.big {\n\t\twidth: 10px;\n\t}\n}");
t(".tabs{&>big{width:10px;}}", ".tabs {\n\t&>big {\n\t\twidth: 10px;\n\t}\n}");
t(".tabs{&+.big{width:10px;}}", ".tabs {\n\t&+.big {\n\t\twidth: 10px;\n\t}\n}");
//nested rules
t(".tabs{.child{width:10px;}}", ".tabs {\n\t.child {\n\t\twidth: 10px;\n\t}\n}");
//variables
t("@myvar:10px;.tabs{width:10px;}", "@myvar: 10px;\n.tabs {\n\twidth: 10px;\n}");
t("@myvar:10px; .tabs{width:10px;}", "@myvar: 10px;\n.tabs {\n\twidth: 10px;\n}");
// test options
opts.indent_size = 2;
opts.indent_char = ' ';
opts.selector_separator_newline = false;
// pseudo-classes and pseudo-elements
t("#foo:hover {\n background-image: url(foo@2x.png)\n}");
t("#foo *:hover {\n color: purple\n}");
t("::selection {\n color: #ff0000;\n}");
// TODO: don't break nested pseduo-classes
t("@media screen {.tab,.bat:hover {color:red}}", "@media screen {\n .tab, .bat:hover {\n color: red\n }\n}");
// particular edge case with braces and semicolons inside tags that allows custom text
t("a:not(\"foobar\\\";{}omg\"){\ncontent: 'example\\';{} text';\ncontent: \"example\\\";{} text\";}",
"a:not(\"foobar\\\";{}omg\") {\n content: 'example\\';{} text';\n content: \"example\\\";{} text\";\n}");
// may not eat the space before "["
t('html.js [data-custom="123"] {\n opacity: 1.00;\n}');
t('html.js *[data-custom="123"] {\n opacity: 1.00;\n}');
}
beautifier_tests();
beautifier_unconverted_tests();
}
if (typeof exports !== "undefined") {
exports.run_css_tests = run_css_tests;
}
+270
View File
@@ -0,0 +1,270 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
{{&header_text}}
The MIT License (MIT)
Copyright (c) 2007-2017 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 unittest
import cssbeautifier
import copy
class CSSBeautifierTest(unittest.TestCase):
options = None
@classmethod
def setUpClass(cls):
false = False
true = True
default_options = cssbeautifier.default_options()
default_options.indent_size = 1
default_options.indent_char = '\t'
default_options.selector_separator_newline = true
default_options.end_with_newline = false
default_options.newline_between_rules = false
{{#default_options}} default_options.{{name}} = {{&value}}
{{/default_options}}
cls.default_options = default_options
def reset_options(self):
self.options = copy.copy(self.default_options)
def testGenerated(self):
self.reset_options()
test_fragment = self.decodesto
t = self.decodesto
false = False
true = True
{{#groups}}{{#set_mustache_tags}}.{{/set_mustache_tags}}
#============================================================
{{^matrix}}
# {{&name}}
self.reset_options();
{{#options}}
self.options.{{name}} = {{&value}}
{{/options}}
{{#tests}}
{{#test_line}}.{{/test_line}}
{{/tests}}
{{/matrix}}
{{#matrix}}
# {{&name}} - ({{#matrix_context_string}}.{{/matrix_context_string}})
self.reset_options();
{{#options}}
self.options.{{name}} = {{&value}}
{{/options}}
{{#tests}}
{{#test_line}}.{{/test_line}}
{{/tests}}
{{/matrix}}
{{#unset_mustache_tags}}.{{/unset_mustache_tags}}{{/groups}}
def testNewline(self):
self.reset_options()
t = self.decodesto
self.options.end_with_newline = True
t("", "\n")
t("\n", "\n")
t(".tabs{}\n", ".tabs {}\n")
t(".tabs{}", ".tabs {}\n")
def testBasics(self):
self.reset_options()
t = self.decodesto
t("", "")
t("\n", "")
t(".tabs{}\n", ".tabs {}")
t(".tabs{}", ".tabs {}")
t(".tabs{color:red}", ".tabs {\n\tcolor: red\n}")
t(".tabs{color:rgb(255, 255, 0)}", ".tabs {\n\tcolor: rgb(255, 255, 0)\n}")
t(".tabs{background:url('back.jpg')}", ".tabs {\n\tbackground: url('back.jpg')\n}")
t("#bla, #foo{color:red}", "#bla,\n#foo {\n\tcolor: red\n}")
t("@media print {.tab{}}", "@media print {\n\t.tab {}\n}")
t("@media print {.tab{background-image:url(foo@2x.png)}}", "@media print {\n\t.tab {\n\t\tbackground-image: url(foo@2x.png)\n\t}\n}")
t("a:before {\n" +
"\tcontent: 'a{color:black;}\"\"\\'\\'\"\\n\\n\\na{color:black}\';\n" +
"}");
# may not eat the space before "["
t('html.js [data-custom="123"] {\n\topacity: 1.00;\n}')
t('html.js *[data-custom="123"] {\n\topacity: 1.00;\n}')
# lead-in whitespace determines base-indent.
# lead-in newlines are stripped.
t("\n\na, img {padding: 0.2px}", "a,\nimg {\n\tpadding: 0.2px\n}")
t(" a, img {padding: 0.2px}", " a,\n img {\n \tpadding: 0.2px\n }")
t(" \t \na, img {padding: 0.2px}", " \t a,\n \t img {\n \t \tpadding: 0.2px\n \t }")
t("\n\n a, img {padding: 0.2px}", "a,\nimg {\n\tpadding: 0.2px\n}")
def testSeperateSelectors(self):
self.reset_options()
t = self.decodesto
t("#bla, #foo{color:red}", "#bla,\n#foo {\n\tcolor: red\n}")
t("a, img {padding: 0.2px}", "a,\nimg {\n\tpadding: 0.2px\n}")
def testBlockNesting(self):
self.reset_options()
t = self.decodesto
t("#foo {\n\tbackground-image: url(foo@2x.png);\n\t@font-face {\n\t\tfont-family: 'Bitstream Vera Serif Bold';\n\t\tsrc: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');\n\t}\n}")
t("@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo@2x.png);\n\t}\n\t@font-face {\n\t\tfont-family: 'Bitstream Vera Serif Bold';\n\t\tsrc: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');\n\t}\n}")
# @font-face {
# font-family: 'Bitstream Vera Serif Bold';
# src: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');
# }
# @media screen {
# #foo:hover {
# background-image: url(foo.png);
# }
# @media screen and (min-device-pixel-ratio: 2) {
# @font-face {
# font-family: 'Helvetica Neue'
# }
# #foo:hover {
# background-image: url(foo@2x.png);
# }
# }
# }
t("@font-face {\n\tfont-family: 'Bitstream Vera Serif Bold';\n\tsrc: url('http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf');\n}\n@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo.png);\n\t}\n\t@media screen and (min-device-pixel-ratio: 2) {\n\t\t@font-face {\n\t\t\tfont-family: 'Helvetica Neue'\n\t\t}\n\t\t#foo:hover {\n\t\t\tbackground-image: url(foo@2x.png);\n\t\t}\n\t}\n}")
def testOptions(self):
self.reset_options()
self.options.indent_size = 2
self.options.indent_char = ' '
self.options.selector_separator_newline = False
t = self.decodesto
# pseudo-classes and pseudo-elements
t("#foo:hover {\n background-image: url(foo@2x.png)\n}")
t("#foo *:hover {\n color: purple\n}")
t("::selection {\n color: #ff0000;\n}")
# TODO: don't break nested pseduo-classes
t("@media screen {.tab,.bat:hover {color:red}}", "@media screen {\n .tab, .bat:hover {\n color: red\n }\n}")
# particular edge case with braces and semicolons inside tags that allows custom text
t( "a:not(\"foobar\\\";{}omg\"){\ncontent: 'example\\';{} text';\ncontent: \"example\\\";{} text\";}",
"a:not(\"foobar\\\";{}omg\") {\n content: 'example\\';{} text';\n content: \"example\\\";{} text\";\n}")
def testLessCss(self):
self.reset_options()
t = self.decodesto
t('.well{ \n @well-bg:@bg-color;@well-fg:@fg-color;}','.well {\n\t@well-bg: @bg-color;\n\t@well-fg: @fg-color;\n}')
t('.well {&.active {\nbox-shadow: 0 1px 1px @border-color, 1px 0 1px @border-color;}}',
'.well {\n' +
'\t&.active {\n' +
'\t\tbox-shadow: 0 1px 1px @border-color, 1px 0 1px @border-color;\n' +
'\t}\n' +
'}')
t('a {\n' +
'\tcolor: blue;\n' +
'\t&:hover {\n' +
'\t\tcolor: green;\n' +
'\t}\n' +
'\t& & &&&.active {\n' +
'\t\tcolor: green;\n' +
'\t}\n' +
'}')
# Not sure if this is sensible
# but I believe it is correct to not remove the space in "&: hover".
t('a {\n' +
'\t&: hover {\n' +
'\t\tcolor: green;\n' +
'\t}\n' +
'}');
# import
t('@import "test";');
# don't break nested pseudo-classes
t("a:first-child{color:red;div:first-child{color:black;}}",
"a:first-child {\n\tcolor: red;\n\tdiv:first-child {\n\t\tcolor: black;\n\t}\n}");
# handle SASS/LESS parent reference
t("div{&:first-letter {text-transform: uppercase;}}",
"div {\n\t&:first-letter {\n\t\ttext-transform: uppercase;\n\t}\n}");
# nested modifiers (&:hover etc)
t(".tabs{&:hover{width:10px;}}", ".tabs {\n\t&:hover {\n\t\twidth: 10px;\n\t}\n}")
t(".tabs{&.big{width:10px;}}", ".tabs {\n\t&.big {\n\t\twidth: 10px;\n\t}\n}")
t(".tabs{&>big{width:10px;}}", ".tabs {\n\t&>big {\n\t\twidth: 10px;\n\t}\n}")
t(".tabs{&+.big{width:10px;}}", ".tabs {\n\t&+.big {\n\t\twidth: 10px;\n\t}\n}")
# nested rules
t(".tabs{.child{width:10px;}}", ".tabs {\n\t.child {\n\t\twidth: 10px;\n\t}\n}")
# variables
t("@myvar:10px;.tabs{width:10px;}", "@myvar: 10px;\n.tabs {\n\twidth: 10px;\n}")
t("@myvar:10px; .tabs{width:10px;}", "@myvar: 10px;\n.tabs {\n\twidth: 10px;\n}")
def decodesto(self, input, expectation=None):
if expectation == None:
expectation = input
self.assertMultiLineEqual(
cssbeautifier.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 != input:
self.assertMultiLineEqual(
cssbeautifier.beautify(expectation, self.options), expectation)
# Everywhere we do newlines, they should be replaced with opts.eol
self.options.eol = '\r\\n';
expectation = expectation.replace('\n', '\r\n')
self.assertMultiLineEqual(
cssbeautifier.beautify(input, self.options), expectation)
if input.find('\n') != -1:
input = input.replace('\n', '\r\n')
self.assertMultiLineEqual(
cssbeautifier.beautify(input, self.options), expectation)
# Ensure support for auto eol detection
self.options.eol = 'auto'
self.assertMultiLineEqual(
cssbeautifier.beautify(input, self.options), expectation)
self.options.eol = '\n'
if __name__ == '__main__':
unittest.main()
+445
View File
@@ -0,0 +1,445 @@
/*
The MIT License (MIT)
Copyright (c) 2007-2017 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.
*/
exports.test_data = {
default_options: [
{ name: "indent_size", value: "1" },
{ name: "indent_char", value: "'\\t'" },
{ name: "selector_separator_newline", value: "true" },
{ name: "end_with_newline", value: "false" },
{ name: "newline_between_rules", value: "false" },
{ name: "space_around_combinator", value: "false" },
{ name: "preserve_newlines", value: "false" },
// deprecated
{ name: "space_around_selector_separator", value: "false" }
],
groups: [{
name: "End With Newline",
description: "",
matrix: [{
options: [
{ name: "end_with_newline", value: "true" }
],
eof: '\\n'
}, {
options: [
{ name: "end_with_newline", value: "false" }
],
eof: ''
}],
tests: [
{ fragment: true, input: '', output: '{{eof}}' },
{ fragment: true, input: ' .tabs{}', output: ' .tabs {}{{eof}}' },
{ fragment: true, input: ' \n\n.tabs{}\n\n\n\n', output: ' .tabs {}{{eof}}' },
{ fragment: true, input: '\n', output: '{{eof}}' }
],
}, {
name: "Empty braces",
description: "",
tests: [
{ input: '.tabs{}', output: '.tabs {}' },
{ input: '.tabs { }', output: '.tabs {}' },
{ input: '.tabs { }', output: '.tabs {}' },
// When we support preserving newlines this will need to change
{ input: '.tabs \n{\n \n }', output: '.tabs {}' }
],
}, {
name: "",
description: "",
tests: [{
input: '#cboxOverlay {\n\tbackground: url(images/overlay.png) repeat 0 0;\n\topacity: 0.9;\n\tfilter: alpha(opacity = 90);\n}',
output: '#cboxOverlay {\n\tbackground: url(images/overlay.png) repeat 0 0;\n\topacity: 0.9;\n\tfilter: alpha(opacity=90);\n}'
}, ],
}, {
name: "Support simple language specific option inheritance/overriding",
description: "Support simple language specific option inheritance/overriding",
matrix: [{
options: [
{ name: "indent_char", value: "' '" },
{ name: "indent_size", value: "4" },
{ name: "js", value: "{ 'indent_size': 3 }" },
{ name: "css", value: "{ 'indent_size': 5 }" }
],
c: ' ',
},
{
options: [
{ name: "indent_char", value: "' '" },
{ name: "indent_size", value: "4" },
{ name: "html", value: "{ 'js': { 'indent_size': 3 }, 'css': { 'indent_size': 5 } }" }
],
c: ' '
},
{
options: [
{ name: "indent_char", value: "' '" },
{ name: "indent_size", value: "9" },
{ name: "html", value: "{ 'js': { 'indent_size': 3 }, 'css': { 'indent_size': 8 }, 'indent_size': 2}" },
{ name: "js", value: "{ 'indent_size': 5 }" },
{ name: "css", value: "{ 'indent_size': 3 }" }
],
c: ' '
}
],
tests: [{
unchanged: [
'.selector {',
'{{c}}font-size: 12px;',
'}'
]
}]
}, {
name: "Space Around Combinator",
description: "",
matrix: [{
options: [{ name: "space_around_combinator", value: "true" }],
space: ' '
}, {
options: [{ name: "space_around_combinator", value: "false" }],
space: ''
}, {
// space_around_selector_separator is deprecated, but needs to keep working for now.
options: [{ name: "space_around_selector_separator", value: "true" }],
space: ' '
}],
tests: [
{ input: 'a>b{}', output: 'a{{space}}>{{space}}b {}' },
{ input: 'a~b{}', output: 'a{{space}}~{{space}}b {}' },
{ input: 'a+b{}', output: 'a{{space}}+{{space}}b {}' },
{ input: 'a+b>c{}', output: 'a{{space}}+{{space}}b{{space}}>{{space}}c {}' },
{ input: 'a > b{}', output: 'a{{space}}>{{space}}b {}' },
{ input: 'a ~ b{}', output: 'a{{space}}~{{space}}b {}' },
{ input: 'a + b{}', output: 'a{{space}}+{{space}}b {}' },
{ input: 'a + b > c{}', output: 'a{{space}}+{{space}}b{{space}}>{{space}}c {}' },
{
input: 'a > b{width: calc(100% + 45px);}',
output: [
'a{{space}}>{{space}}b {',
'\twidth: calc(100% + 45px);',
'}'
]
},
{
input: 'a ~ b{width: calc(100% + 45px);}',
output: [
'a{{space}}~{{space}}b {',
'\twidth: calc(100% + 45px);',
'}'
]
},
{
input: 'a + b{width: calc(100% + 45px);}',
output: [
'a{{space}}+{{space}}b {',
'\twidth: calc(100% + 45px);',
'}'
]
},
{
input: 'a + b > c{width: calc(100% + 45px);}',
output: [
'a{{space}}+{{space}}b{{space}}>{{space}}c {',
'\twidth: calc(100% + 45px);',
'}'
]
}
]
}, {
name: 'Selector Separator',
description: '',
matrix: [{
options: [
{ name: 'selector_separator_newline', value: 'false' },
{ name: 'selector_separator', value: '" "' }
],
separator: ' ',
separator1: ' '
}, {
options: [
{ name: 'selector_separator_newline', value: 'false' },
{ name: 'selector_separator', value: '" "' }
],
// BUG: #713
separator: ' ',
separator1: ' '
}, {
options: [
{ name: 'selector_separator_newline', value: 'true' },
{ name: 'selector_separator', value: '" "' }
],
separator: '\\n',
separator1: '\\n\\t'
}, {
options: [
{ name: 'selector_separator_newline', value: 'true' },
{ name: 'selector_separator', value: '" "' }
],
separator: '\\n',
separator1: '\\n\\t'
}],
tests: [
{ input: '#bla, #foo{color:green}', output: '#bla,{{separator}}#foo {\n\tcolor: green\n}' },
{ input: '@media print {.tab{}}', output: '@media print {\n\t.tab {}\n}' },
{ input: '@media print {.tab,.bat{}}', output: '@media print {\n\t.tab,{{separator1}}.bat {}\n}' },
{ input: '#bla, #foo{color:black}', output: '#bla,{{separator}}#foo {\n\tcolor: black\n}' }, {
input: 'a:first-child,a:first-child{color:red;div:first-child,div:hover{color:black;}}',
output: 'a:first-child,{{separator}}a:first-child {\n\tcolor: red;\n\tdiv:first-child,{{separator1}}div:hover {\n\t\tcolor: black;\n\t}\n}'
}
]
}, {
name: "Preserve Newlines",
description: "",
matrix: [{
options: [
{ name: "preserve_newlines", value: "true" }
],
separator_input: '\\n\\n',
separator_output: '\\n\\n',
}, {
options: [
{ name: "preserve_newlines", value: "false" }
],
separator_input: '\\n\\n',
separator_output: '\\n',
}],
tests: [
{ input: '.div {}{{separator_input}}.span {}', output: '.div {}{{separator_output}}.span {}' },
{ input: '#bla, #foo{\n\tcolor:black;{{separator_input}}\tfont-size: 12px;\n}', output: '#bla,\n#foo {\n\tcolor: black;{{separator_output}}\tfont-size: 12px;\n}' }
],
},
{
name: "Preserve Newlines and newline_between_rules",
description: "",
options: [
{ name: "preserve_newlines", value: "true" },
{ name: "newline_between_rules", value: "true" }
],
tests: [
{ input: '.div {}.span {}', output: '.div {}\n\n.span {}' },
{ input: '#bla, #foo{\n\tcolor:black;\n\tfont-size: 12px;\n}', output: '#bla,\n#foo {\n\tcolor: black;\n\tfont-size: 12px;\n}' },
{ input: '#bla, #foo{\n\tcolor:black;\n\n\n\tfont-size: 12px;\n}', output: '#bla,\n#foo {\n\tcolor: black;\n\n\n\tfont-size: 12px;\n}' },
{ unchanged: '#bla,\n\n#foo {\n\tcolor: black;\n\tfont-size: 12px;\n}' },
{ unchanged: 'a {\n\tb: c;\n\n\n\td: {\n\t\te: f;\n\t}\n}' },
{ unchanged: '.div {}\n\n.span {}' },
{ unchanged: '.div {\n\ta: 1;\n\n\n\tb: 2;\n}\n\n\n\n.span {\n\ta: 1;\n}' },
{ unchanged: '.div {\n\n\n\ta: 1;\n\n\n\tb: 2;\n}\n\n\n\n.span {\n\ta: 1;\n}' },
{ unchanged: '@media screen {\n\t.div {\n\t\ta: 1;\n\n\n\t\tb: 2;\n\t}\n\n\n\n\t.span {\n\t\ta: 1;\n\t}\n}\n\n.div {}\n\n.span {}' },
],
}, {
name: "Preserve Newlines and add tabs",
options: [{ name: "preserve_newlines", value: "true" }],
description: "",
tests: [{
input: '.tool-tip {\n\tposition: relative;\n\n\t\t\n\t.tool-tip-content {\n\t\t&>* {\n\t\t\tmargin-top: 0;\n\t\t}\n\t\t\n\n\t\t.mixin-box-shadow(.2rem .2rem .5rem rgba(0, 0, 0, .15));\n\t\tpadding: 1rem;\n\t\tposition: absolute;\n\t\tz-index: 10;\n\t}\n}',
output: '.tool-tip {\n\tposition: relative;\n\n\n\t.tool-tip-content {\n\t\t&>* {\n\t\t\tmargin-top: 0;\n\t\t}\n\\n\\n\t\t.mixin-box-shadow(.2rem .2rem .5rem rgba(0, 0, 0, .15));\n\t\tpadding: 1rem;\n\t\tposition: absolute;\n\t\tz-index: 10;\n\t}\n}'
}],
}, {
name: "Newline Between Rules",
description: "",
matrix: [{
options: [
{ name: "newline_between_rules", value: "true" }
],
separator: '\\n'
}, {
options: [
{ name: "newline_between_rules", value: "false" }
],
separator: ''
}],
tests: [
{ input: '.div {}\n.span {}', output: '.div {}\n{{separator}}.span {}' },
{ input: '.div{}\n \n.span{}', output: '.div {}\n{{separator}}.span {}' },
{ input: '.div {} \n \n.span { } \n', output: '.div {}\n{{separator}}.span {}' },
{ input: '.div {\n \n} \n .span {\n } ', output: '.div {}\n{{separator}}.span {}' },
{ input: '.selector1 {\n\tmargin: 0; /* This is a comment including an url http://domain.com/path/to/file.ext */\n}\n.div{height:15px;}', output: '.selector1 {\n\tmargin: 0;\n\t/* This is a comment including an url http://domain.com/path/to/file.ext */\n}\n{{separator}}.div {\n\theight: 15px;\n}' },
{ input: '.tabs{width:10px;//end of line comment\nheight:10px;//another\n}\n.div{height:15px;}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}\n{{separator}}.div {\n\theight: 15px;\n}' },
{ input: '#foo {\n\tbackground-image: url(foo@2x.png);\n\t@font-face {\n\t\tfont-family: "Bitstream Vera Serif Bold";\n\t\tsrc: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");\n\t}\n}\n.div{height:15px;}', output: '#foo {\n\tbackground-image: url(foo@2x.png);\n\t@font-face {\n\t\tfont-family: "Bitstream Vera Serif Bold";\n\t\tsrc: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");\n\t}\n}\n{{separator}}.div {\n\theight: 15px;\n}' },
{ input: '@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo@2x.png);\n\t}\n\t@font-face {\n\t\tfont-family: "Bitstream Vera Serif Bold";\n\t\tsrc: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");\n\t}\n}\n.div{height:15px;}', output: '@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo@2x.png);\n\t}\n\t@font-face {\n\t\tfont-family: "Bitstream Vera Serif Bold";\n\t\tsrc: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");\n\t}\n}\n{{separator}}.div {\n\theight: 15px;\n}' },
{ input: '@font-face {\n\tfont-family: "Bitstream Vera Serif Bold";\n\tsrc: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");\n}\n@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo.png);\n\t}\n\t@media screen and (min-device-pixel-ratio: 2) {\n\t\t@font-face {\n\t\t\tfont-family: "Helvetica Neue"\n\t\t}\n\t\t#foo:hover {\n\t\t\tbackground-image: url(foo@2x.png);\n\t\t}\n\t}\n}', output: '@font-face {\n\tfont-family: "Bitstream Vera Serif Bold";\n\tsrc: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");\n}\n{{separator}}@media screen {\n\t#foo:hover {\n\t\tbackground-image: url(foo.png);\n\t}\n\t@media screen and (min-device-pixel-ratio: 2) {\n\t\t@font-face {\n\t\t\tfont-family: "Helvetica Neue"\n\t\t}\n\t\t#foo:hover {\n\t\t\tbackground-image: url(foo@2x.png);\n\t\t}\n\t}\n}' },
{ input: 'a:first-child{color:red;div:first-child{color:black;}}\n.div{height:15px;}', output: 'a:first-child {\n\tcolor: red;\n\tdiv:first-child {\n\t\tcolor: black;\n\t}\n}\n{{separator}}.div {\n\theight: 15px;\n}' },
{ input: 'a:first-child{color:red;div:not(.peq){color:black;}}\n.div{height:15px;}', output: 'a:first-child {\n\tcolor: red;\n\tdiv:not(.peq) {\n\t\tcolor: black;\n\t}\n}\n{{separator}}.div {\n\theight: 15px;\n}' },
],
}, {
name: "Functions braces",
description: "",
tests: [
{ input: '.tabs(){}', output: '.tabs() {}' },
{ input: '.tabs (){}', output: '.tabs () {}' },
{ input: '.tabs (pa, pa(1,2)), .cols { }', output: '.tabs (pa, pa(1, 2)),\n.cols {}' },
{ input: '.tabs(pa, pa(1,2)), .cols { }', output: '.tabs(pa, pa(1, 2)),\n.cols {}' },
{ input: '.tabs ( ) { }', output: '.tabs () {}' },
{ input: '.tabs( ) { }', output: '.tabs() {}' },
{ input: '.tabs (t, t2) \n{\n key: val(p1 ,p2); \n }', output: '.tabs (t, t2) {\n\tkey: val(p1, p2);\n}' },
{ unchanged: '.box-shadow(@shadow: 0 1px 3px rgba(0, 0, 0, .25)) {\n\t-webkit-box-shadow: @shadow;\n\t-moz-box-shadow: @shadow;\n\tbox-shadow: @shadow;\n}' }
],
}, {
name: "Comments",
description: "",
tests: [
{ unchanged: '/* test */' },
{ input: '.tabs{/* test */}', output: '.tabs {\n\t/* test */\n}' },
{ input: '.tabs{/* test */}', output: '.tabs {\n\t/* test */\n}' },
{ input: '/* header */.tabs {}', output: '/* header */\n\n.tabs {}' },
{ input: '.tabs {\n/* non-header */\nwidth:10px;}', output: '.tabs {\n\t/* non-header */\n\twidth: 10px;\n}' },
{ unchanged: '/* header' },
{ unchanged: '// comment' }, {
input: '.selector1 {\n\tmargin: 0; /* This is a comment including an url http://domain.com/path/to/file.ext */\n}',
output: '.selector1 {\n\tmargin: 0;\n\t/* This is a comment including an url http://domain.com/path/to/file.ext */\n}'
},
{
comment: "single line comment support (less/sass)",
input: '.tabs{\n// comment\nwidth:10px;\n}',
output: '.tabs {\n\t// comment\n\twidth: 10px;\n}'
},
{ input: '.tabs{// comment\nwidth:10px;\n}', output: '.tabs {\n\t// comment\n\twidth: 10px;\n}' },
{ input: '//comment\n.tabs{width:10px;}', output: '//comment\n.tabs {\n\twidth: 10px;\n}' },
{ input: '.tabs{//comment\n//2nd single line comment\nwidth:10px;}', output: '.tabs {\n\t//comment\n\t//2nd single line comment\n\twidth: 10px;\n}' },
{ input: '.tabs{width:10px;//end of line comment\n}', output: '.tabs {\n\twidth: 10px; //end of line comment\n}' },
{ input: '.tabs{width:10px;//end of line comment\nheight:10px;}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px;\n}' },
{ input: '.tabs{width:10px;//end of line comment\nheight:10px;//another\n}', output: '.tabs {\n\twidth: 10px; //end of line comment\n\theight: 10px; //another\n}' }
],
}, {
name: "Handle LESS property name interpolation",
description: "",
tests: [
{ unchanged: 'tag {\n\t@{prop}: none;\n}' },
{ input: 'tag{@{prop}:none;}', output: 'tag {\n\t@{prop}: none;\n}' },
{ input: 'tag{ @{prop}: none;}', output: 'tag {\n\t@{prop}: none;\n}' },
{
comment: "can also be part of property name",
unchanged: 'tag {\n\tdynamic-@{prop}: none;\n}'
},
{ input: 'tag{dynamic-@{prop}:none;}', output: 'tag {\n\tdynamic-@{prop}: none;\n}' },
{ input: 'tag{ dynamic-@{prop}: none;}', output: 'tag {\n\tdynamic-@{prop}: none;\n}' },
],
}, {
name: "Handle LESS property name interpolation, test #631",
description: "",
tests: [
{ unchanged: '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}' },
{
input: '.generate-columns(@n,@i:1) when (@i =< @n){.column-@{i}{width:(@i * 100% / @n);}.generate-columns(@n,(@i + 1));}',
output: '.generate-columns(@n, @i: 1) when (@i =< @n) {\n\t.column-@{i} {\n\t\twidth: (@i * 100% / @n);\n\t}\n\t.generate-columns(@n, (@i + 1));\n}'
}
],
}, {
name: "Psuedo-classes vs Variables",
description: "",
tests: [
{ unchanged: '@page :first {}' }, {
comment: "Assume the colon goes with the @name. If we're in LESS, this is required regardless of the at-string.",
input: '@page:first {}',
output: '@page: first {}'
},
{ unchanged: '@page: first {}' }
],
}, {
name: "SASS/SCSS",
description: "",
tests: [{
comment: "Basic Interpolation",
unchanged: 'p {\n\t$font-size: 12px;\n\t$line-height: 30px;\n\tfont: #{$font-size}/#{$line-height};\n}'
},
{ unchanged: 'p.#{$name} {}' }, {
unchanged: [
'@mixin itemPropertiesCoverItem($items, $margin) {',
'\twidth: calc((100% - ((#{$items} - 1) * #{$margin}rem)) / #{$items});',
'\tmargin: 1.6rem #{$margin}rem 1.6rem 0;',
'}'
]
},
{
comment: "Multiple filed issues in LESS due to not(:blah)",
unchanged: '&:first-of-type:not(:last-child) {}'
},
{
unchanged: [
'div {',
'\t&:not(:first-of-type) {',
'\t\tbackground: red;',
'\t}',
'}',
]
}
],
}, {
name: "Proper handling of colon in selectors",
description: "Space before a colon in a selector must be preserved, as it means pseudoclass/pseudoelement on any child",
options: [{ name: "selector_separator_newline", value: "false" }],
tests: [
{ unchanged: 'a :b {}' },
{ unchanged: 'a ::b {}' },
{ unchanged: 'a:b {}' },
{ unchanged: 'a::b {}' },
{
input: 'a {}, a::b {}, a ::b {}, a:b {}, a :b {}',
output: 'a {}\n, a::b {}\n, a ::b {}\n, a:b {}\n, a :b {}'
},
{
unchanged: [
'.card-blue ::-webkit-input-placeholder {',
'\tcolor: #87D1FF;',
'}'
]
},
{
unchanged: [
'div [attr] :not(.class) {',
'\tcolor: red;',
'}'
]
}
]
}, {
name: "Regresssion Tests",
description: "General Regression tests for known issues",
options: [{ name: "selector_separator_newline", value: "false" }],
tests: [{
unchanged: [
'@media(min-width:768px) {',
'\t.selector::after {',
'\t\t/* property: value */',
'\t}',
'\t.other-selector {',
'\t\t/* property: value */',
'\t}',
'}'
]
}, {
unchanged: [
'.fa-rotate-270 {',
'\tfilter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);',
'}'
]
}]
}, {
}
]
};
+378
View File
@@ -0,0 +1,378 @@
/*
{{&header_text}}
The MIT License (MIT)
Copyright (c) 2007-2017 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.
*/
/*jshint unused:false */
function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_beautify)
{
var default_opts = {
indent_size: 4,
indent_char: ' ',
preserve_newlines: true,
jslint_happy: false,
keep_array_indentation: false,
brace_style: 'collapse',
space_before_conditional: true,
break_chained_methods: false,
selector_separator: '\n',
end_with_newline: false
};
var opts;
{{#default_options}} default_opts.{{name}} = {{&value}};
{{/default_options}}
function reset_options()
{
opts = JSON.parse(JSON.stringify(default_opts));
}
function test_html_beautifier(input)
{
return html_beautify(input, opts);
}
var sanitytest;
// test the input on beautifier with the current flag settings
// does not check the indentation / surroundings as bt() does
function test_fragment(input, expected)
{
expected = expected || expected === '' ? expected : input;
sanitytest.expect(input, expected);
// if the expected is different from input, run it again
// expected output should be unchanged when run twice.
if (expected !== input) {
sanitytest.expect(expected, expected);
}
// Everywhere we do newlines, they should be replaced with opts.eol
opts.eol = '\r\n';
expected = expected.replace(/[\n]/g, '\r\n');
sanitytest.expect(input, expected);
if (input.indexOf('\n') !== -1) {
input = input.replace(/[\n]/g, '\r\n');
sanitytest.expect(input, expected);
// Ensure support for auto eol detection
opts.eol = 'auto';
sanitytest.expect(input, expected);
}
opts.eol = '\n';
}
// test html
function bth(input, expectation)
{
var wrapped_input, wrapped_expectation, field_input, field_expectation;
expectation = expectation || expectation === '' ? expectation : input;
sanitytest.test_function(test_html_beautifier, 'html_beautify');
test_fragment(input, expectation);
if (opts.indent_size === 4 && input) {
wrapped_input = '<div>\n' + input.replace(/^(.+)$/mg, ' $1') + '\n <span>inline</span>\n</div>';
wrapped_expectation = '<div>\n' + expectation.replace(/^(.+)$/mg, ' $1') + '\n <span>inline</span>\n</div>';
test_fragment(wrapped_input, wrapped_expectation);
}
}
function unicode_char(value) {
return String.fromCharCode(value);
}
function beautifier_tests()
{
sanitytest = test_obj;
reset_options();
//============================================================
bth('');
{{#groups}}{{#set_mustache_tags}}.{{/set_mustache_tags}}
//============================================================
{{^matrix}}
// {{&name}}
reset_options();
{{#options}}
opts.{{name}} = {{&value}};
{{/options}}
{{#tests}}
{{#test_line}}.{{/test_line}};
{{/tests}}
{{/matrix}}
{{#matrix}}
// {{&name}} - ({{#matrix_context_string}}.{{/matrix_context_string}})
reset_options();
{{#options}}
opts.{{name}} = {{&value}};
{{/options}}
{{#tests}}
{{#test_line}}.{{/test_line}};
{{/tests}}
{{/matrix}}
{{#unset_mustache_tags}}.{{/unset_mustache_tags}}{{/groups}}
}
function beautifier_unconverted_tests()
{
sanitytest = test_obj;
reset_options();
//============================================================
opts.end_with_newline = true;
test_fragment('', '\n');
test_fragment('<div></div>\n');
test_fragment('<div></div>\n\n\n', '<div></div>\n');
test_fragment('<head>\n' +
' <script>\n' +
' mocha.setup("bdd");\n' +
'\n' +
' </script>\n' +
'</head>\n');
opts.end_with_newline = false;
// error cases need love too
bth('<img title="Bad food!" src="foo.jpg" alt="Evil" ">');
bth("<!-- don't blow up if a comment is not complete"); // -->
test_fragment(
'<head>\n' +
' <script>\n' +
' mocha.setup("bdd");\n' +
' </script>\n' +
'</head>');
test_fragment('<div></div>\n', '<div></div>');
bth('<div></div>');
bth('<div>content</div>');
bth('<div><div></div></div>',
'<div>\n' +
' <div></div>\n' +
'</div>');
bth('<div><div>content</div></div>',
'<div>\n' +
' <div>content</div>\n' +
'</div>');
bth('<div>\n' +
' <span>content</span>\n' +
'</div>');
bth('<div>\n' +
'</div>');
bth('<div>\n' +
' content\n' +
'</div>');
bth('<div>\n' +
' </div>',
'<div>\n' +
'</div>');
bth(' <div>\n' +
' </div>',
'<div>\n' +
'</div>');
bth('<div>\n' +
'</div>\n' +
' <div>\n' +
' </div>',
'<div>\n' +
'</div>\n' +
'<div>\n' +
'</div>');
bth(' <div>\n' +
'</div>',
'<div>\n' +
'</div>');
bth('<div >content</div>',
'<div>content</div>');
bth('<div thinger="preserve space here" ></div >',
'<div thinger="preserve space here"></div>');
bth('content\n' +
' <div>\n' +
' </div>\n' +
'content',
'content\n' +
'<div>\n' +
'</div>\n' +
'content');
bth('<li>\n' +
' <div>\n' +
' </div>\n' +
'</li>');
bth('<li>\n' +
'<div>\n' +
'</div>\n' +
'</li>',
'<li>\n' +
' <div>\n' +
' </div>\n' +
'</li>');
bth('<li>\n' +
' content\n' +
'</li>\n' +
'<li>\n' +
' content\n' +
'</li>');
bth('<img>content');
bth('<img> content');
bth('<img> content', '<img> content');
bth('<img><img>content');
bth('<img> <img>content');
bth('<img> <img>content', '<img> <img>content');
bth('<img><b>content</b>');
bth('<img> <b>content</b>');
bth('<img> <b>content</b>', '<img> <b>content</b>');
bth('<div>content<img>content</div>');
bth('<div> content <img> content</div>');
bth('<div> content <img> content </div>',
'<div> content <img> content </div>');
bth('Text <a href="#">Link</a> Text');
var unformatted = opts.unformatted;
opts.unformatted = ['script', 'style'];
bth('<script id="javascriptTemplate" type="text/x-kendo-template">\n' +
' <ul>\n' +
' # for (var i = 0; i < data.length; i++) { #\n' +
' <li>#= data[i] #</li>\n' +
' # } #\n' +
' </ul>\n' +
'</script>');
bth('<style>\n' +
' body {background-color:lightgrey}\n' +
' h1 {color:blue}\n' +
'</style>');
opts.unformatted = unformatted;
unformatted = opts.unformatted;
opts.unformatted = ['custom-element'];
test_fragment('<div>should <custom-element>not</custom-element>' +
' insert newlines</div>',
'<div>should <custom-element>not</custom-element>' +
' insert newlines</div>');
opts.unformatted = unformatted;
// Tests that don't pass, but probably should.
// bth('<div><span>content</span></div>');
// Handlebars tests
// Without the indent option on, handlebars are treated as content.
opts.wrap_line_length = 0;
//...---------1---------2---------3---------4---------5---------6---------7
//...1234567890123456789012345678901234567890123456789012345678901234567890
bth('<div>Some text that should not wrap at all.</div>',
/* expected */
'<div>Some text that should not wrap at all.</div>');
// A value of 0 means no max line length, and should not wrap.
//...---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10--------11--------12--------13--------14--------15--------16--------17--------18--------19--------20--------21--------22--------23--------24--------25--------26--------27--------28--------29
//...12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
bth('<div>Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all.</div>',
/* expected */
'<div>Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all.</div>');
opts.wrap_line_length = "0";
//...---------1---------2---------3---------4---------5---------6---------7
//...1234567890123456789012345678901234567890123456789012345678901234567890
bth('<div>Some text that should not wrap at all.</div>',
/* expected */
'<div>Some text that should not wrap at all.</div>');
// A value of "0" means no max line length, and should not wrap
//...---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10--------11--------12--------13--------14--------15--------16--------17--------18--------19--------20--------21--------22--------23--------24--------25--------26--------27--------28--------29
//...12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
bth('<div>Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all.</div>',
/* expected */
'<div>Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all. Some text that should not wrap at all.</div>');
//BUGBUG: This should wrap before 40 not after.
opts.wrap_line_length = 40;
//...---------1---------2---------3---------4---------5---------6---------7
//...1234567890123456789012345678901234567890123456789012345678901234567890
bth('<div>Some test text that should wrap_inside_this section here.</div>',
/* expected */
'<div>Some test text that should wrap_inside_this\n' +
' section here.</div>');
opts.wrap_line_length = "40";
//...---------1---------2---------3---------4---------5---------6---------7
//...1234567890123456789012345678901234567890123456789012345678901234567890
bth('<div>Some test text that should wrap_inside_this section here.</div>',
/* expected */
'<div>Some test text that should wrap_inside_this\n' +
' section here.</div>');
opts.indent_size = 1;
opts.indent_char = '\t';
opts.preserve_newlines = false;
bth('<div>\n\tfoo\n</div>', '<div> foo </div>');
opts.preserve_newlines = true;
bth('<div>\n\tfoo\n</div>');
// test preserve_newlines and max_preserve_newlines
opts.preserve_newlines = false;
bth('<div>Should not</div>\n\n\n' +
'<div>preserve newlines</div>',
'<div>Should not</div>\n' +
'<div>preserve newlines</div>');
opts.preserve_newlines = true;
opts.max_preserve_newlines = 0;
bth('<div>Should</div>\n\n\n' +
'<div>preserve zero newlines</div>',
'<div>Should</div>\n' +
'<div>preserve zero newlines</div>');
opts.max_preserve_newlines = 1;
bth('<div>Should</div>\n\n\n' +
'<div>preserve one newline</div>',
'<div>Should</div>\n\n' +
'<div>preserve one newline</div>');
opts.max_preserve_newlines = null;
bth('<div>Should</div>\n\n\n' +
'<div>preserve one newline</div>',
'<div>Should</div>\n\n\n' +
'<div>preserve one newline</div>');
}
beautifier_tests();
beautifier_unconverted_tests();
}
if (typeof exports !== "undefined") {
exports.run_html_tests = run_html_tests;
}
+1105
View File
File diff suppressed because it is too large Load Diff
+84
View File
@@ -0,0 +1,84 @@
//--------//
// Inputs //
//--------//
var operator_position = {
sanity: [
'var res = a + b - c / d * e % f;',
'var res = g & h | i ^ j;',
'var res = (k && l || m) ? n : o;',
'var res = p >> q << r >>> s;',
'var res = t === u !== v != w == x >= y <= z > aa < ab;',
'ac + -ad'
],
comprehensive: [
'var res = a + b',
'- c /',
'd * e',
'%',
'f;',
' var res = g & h',
'| i ^',
'j;',
'var res = (k &&',
'l',
'|| m) ?',
'n',
': o',
';',
'var res = p',
'>> q <<',
'r',
'>>> s;',
'var res',
' = t',
'',
' === u !== v',
' !=',
'w',
'== x >=',
'y <= z > aa <',
'ab;',
'ac +',
'-ad'
],
colon_special_case: [
'var a = {',
' b',
': bval,',
' c:',
'cval',
' ,d: dval',
'};',
'var e = f ? g',
': h;',
'var i = j ? k :',
'l;'
],
catch_all: [
'var d = 1;',
'if (a === b',
' && c) {',
' d = (c * everything',
' / something_else) %',
' b;',
' e',
' += d;',
'',
'} else if (!(complex && simple) ||',
' (emotion && emotion.name === "happy")) {',
' cryTearsOfJoy(many ||',
' anOcean',
' || aRiver);',
'}'
]
};
//---------//
// Exports //
//---------//
module.exports = {
operator_position: operator_position
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+216
View File
@@ -0,0 +1,216 @@
#!/usr/bin/env node
/*
The MIT License (MIT)
Copyright (c) 2007-2017 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.
*/
var fs = require('fs');
var mustache = require('mustache');
var path = require('path');
function generate_tests() {
// javascript
generate_test_files('javascript', 'bt', 'js/test/generated/beautify-javascript-tests.js', 'python/jsbeautifier/tests/generated/tests.py');
// css
generate_test_files('css', 't', 'js/test/generated/beautify-css-tests.js', 'python/cssbeautifier/tests/generated/tests.py');
// html
// no python html beautifier, so no tests
generate_test_files('html', 'bth', 'js/test/generated/beautify-html-tests.js');
}
function generate_test_files(data_folder, test_method, node_output, python_output) {
var data_file_path, input_path, template_file_path;
var test_data, template;
input_path = path.resolve(__dirname, 'data', data_folder);
data_file_path = path.resolve(input_path, 'tests.js');
test_data = require(data_file_path).test_data;
template_file_path = path.resolve(input_path, 'node.mustache');
template = fs.readFileSync(template_file_path, { encoding: 'utf-8' });
set_formatters(test_data, test_method, '// ');
set_generated_header(test_data, data_file_path, template_file_path);
fs.writeFileSync(path.resolve(__dirname, '..', node_output),
mustache.render(template, test_data), { encoding: 'utf-8' });
if (python_output) {
template_file_path = path.resolve(input_path, 'python.mustache');
template = fs.readFileSync(template_file_path, { encoding: 'utf-8' });
set_formatters(test_data, test_method, '# ');
set_generated_header(test_data, data_file_path, template_file_path);
fs.writeFileSync(path.resolve(__dirname, '..', python_output),
mustache.render(template, test_data), { encoding: 'utf-8' });
}
}
function set_generated_header(data, data_file_path, template_file_path) {
var relative_script_path = path.relative(process.cwd(), __filename).split(path.sep).join('/');
var relative_data_file_path = path.relative(process.cwd(), data_file_path).split(path.sep).join('/');
var relative_template_file_path = path.relative(process.cwd(), template_file_path).split(path.sep).join('/');
data.header_text =
' AUTO-GENERATED. DO NOT MODIFY.\n' +
' Script: ' + relative_script_path + '\n' +
' Template: ' + relative_template_file_path + '\n' +
' Data: ' + relative_data_file_path;
}
function isStringOrArray(val) {
return typeof val === 'string' || val instanceof Array;
}
function getTestString(val) {
val = val.split('\n');
var result = "'" + val.join("\\n' +\n '").replace(/\t/g, '\\t') + "'";
result = result.replace(/' \+\n ''$/, "'");
return result;
}
function set_formatters(data, test_method, comment_mark) {
// utility mustache functions
data.matrix_context_string = function() {
var context = this;
return function(text, render) {
var outputs = [];
// text is ignored for this
for (var name in context) {
if (name === 'options') {
continue;
}
if (context.hasOwnProperty(name)) {
outputs.push(name + ' = "' + context[name].replace(/\n/g, '\\n').replace(/\t/g, '\\t') + '"');
}
}
return render(outputs.join(', '));
};
};
data.test_line = function() {
return function(text, render) {
var method_text = this.fragment ? 'test_fragment' : test_method;
var comment = '';
var before_input = method_text + '(';
var input = null;
var before_output = ', ';
var output = null;
// text is ignored for this.
if (typeof this.comment === 'string') {
this.comment = this.comment.split('\n');
}
if (this.comment instanceof Array) {
comment = '\n ' + comment_mark + this.comment.join('\n ' + comment_mark) + '\n ';
}
// input: the default field
// input_: allow underscore for formatting alignment with "output"
// unchanged: use "unchanged" instead of "input" if there is no output
input = this.input || this.input_ || this.unchanged;
if (input instanceof Array) {
input = input.join('\n');
}
if (isStringOrArray(this.output)) {
output = this.output;
if (output instanceof Array) {
output = output.join('\n');
}
}
// Do all most error checking
if (!(this.input !== null || this.input_ !== null || this.unchanged !== null)) {
throw "Missing test input field (input, input_, or unchanged).";
} else if ((this.input !== null && (this.input_ !== null || this.unchanged !== null)) &&
(this.input_ === null || this.unchanged === null)) {
throw "Only one test input field allowed (input, input_, or unchanged): " + input;
} else if (output && isStringOrArray(this.unchanged)) {
throw "Cannot specify 'output' with 'unchanged' test input: " + input;
} else if (!output && !isStringOrArray(this.unchanged)) {
throw "Neither 'output' nor 'unchanged' specified for test input: " + input;
} else if (input === output) {
// Raw input and output can be the same, just omit output.
throw "Test strings are identical. Omit 'output' and use 'unchanged': " + input;
}
if (output && output.indexOf('<%') !== -1) {
mustache.tags = ['<%', '%>'];
}
input = getTestString(render(input));
if (output) {
output = getTestString(render(output));
} else {
output = '';
}
if (output && output.indexOf('<%') !== -1) {
mustache.tags = ['{{', '}}'];
}
if (this.input_ || input.indexOf('\n') !== -1 || output.indexOf('\n') !== -1) {
before_input = method_text + '(\n ';
before_output = ',\n ' + comment_mark + ' -- output --\n ';
}
if (output === '') {
before_output = '';
}
// Rendered input and output can be the same, just omit output.
if (output === input) {
before_output = '';
output = '';
}
return comment + before_input + input + before_output + output + ')';
};
};
data.set_mustache_tags = function() {
return function( /* text, render */ ) {
if (this.template) {
mustache.tags = this.template.split(' ');
}
return '';
};
};
data.unset_mustache_tags = function() {
return function( /* text , render */ ) {
if (this.template) {
mustache.tags = ['{{', '}}'];
}
return '';
};
};
}
generate_tests();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+140
View File
@@ -0,0 +1,140 @@
#!/usr/bin/env bash
REL_SCRIPT_DIR="`dirname \"$0\"`"
SCRIPT_DIR="`( cd \"$REL_SCRIPT_DIR\" && pwd )`"
PROJECT_DIR="`( cd \"$SCRIPT_DIR/..\" && pwd )`"
build_help()
{
echo "build.sh <action>"
echo " full - build and test of all implementations"
echo " all - build of both implementations"
echo " js - build of javascript"
echo " py - build of python"
echo " alltest - test both implementations, js and python"
echo " pytest - test python implementation"
echo " jstest - test javascript implementation"
}
build_ci()
{
build_full
build_git_status
}
build_full()
{
build_all
build_alltest
}
build_all()
{
build_py
build_js
}
build_py()
{
echo Building python module...
pip install -e ./python || exit 1
}
build_js()
{
echo Building javascript...
npm install || exit 1
generate_tests
# jshint
$PROJECT_DIR/node_modules/.bin/jshint 'js' 'test' || exit 1
# beautify test and data
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/test/amd-beautify-tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/test/node-beautify-html-perf-tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/test/node-beautify-perf-tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/test/node-beautify-tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/test/sanitytest.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/test/data/css/tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/test/data/html/tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/test/data/javascript/inputlib.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/test/data/javascript/tests.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/test/generate-tests.js || exit 1
# beautify product code
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/unpackers/javascriptobfuscator_unpacker.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/unpackers/myobfuscate_unpacker.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/unpackers/p_a_c_k_e_r_unpacker.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/unpackers/urlencode_unpacker.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/beautify-css.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/beautify-html.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/beautify.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/lib/cli.js || exit 1
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/index.js || exit 1
# html not ready yet
# $PROJECT_DIR/js/bin/html-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r index.html
# jshint again to make sure things haven't changed
$PROJECT_DIR/node_modules/.bin/jshint 'js' 'test' || exit 1
}
generate_tests()
{
node test/generate-tests.js || exit 1
}
build_alltest()
{
build_jstest
build_pytest
}
build_pytest()
{
echo Testing python implementation...
generate_tests
cd python
python --version
./jsbeautifier/tests/shell-smoke-test.sh || exit 1
}
build_jstest()
{
echo Testing javascript implementation...
generate_tests
node --version
./js/test/shell-smoke-test.sh || exit 1
}
build_git_status()
{
$SCRIPT_DIR/git-status-clear.sh || exit 1
}
build_update-codemirror()
{
rm -rf node_modules/codemirror
npm install codemirror
rm -rf ./web/third-party/codemirror/*
cp ./node_modules/codemirror/LICENSE ./web/third-party/codemirror/
cp ./node_modules/codemirror/README.md ./web/third-party/codemirror/
cp -r ./node_modules/codemirror/lib ./web/third-party/codemirror/
mkdir -p ./web/third-party/codemirror/mode
cp -r ./node_modules/codemirror/mode/javascript ./web/third-party/codemirror/mode/
git add -Av ./web/third-party/codemirror
}
main() {
cd $PROJECT_DIR
local ACTION
ACTION=build_${1:-full}
if [ -n "$(type -t $ACTION)" ] && [ "$(type -t $ACTION)" = "function" ]; then
$ACTION
else
build_help
fi
}
(main $*)
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
REL_SCRIPT_DIR="`dirname \"$0\"`"
SCRIPT_DIR="`( cd \"$REL_SCRIPT_DIR\" && pwd )`"
# based on https://gist.github.com/joelittlejohn/5937573
#
main()
{
cd $SCRIPT_DIR/..
if [ "$#" -ne 1 ]; then
echo "Usage: ./generate-changelog.sh user/repo"
exit 1
fi
IFS=$'\n'
echo "# Changelog" > CHANGELOG.md
for m in $(curl -s "https://api.github.com/repos/$1/milestones?state=closed" | jq -c '.[] | [.title, .number, .description]' | gsort -r -V); do
mid=$(echo $m | sed 's/\[".*",\(.*\),".*"\]/\1/')
title=$(echo $m | sed 's/\["\(.*\)",.*,".*"\]/\1/')
echo "Processing milestone: $title..."
echo $m | sed 's/\["\(.*\)",.*\]/## \1/' >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo '### Description' >> CHANGELOG.md
echo $m | sed 's/\[".*",.*,"\(.*\)"\]/\1/' | sed -e 's/\\"/"/g' | sed -e 's/\\r\\n/\\n/g' | sed -e 's/\\n/\'$'\n/g' >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo '### Closed Issues' >> CHANGELOG.md
for i in $(curl -s "https://api.github.com/repos/$1/issues?milestone=$mid&state=closed" | jq -c '.[] | [.html_url, .number, .title]'); do
echo $i | sed 's/\["\(.*\)",\(.*\),\"\(.*\)\"\]/* \3 ([#\2](\1))/' | sed 's/\\"/"/g' >> CHANGELOG.md
done
echo "" >> CHANGELOG.md
echo "" >> CHANGELOG.md
done
}
(main $*)
+18
View File
@@ -0,0 +1,18 @@
echo "Post-build git status check..."
echo "Ensuring no changes visible to git have been made to '$*' ..."
git status $* | egrep -q 'nothing to commit.*working (directory|tree) clean' || {
# we should find nothing to commit. If we don't, build has failed.
echo "ERROR: Post-build git status check - FAILED."
echo "Git status reported changes to non-git-ignore'd files."
echo "TO REPRO: Run 'git status $*'. The use git gui or git diff to see what was changed during the build."
echo "TO FIX: Amend your commit and rebuild. Repeat until git status reports no changes both before and after the build."
echo "OUTPUT FOR 'git status $*':"
git status $*
echo "."
echo "OUTPUT FOR 'git diff $*':"
git diff $* | cat -t -e
exit 1
}
echo "Post-build git status check - Succeeded."
exit 0
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
REL_SCRIPT_DIR="`dirname \"$0\"`"
SCRIPT_DIR="`( cd \"$REL_SCRIPT_DIR\" && pwd )`"
case "$OSTYPE" in
darwin*) PLATFORM="OSX" ;;
linux*) PLATFORM="LINUX" ;;
bsd*) PLATFORM="BSD" ;;
*) PLATFORM="UNKNOWN" ;;
esac
generate_changelog()
{
$SCRIPT_DIR/generate-changelog.sh beautify-web/js-beautify || exit 1
git commit -am "Update Changelog for $NEW_VERSION"
}
release_python()
{
git clean -xfd || exit 1
echo "__version__ = '$NEW_VERSION'" > python/jsbeautifier/__version__.py
git commit -am "Python $NEW_VERSION"
cd python
python setup.py register -r pypi
python setup.py sdist upload -r pypi
git push
}
release_node()
{
git clean -xfd || exit 1
npm version $NEW_VERSION
npm publish .
git push
git push --tags
}
release_web()
{
local ORIGINAL_BRANCH
ORIGINAL_BRANCH=$(git branch | grep '[*] .*' | awk '{print $2}')
git clean -xfd || exit 1
git fetch || exit 1
git checkout -B gh-pages origin/gh-pages || exit 1
git merge origin/master && git push || exit 1
git checkout $ORIGINAL_BRANCH
}
sedi() {
if [[ "$PLATFORM" == "OSX" || "$PLATFORM" == "BSD" ]]; then
sed -i "" $@
elif [ "$PLATFORM" == "LINUX" ]; then
sed -i $@
else
exit 1
fi
}
update_readme_versions()
{
git clean -xfd || exit 1
sedi -E 's@(cdn.rawgit.+beautify/v)[^/]+@\1'$NEW_VERSION'@' README.md
sedi -E 's@(cdnjs.cloudflare.+beautify/)[^/]+@\1'$NEW_VERSION'@' README.md
sedi -E 's/\((README\.md:.js-beautify@).+\)/(\1'$NEW_VERSION')/' README.md
git add README.md
git commit -m "Bump version numbers in README.md"
}
main()
{
cd $SCRIPT_DIR/..
local NEW_VERSION=$1
NEW_VERSION=$1
git checkout master
generate_changelog
update_readme_versions
(release_python)
release_node
release_web
}
(main $*)