mirror of
https://github.com/beautifier/js-beautify.git
synced 2025-01-31 09:52:17 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
ef7e2cdd61
@ -5,34 +5,42 @@
|
||||
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.
|
||||
Fixes and enhancements are totally welcome. We prefer you to file an issue before filing a PR, as this gives us chance to discuss design details, but feel 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.
|
||||
This repository holds two mostly identical implementations of the beautifiers: a JavaScript implementation and a Python implementation.
|
||||
While developing, you may locally build and test the JavaScript or Python (or both). 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 implementation of your choice
|
||||
* Make changes to the implementation of your choice.
|
||||
* If working in the JavaScript implementation:
|
||||
* Run `./build js`
|
||||
* Run `./build static` to see changes served locally
|
||||
* If working in the Python implementation:
|
||||
* Run `./build py`
|
||||
* Run `./build static` to see changes served locally
|
||||
* 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 implementations 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. :(
|
||||
Any changes made to one implementation must be also made to the other implementation. **This is required**. Every time we make an exception to this requirement the project becomes harder to maintain. This will become painfully clear, should you find yourself unable to port changes from one implementation to the other due to implementations being out of sync. We made this a requirement several years ago and there are **still** open issues for changes that people 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.
|
||||
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, go ahead and file 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.
|
||||
Update documentation as needed. This includes files such as the README.md, internal command-line help, and file comments.
|
||||
Also, check if your change needs any tooling updates. For example, the CDN URLs required additional 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.
|
||||
* Run `./build full` locally after commit but before creation of Pull Request. You may start a Pull Request even if this reports errors, but the PR will not be merged until all errors are fixed.
|
||||
* 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.
|
||||
* Pull requests must pass build checks on all platforms before being merged. We use Travis CI and AppVeyor to run tests on Linux and Windows across multiple versions of Node.js and Python.
|
||||
|
||||
|
||||
# Folders
|
||||
|
||||
@ -45,12 +53,11 @@ Files related to the JavaScript implementations of the beautifiers.
|
||||
## `python`
|
||||
Files related to the Python implementations of the beautifiers.
|
||||
|
||||
|
||||
## `web`
|
||||
Files related to http://jsbeautifier.org/.
|
||||
|
||||
## `test`
|
||||
Test data files and support files used to generate implementation-specific test files from them.
|
||||
Test data files and support files used to generate implementation-specific test files.
|
||||
|
||||
|
||||
# Branches
|
||||
@ -84,14 +91,14 @@ available on branch `attic-other`. Take a look and feel free to resurrect them,
|
||||
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.
|
||||
The `attic-genericeval` branch includes an unpacker that calls `eval` on whatever source is passed to it.
|
||||
This file may be useful when working with source that unpacks itself when `eval` is called on it, but is also very unsafe.
|
||||
We have isolated it on this separate branch to keep it from hurting the other children.
|
||||
|
||||
# Publishing a Release
|
||||
Each platform has it's own release process.
|
||||
Each platform has its own release process.
|
||||
|
||||
NOTE: Before you do any of these make sure the latest changes have passed the Travis CI build!
|
||||
NOTE: Before you do any of the following 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.
|
||||
@ -126,7 +133,7 @@ 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.
|
||||
NPM makes this process even simpler than Python's and also creates a tag for the release.
|
||||
|
||||
```bash
|
||||
git clean -xfd
|
||||
|
29
README.md
29
README.md
@ -13,11 +13,19 @@
|
||||
[![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
|
||||
This little beautifier will reformat and re-indent bookmarklets, ugly
|
||||
JavaScript, unpack scripts packed by Dean Edward’s popular packer,
|
||||
as well as deobfuscate scripts processed by
|
||||
[javascriptobfuscator.com](http://javascriptobfuscator.com/).
|
||||
|
||||
# Contributors Needed
|
||||
I'm putting this front and center above because existing owners have very limited time to work on this project currently.
|
||||
This is a popular project and widely used but it desperately needs contributors who have time to commit to fixing both
|
||||
customer facing bugs and underlying problems with the internal design and implementation.
|
||||
|
||||
If you are interested, please take a look at the [CONTRIBUTING.md](https://github.com/beautify-web/js-beautify/blob/master/CONTRIBUTING.md) then fix an issue marked with the ["Good first issue"](https://github.com/beautify-web/js-beautify/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label and submit a PR. Repeat as often as possible. Thanks!
|
||||
|
||||
|
||||
# Usage
|
||||
You can beautify javascript using JS Beautifier in your web browser, or on the command-line using node.js or python.
|
||||
|
||||
@ -86,7 +94,7 @@ You can also use `js-beautify` as a `node` library (install locally, the `npm` d
|
||||
$ npm install js-beautify
|
||||
```
|
||||
|
||||
Import and call the approriate beautifier method for javascript (js), css, or html. All three method signatures are `beautify(code, options)`. `code` is a the string of code to be beautified. options is an object with the settings you would like used to beautify the code.
|
||||
Import and call the appropriate beautifier method for javascript (js), css, or html. All three method signatures are `beautify(code, options)`. `code` is the string of code to be beautified. options is an object with the settings you would like used to beautify the code.
|
||||
|
||||
The configuration option names are the same as the CLI names but with underscores instead of dashes. For example, `--indent-size 2 --space-in-empty-paren` would be `{ indent_size: 2, space_in_empty_paren: true }`.
|
||||
|
||||
@ -202,12 +210,10 @@ Configuration sources provided earlier in this stack will override later ones.
|
||||
|
||||
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.
|
||||
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:
|
||||
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
|
||||
{
|
||||
@ -236,13 +242,13 @@ Using the above example would have the following result:
|
||||
* 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
|
||||
* 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`
|
||||
* Inherit `indent_size` of 4 spaces from the top-level setting.
|
||||
* Set `preserve-newlines` to `true`.
|
||||
|
||||
### CSS & HTML
|
||||
|
||||
@ -316,8 +322,7 @@ var a = 1;
|
||||
|
||||
# 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)
|
||||
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
|
||||
|
||||
|
316
index.html
316
index.html
@ -35,100 +35,7 @@
|
||||
<script src="web/third-party/codemirror/lib/codemirror.js"></script>
|
||||
<script src="web/third-party/codemirror/mode/javascript/javascript.js"></script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: #eee;
|
||||
color: #333;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
a.self {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: #444;
|
||||
border-bottom: 1px solid #aaa
|
||||
}
|
||||
p, select, label, .blurb, a.turn-off-codemirror {
|
||||
font:13px/1.231 arial, sans-serif;
|
||||
*font-size:small;
|
||||
}
|
||||
a.turn-off-codemirror {
|
||||
margin-left: 25px;
|
||||
}
|
||||
button.submit {
|
||||
width: 100%;
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
button.submit em {
|
||||
font-size: 11px;
|
||||
font-style: normal;
|
||||
color: #999;
|
||||
}
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
select {
|
||||
width: 220px;
|
||||
}
|
||||
table#options {
|
||||
float: right;
|
||||
}
|
||||
table#options td {
|
||||
vertical-align: top;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.col-6 {
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
#about {
|
||||
float: left;
|
||||
}
|
||||
#about p {
|
||||
margin: 0 6px 6px 0;
|
||||
}
|
||||
.uses li {
|
||||
padding-top: 3px;
|
||||
line-height: 150%;
|
||||
}
|
||||
.uses li.sep {
|
||||
margin-top: 8px;
|
||||
}
|
||||
#testresults {
|
||||
display: none;
|
||||
font-family: monaco, "lucida console", "courier new", monospace;
|
||||
}
|
||||
.CodeMirror {
|
||||
border: 1px solid #ccc;
|
||||
height: 450px;
|
||||
font-size: 90%;
|
||||
margin-bottom: 6px;
|
||||
background: white;
|
||||
}
|
||||
p {
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
a {
|
||||
white-space: nowrap;
|
||||
color: #36d;
|
||||
}
|
||||
.contributor-sep {
|
||||
clear: left;
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 8px;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 32px;
|
||||
margin-left: 40px;
|
||||
margin-bottom: 0;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="web/common-style.css"></style>
|
||||
|
||||
<script src="web/third-party/jquery/jquery.js"></script>
|
||||
<script src="web/third-party/jquery/jquery.cookie.js"></script>
|
||||
@ -144,166 +51,7 @@
|
||||
<script src="js/lib/unpackers/urlencode_unpacker.js"></script>
|
||||
<script src="js/lib/unpackers/p_a_c_k_e_r_unpacker.js"></script>
|
||||
<script src="js/lib/unpackers/myobfuscate_unpacker.js"></script>
|
||||
|
||||
<script>
|
||||
var the = {
|
||||
use_codemirror: (!window.location.href.match(/without-codemirror/)),
|
||||
beautify_in_progress: false,
|
||||
editor: null // codemirror editor
|
||||
};
|
||||
|
||||
function run_tests() {
|
||||
var st = new SanityTest();
|
||||
run_javascript_tests(st, Urlencoded, js_beautify, html_beautify, css_beautify);
|
||||
run_css_tests(st, Urlencoded, js_beautify, html_beautify, css_beautify);
|
||||
run_html_tests(st, Urlencoded, js_beautify, html_beautify, css_beautify);
|
||||
JavascriptObfuscator.run_tests(st);
|
||||
P_A_C_K_E_R.run_tests(st);
|
||||
Urlencoded.run_tests(st);
|
||||
MyObfuscate.run_tests(st);
|
||||
var results = st.results_raw()
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/ /g, ' ')
|
||||
.replace(/\r/g, '·')
|
||||
.replace(/\n/g, '<br>');
|
||||
$('#testresults').html(results).show();
|
||||
}
|
||||
|
||||
|
||||
function any(a, b) {
|
||||
return a || b;
|
||||
}
|
||||
|
||||
function read_settings_from_cookie() {
|
||||
$('#tabsize').val(any($.cookie('tabsize'), '4'));
|
||||
$('#brace-style').val(any($.cookie('brace-style'), 'collapse'));
|
||||
$('#detect-packers').prop('checked', $.cookie('detect-packers') !== 'off');
|
||||
$('#max-preserve-newlines').val(any($.cookie('max-preserve-newlines'), '5'));
|
||||
$('#keep-array-indentation').prop('checked', $.cookie('keep-array-indentation') === 'on');
|
||||
$('#break-chained-methods').prop('checked', $.cookie('break-chained-methods') === 'on');
|
||||
$('#indent-scripts').val(any($.cookie('indent-scripts'), 'normal'));
|
||||
$('#space-before-conditional').prop('checked', $.cookie('space-before-conditional') !== 'off');
|
||||
$('#wrap-line-length').val(any($.cookie('wrap-line-length'), '0'));
|
||||
$('#unescape-strings').prop('checked', $.cookie('unescape-strings') === 'on');
|
||||
$('#jslint-happy').prop('checked', $.cookie('jslint-happy') === 'on');
|
||||
$('#end-with-newline').prop('checked', $.cookie('end-with-newline') === 'on');
|
||||
$('#indent-inner-html').prop('checked', $.cookie('indent-inner-html') === 'on');
|
||||
$('#comma-first').prop('checked', $.cookie('comma-first') === 'on');
|
||||
$('#e4x').prop('checked', $.cookie('e4x') === 'on');
|
||||
}
|
||||
|
||||
function store_settings_to_cookie() {
|
||||
var opts = {
|
||||
expires: 360
|
||||
};
|
||||
$.cookie('tabsize', $('#tabsize').val(), opts);
|
||||
$.cookie('brace-style', $('#brace-style').val(), opts);
|
||||
$.cookie('detect-packers', $('#detect-packers').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('max-preserve-newlines', $('#max-preserve-newlines').val(), opts);
|
||||
$.cookie('keep-array-indentation', $('#keep-array-indentation').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('break-chained-methods', $('#break-chained-methods').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('space-before-conditional', $('#space-before-conditional').prop('checked') ? 'on' : 'off',
|
||||
opts);
|
||||
$.cookie('unescape-strings', $('#unescape-strings').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('jslint-happy', $('#jslint-happy').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('end-with-newline', $('#end-with-newline').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('wrap-line-length', $('#wrap-line-length').val(), opts);
|
||||
$.cookie('indent-scripts', $('#indent-scripts').val(), opts);
|
||||
$.cookie('indent-inner-html', $('#indent-inner-html').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('comma-first', $('#comma-first').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('e4x', $('#e4x').prop('checked') ? 'on' : 'off', opts);
|
||||
|
||||
}
|
||||
|
||||
function unpacker_filter(source) {
|
||||
var trailing_comments = '',
|
||||
comment = '',
|
||||
unpacked = '',
|
||||
found = false;
|
||||
|
||||
// cut trailing comments
|
||||
do {
|
||||
found = false;
|
||||
if (/^\s*\/\*/.test(source)) {
|
||||
found = true;
|
||||
comment = source.substr(0, source.indexOf('*/') + 2);
|
||||
source = source.substr(comment.length).replace(/^\s+/, '');
|
||||
trailing_comments += comment + "\n";
|
||||
} else if (/^\s*\/\//.test(source)) {
|
||||
found = true;
|
||||
comment = source.match(/^\s*\/\/.*/)[0];
|
||||
source = source.substr(comment.length).replace(/^\s+/, '');
|
||||
trailing_comments += comment + "\n";
|
||||
}
|
||||
} while (found);
|
||||
|
||||
var unpackers = [P_A_C_K_E_R, Urlencoded, JavascriptObfuscator/*, MyObfuscate*/];
|
||||
for (var i = 0; i < unpackers.length; i++) {
|
||||
if (unpackers[i].detect(source)) {
|
||||
unpacked = unpackers[i].unpack(source);
|
||||
if (unpacked != source) {
|
||||
source = unpacker_filter(unpacked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trailing_comments + source;
|
||||
}
|
||||
|
||||
|
||||
function beautify() {
|
||||
if (the.beautify_in_progress) return;
|
||||
|
||||
store_settings_to_cookie();
|
||||
|
||||
the.beautify_in_progress = true;
|
||||
|
||||
var source = the.editor ? the.editor.getValue() : $('#source').val(),
|
||||
output,
|
||||
opts = {};
|
||||
|
||||
opts.indent_size = $('#tabsize').val();
|
||||
opts.indent_char = opts.indent_size == 1 ? '\t' : ' ';
|
||||
opts.max_preserve_newlines = $('#max-preserve-newlines').val();
|
||||
opts.preserve_newlines = opts.max_preserve_newlines !== "-1";
|
||||
opts.keep_array_indentation = $('#keep-array-indentation').prop('checked');
|
||||
opts.break_chained_methods = $('#break-chained-methods').prop('checked');
|
||||
opts.indent_scripts = $('#indent-scripts').val();
|
||||
opts.brace_style = $('#brace-style').val() + ($('#brace-preserve-inline').prop('checked') ? ",preserve-inline" : "");
|
||||
opts.space_before_conditional = $('#space-before-conditional').prop('checked');
|
||||
opts.unescape_strings = $('#unescape-strings').prop('checked');
|
||||
opts.jslint_happy = $('#jslint-happy').prop('checked');
|
||||
opts.end_with_newline = $('#end-with-newline').prop('checked');
|
||||
opts.wrap_line_length = $('#wrap-line-length').val();
|
||||
opts.indent_inner_html = $('#indent-inner-html').prop('checked');
|
||||
opts.comma_first = $('#comma-first').prop('checked');
|
||||
opts.e4x = $('#e4x').prop('checked');
|
||||
|
||||
if (looks_like_html(source)) {
|
||||
output = html_beautify(source, opts);
|
||||
} else {
|
||||
if ($('#detect-packers').prop('checked')) {
|
||||
source = unpacker_filter(source);
|
||||
}
|
||||
output = js_beautify(source, opts);
|
||||
}
|
||||
if (the.editor) {
|
||||
the.editor.setValue(output);
|
||||
} else {
|
||||
$('#source').val(output);
|
||||
}
|
||||
|
||||
the.beautify_in_progress = false;
|
||||
}
|
||||
|
||||
function looks_like_html(source) {
|
||||
// <foo> - looks like html
|
||||
var trimmed = source.replace(/^[ \t\n\r]+/, '');
|
||||
return trimmed && (trimmed.substring(0, 1) === '<');
|
||||
}
|
||||
</script>
|
||||
<script src="web/common-function.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -499,64 +247,8 @@
|
||||
|
||||
</div>
|
||||
<div id="testresults"></div>
|
||||
<script>
|
||||
$(function () {
|
||||
|
||||
read_settings_from_cookie();
|
||||
|
||||
var default_text =
|
||||
"// This is just a sample script. Paste your real code (javascript or HTML) here.\n\nif ('this_is'==/an_example/){of_beautifier();}else{var a=b?(c%d):e[f];}";
|
||||
var textArea = $('#source')[0];
|
||||
|
||||
if (the.use_codemirror && typeof CodeMirror !== 'undefined') {
|
||||
the.editor = CodeMirror.fromTextArea(textArea, {
|
||||
theme: 'default',
|
||||
lineNumbers: true
|
||||
});
|
||||
the.editor.focus();
|
||||
|
||||
the.editor.setValue(default_text);
|
||||
$('.CodeMirror').click(function () {
|
||||
if (the.editor.getValue() == default_text) {
|
||||
the.editor.setValue('');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#source').val(default_text).bind('click focus', function () {
|
||||
if ($(this).val() == default_text) {
|
||||
$(this).val('');
|
||||
}
|
||||
}).bind('blur', function () {
|
||||
if (!$(this).val()) {
|
||||
$(this).val(default_text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(window).bind('keydown', function (e) {
|
||||
if (e.ctrlKey && e.keyCode == 13) {
|
||||
beautify();
|
||||
}
|
||||
})
|
||||
$('.submit').click(beautify);
|
||||
$('select').change(beautify);
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
var _gaq = [
|
||||
['_setAccount', 'UA-7409939-1'],
|
||||
['_trackPageview']
|
||||
];
|
||||
(function (d, t) {
|
||||
var g = d.createElement(t),
|
||||
s = d.getElementsByTagName(t)[0];
|
||||
g.src = '//www.google-analytics.com/ga.js';
|
||||
s.parentNode.insertBefore(g, s);
|
||||
}(document, 'script'));
|
||||
</script>
|
||||
<script src="web/onload.js"></script>
|
||||
<script src="web/google-analytics.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
37
python/jsbeautifier/tests/test-packer.py
Normal file
37
python/jsbeautifier/tests/test-packer.py
Normal file
@ -0,0 +1,37 @@
|
||||
import sys
|
||||
import jsbeautifier
|
||||
|
||||
opts = jsbeautifier.default_options()
|
||||
opts.eol = "\n"
|
||||
global fails
|
||||
fails = 0
|
||||
|
||||
|
||||
def test_str(str, expected):
|
||||
global fails
|
||||
res = jsbeautifier.beautify(str, opts)
|
||||
if(res == expected):
|
||||
print "."
|
||||
return True
|
||||
else:
|
||||
print "___got:" + res + "\n___expected:" + expected + "\n"
|
||||
fails = fails + 1
|
||||
return False
|
||||
|
||||
str = "eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[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}('2 0=\"4 3!\";2 1=0.5(/b/6);a.9(\"8\").7=1;',12,12,'str|n|var|W3Schools|Visit|search|i|innerHTML|demo|getElementById|document|w3Schools'.split('|'),0,{}))"
|
||||
expected = "var str = \"Visit W3Schools!\";\nvar n = str.search(/w3Schools/i);\ndocument.getElementById(\"demo\").innerHTML = n;"
|
||||
|
||||
res = test_str(str, expected)
|
||||
|
||||
str = "a=b;\r\nwhile(1){\ng=h;{return'\\w+'};break;eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[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}('$(5).4(3(){$(\'.1\').0(2);$(\'.6\').0(d);$(\'.7\').0(b);$(\'.a\').0(8);$(\'.9\').0(c)});',14,14,'html|r5e57|8080|function|ready|document|r1655|rc15b|8888|r39b0|r6ae9|3128|65309|80'.split('|'),0,{}))c=abx;"
|
||||
expected = "a = b;\nwhile (1) {\n g = h; {\n return '\w+'\n };\n break;\n $(document).ready(function() {\n $('.r5e57').html(8080);\n $('.r1655').html(80);\n $('.rc15b').html(3128);\n $('.r6ae9').html(8888);\n $('.r39b0').html(65309)\n });\n c = abx;"
|
||||
|
||||
res = test_str(str, expected)
|
||||
|
||||
str = "eval(function(p,a,c,k,e,r){e=function(c){return c.toString(36)};if('0'.replace(0,e)==0){while(c--)r[e(c)]=k[c];k=[function(e){return r[e]||e}];e=function(){return'[0-9ab]'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$(5).a(6(){ $(\'.8\').0(1); $(\'.b\').0(4); $(\'.9\').0(2); $(\'.7\').0(3)})',[],12,'html|52136|555|65103|8088|document|function|r542c|r8ce6|rb0de|ready|rfab0'.split('|'),0,{}))"
|
||||
expected = "$(document).ready(function() {\n $(\'.r8ce6\').html(52136);\n $(\'.rfab0\').html(8088);\n $(\'.rb0de\').html(555);\n $(\'.r542c\').html(65103)\n})"
|
||||
|
||||
res = test_str(str, expected)
|
||||
|
||||
if (fails == 0):
|
||||
print "OK"
|
@ -18,9 +18,27 @@ from jsbeautifier.unpackers import UnpackingError
|
||||
|
||||
PRIORITY = 1
|
||||
|
||||
|
||||
def detect(source):
|
||||
global beginstr
|
||||
global endstr
|
||||
beginstr = ''
|
||||
endstr = ''
|
||||
"""Detects whether `source` is P.A.C.K.E.R. coded."""
|
||||
return source.replace(' ', '').startswith('eval(function(p,a,c,k,e,')
|
||||
mystr = source.replace(' ', '').find('eval(function(p,a,c,k,e,')
|
||||
if(mystr > 0):
|
||||
beginstr = source[:mystr]
|
||||
if(mystr != -1):
|
||||
""" Find endstr"""
|
||||
if(source.split("')))", 1)[0] == source):
|
||||
try:
|
||||
endstr = source.split("}))", 1)[1]
|
||||
except IndexError:
|
||||
endstr = ''
|
||||
else:
|
||||
endstr = source.split("')))", 1)[1]
|
||||
return (mystr != -1)
|
||||
|
||||
|
||||
def unpack(source):
|
||||
"""Unpacks P.A.C.K.E.R. packed js code."""
|
||||
@ -36,21 +54,26 @@ def unpack(source):
|
||||
|
||||
def lookup(match):
|
||||
"""Look up symbols in the synthetic symtab."""
|
||||
word = match.group(0)
|
||||
word = match.group(0)
|
||||
return symtab[unbase(word)] or word
|
||||
|
||||
source = re.sub(r'\b\w+\b', lookup, payload)
|
||||
return _replacestrings(source)
|
||||
|
||||
|
||||
def _filterargs(source):
|
||||
"""Juice from a source file the four args needed by decoder."""
|
||||
juicers = [ (r"}\('(.*)', *(\d+), *(\d+), *'(.*)'\.split\('\|'\), *(\d+), *(.*)\)\)"),
|
||||
(r"}\('(.*)', *(\d+), *(\d+), *'(.*)'\.split\('\|'\)"),
|
||||
juicers = [ (r"}\('(.*)', *(\d+|\[\]), *(\d+), *'(.*)'\.split\('\|'\), *(\d+), *(.*)\)\)"),
|
||||
(r"}\('(.*)', *(\d+|\[\]), *(\d+), *'(.*)'\.split\('\|'\)"),
|
||||
]
|
||||
for juicer in juicers:
|
||||
args = re.search(juicer, source, re.DOTALL)
|
||||
if args:
|
||||
a = args.groups()
|
||||
if a[1] == "[]":
|
||||
a = list(a)
|
||||
a[1] = 62
|
||||
a = tuple(a)
|
||||
try:
|
||||
return a[0], a[3].split('|'), int(a[1]), int(a[2])
|
||||
except ValueError:
|
||||
@ -60,8 +83,9 @@ def _filterargs(source):
|
||||
raise UnpackingError('Could not make sense of p.a.c.k.e.r data (unexpected code structure)')
|
||||
|
||||
|
||||
|
||||
def _replacestrings(source):
|
||||
global beginstr
|
||||
global endstr
|
||||
"""Strip string lookup table (list) and replace values in source."""
|
||||
match = re.search(r'var *(_\w+)\=\["(.*?)"\];', source, re.DOTALL)
|
||||
|
||||
@ -73,23 +97,27 @@ def _replacestrings(source):
|
||||
for index, value in enumerate(lookup):
|
||||
source = source.replace(variable % index, '"%s"' % value)
|
||||
return source[startpoint:]
|
||||
return source
|
||||
return beginstr + source + endstr
|
||||
|
||||
|
||||
class Unbaser(object):
|
||||
"""Functor for a given base. Will efficiently convert
|
||||
strings to natural numbers."""
|
||||
ALPHABET = {
|
||||
53 : '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ',
|
||||
59 : '0123456789abcdefghijklmnopqrstuvwABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
62 : '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
95 : (' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
ALPHABET = {
|
||||
62: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
95: (' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
'[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
|
||||
}
|
||||
|
||||
def __init__(self, base):
|
||||
self.base = base
|
||||
|
||||
# fill elements 37...61, if necessary
|
||||
if 36 < base < 62:
|
||||
if not hasattr(self.ALPHABET, self.ALPHABET[62][:base]):
|
||||
self.ALPHABET[base] = self.ALPHABET[62][:base]
|
||||
# attrs = self.ALPHABET
|
||||
# print ', '.join("%s: %s" % item for item in attrs.items())
|
||||
# If base can be handled by int() builtin, let it do it for us
|
||||
if 2 <= base <= 36:
|
||||
self.unbase = lambda string: int(string, base)
|
||||
|
169
tools/build.sh
169
tools/build.sh
@ -6,32 +6,39 @@ 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"
|
||||
echo "build.sh <action>"
|
||||
echo " full - build and test all implementations"
|
||||
echo " all - build both implementations"
|
||||
echo " static - serve static version of site locally"
|
||||
echo " js - build javascript"
|
||||
echo " py - build 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_git_status
|
||||
}
|
||||
|
||||
build_full()
|
||||
{
|
||||
build_all
|
||||
build_alltest
|
||||
build_all
|
||||
build_alltest
|
||||
}
|
||||
|
||||
build_all()
|
||||
{
|
||||
build_py
|
||||
build_js
|
||||
build_py
|
||||
build_js
|
||||
}
|
||||
|
||||
build_static()
|
||||
{
|
||||
npm install || exit 1
|
||||
./node_modules/.bin/static
|
||||
}
|
||||
|
||||
build_py()
|
||||
@ -42,108 +49,108 @@ build_py()
|
||||
|
||||
build_js()
|
||||
{
|
||||
echo Building javascript...
|
||||
npm install || exit 1
|
||||
generate_tests
|
||||
echo Building javascript...
|
||||
npm install || exit 1
|
||||
generate_tests
|
||||
|
||||
# generate lib files
|
||||
./node_modules/.bin/webpack
|
||||
# generate lib files
|
||||
./node_modules/.bin/webpack
|
||||
|
||||
# Wrap webkit output into an non-breaking form.
|
||||
# In an upcoming verion these will be replaced with standard webpack umd
|
||||
cat ./tools/template/beautify.begin.js > ./js/lib/beautify.js
|
||||
cat ./dist/legacy_beautify_js.js >> ./js/lib/beautify.js
|
||||
cat ./tools/template/beautify.end.js >> ./js/lib/beautify.js
|
||||
# Wrap webkit output into an non-breaking form.
|
||||
# In an upcoming verion these will be replaced with standard webpack umd
|
||||
cat ./tools/template/beautify.begin.js > ./js/lib/beautify.js
|
||||
cat ./dist/legacy_beautify_js.js >> ./js/lib/beautify.js
|
||||
cat ./tools/template/beautify.end.js >> ./js/lib/beautify.js
|
||||
|
||||
cat ./tools/template/beautify-css.begin.js > ./js/lib/beautify-css.js
|
||||
cat ./dist/legacy_beautify_css.js >> ./js/lib/beautify-css.js
|
||||
cat ./tools/template/beautify-css.end.js >> ./js/lib/beautify-css.js
|
||||
cat ./tools/template/beautify-css.begin.js > ./js/lib/beautify-css.js
|
||||
cat ./dist/legacy_beautify_css.js >> ./js/lib/beautify-css.js
|
||||
cat ./tools/template/beautify-css.end.js >> ./js/lib/beautify-css.js
|
||||
|
||||
cat ./tools/template/beautify-html.begin.js > ./js/lib/beautify-html.js
|
||||
cat ./dist/legacy_beautify_html.js >> ./js/lib/beautify-html.js
|
||||
cat ./tools/template/beautify-html.end.js >> ./js/lib/beautify-html.js
|
||||
cat ./tools/template/beautify-html.begin.js > ./js/lib/beautify-html.js
|
||||
cat ./dist/legacy_beautify_html.js >> ./js/lib/beautify-html.js
|
||||
cat ./tools/template/beautify-html.end.js >> ./js/lib/beautify-html.js
|
||||
|
||||
# jshint
|
||||
$PROJECT_DIR/node_modules/.bin/jshint 'js/src' 'test' || exit 1
|
||||
# jshint
|
||||
$PROJECT_DIR/node_modules/.bin/jshint 'js/src' '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 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/src/css/index.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/html/index.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/javascript/index.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/javascript/beautifier.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/javascript/tokenizer.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/src/css/index.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/html/index.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/javascript/index.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/javascript/beautifier.js || exit 1
|
||||
$PROJECT_DIR/js/bin/js-beautify.js --config $PROJECT_DIR/jsbeautifyrc -r $PROJECT_DIR/js/src/javascript/tokenizer.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
|
||||
$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
|
||||
# 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/src' 'test' || exit 1
|
||||
# jshint again to make sure things haven't changed
|
||||
$PROJECT_DIR/node_modules/.bin/jshint 'js/src' 'test' || exit 1
|
||||
}
|
||||
|
||||
generate_tests()
|
||||
{
|
||||
node test/generate-tests.js || exit 1
|
||||
node test/generate-tests.js || exit 1
|
||||
}
|
||||
|
||||
build_alltest()
|
||||
{
|
||||
build_jstest
|
||||
build_pytest
|
||||
build_jstest
|
||||
build_pytest
|
||||
}
|
||||
|
||||
build_pytest()
|
||||
{
|
||||
echo Testing python implementation...
|
||||
generate_tests
|
||||
cd python
|
||||
python --version
|
||||
./jsbeautifier/tests/shell-smoke-test.sh || exit 1
|
||||
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
|
||||
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
|
||||
$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
|
||||
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() {
|
||||
|
157
web/common-function.js
Normal file
157
web/common-function.js
Normal file
@ -0,0 +1,157 @@
|
||||
var the = {
|
||||
use_codemirror: (!window.location.href.match(/without-codemirror/)),
|
||||
beautify_in_progress: false,
|
||||
editor: null // codemirror editor
|
||||
};
|
||||
|
||||
function run_tests() {
|
||||
var st = new SanityTest();
|
||||
run_javascript_tests(st, Urlencoded, js_beautify, html_beautify, css_beautify);
|
||||
run_css_tests(st, Urlencoded, js_beautify, html_beautify, css_beautify);
|
||||
run_html_tests(st, Urlencoded, js_beautify, html_beautify, css_beautify);
|
||||
JavascriptObfuscator.run_tests(st);
|
||||
P_A_C_K_E_R.run_tests(st);
|
||||
Urlencoded.run_tests(st);
|
||||
MyObfuscate.run_tests(st);
|
||||
var results = st.results_raw()
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/ /g, ' ')
|
||||
.replace(/\r/g, '·')
|
||||
.replace(/\n/g, '<br>');
|
||||
$('#testresults').html(results).show();
|
||||
}
|
||||
|
||||
|
||||
function any(a, b) {
|
||||
return a || b;
|
||||
}
|
||||
|
||||
function read_settings_from_cookie() {
|
||||
$('#tabsize').val(any($.cookie('tabsize'), '4'));
|
||||
$('#brace-style').val(any($.cookie('brace-style'), 'collapse'));
|
||||
$('#detect-packers').prop('checked', $.cookie('detect-packers') !== 'off');
|
||||
$('#max-preserve-newlines').val(any($.cookie('max-preserve-newlines'), '5'));
|
||||
$('#keep-array-indentation').prop('checked', $.cookie('keep-array-indentation') === 'on');
|
||||
$('#break-chained-methods').prop('checked', $.cookie('break-chained-methods') === 'on');
|
||||
$('#indent-scripts').val(any($.cookie('indent-scripts'), 'normal'));
|
||||
$('#space-before-conditional').prop('checked', $.cookie('space-before-conditional') !== 'off');
|
||||
$('#wrap-line-length').val(any($.cookie('wrap-line-length'), '0'));
|
||||
$('#unescape-strings').prop('checked', $.cookie('unescape-strings') === 'on');
|
||||
$('#jslint-happy').prop('checked', $.cookie('jslint-happy') === 'on');
|
||||
$('#end-with-newline').prop('checked', $.cookie('end-with-newline') === 'on');
|
||||
$('#indent-inner-html').prop('checked', $.cookie('indent-inner-html') === 'on');
|
||||
$('#comma-first').prop('checked', $.cookie('comma-first') === 'on');
|
||||
$('#e4x').prop('checked', $.cookie('e4x') === 'on');
|
||||
}
|
||||
|
||||
function store_settings_to_cookie() {
|
||||
var opts = {
|
||||
expires: 360
|
||||
};
|
||||
$.cookie('tabsize', $('#tabsize').val(), opts);
|
||||
$.cookie('brace-style', $('#brace-style').val(), opts);
|
||||
$.cookie('detect-packers', $('#detect-packers').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('max-preserve-newlines', $('#max-preserve-newlines').val(), opts);
|
||||
$.cookie('keep-array-indentation', $('#keep-array-indentation').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('break-chained-methods', $('#break-chained-methods').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('space-before-conditional', $('#space-before-conditional').prop('checked') ? 'on' : 'off',
|
||||
opts);
|
||||
$.cookie('unescape-strings', $('#unescape-strings').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('jslint-happy', $('#jslint-happy').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('end-with-newline', $('#end-with-newline').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('wrap-line-length', $('#wrap-line-length').val(), opts);
|
||||
$.cookie('indent-scripts', $('#indent-scripts').val(), opts);
|
||||
$.cookie('indent-inner-html', $('#indent-inner-html').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('comma-first', $('#comma-first').prop('checked') ? 'on' : 'off', opts);
|
||||
$.cookie('e4x', $('#e4x').prop('checked') ? 'on' : 'off', opts);
|
||||
|
||||
}
|
||||
|
||||
function unpacker_filter(source) {
|
||||
var trailing_comments = '',
|
||||
comment = '',
|
||||
unpacked = '',
|
||||
found = false;
|
||||
|
||||
// cut trailing comments
|
||||
do {
|
||||
found = false;
|
||||
if (/^\s*\/\*/.test(source)) {
|
||||
found = true;
|
||||
comment = source.substr(0, source.indexOf('*/') + 2);
|
||||
source = source.substr(comment.length).replace(/^\s+/, '');
|
||||
trailing_comments += comment + "\n";
|
||||
} else if (/^\s*\/\//.test(source)) {
|
||||
found = true;
|
||||
comment = source.match(/^\s*\/\/.*/)[0];
|
||||
source = source.substr(comment.length).replace(/^\s+/, '');
|
||||
trailing_comments += comment + "\n";
|
||||
}
|
||||
} while (found);
|
||||
|
||||
var unpackers = [P_A_C_K_E_R, Urlencoded, JavascriptObfuscator/*, MyObfuscate*/];
|
||||
for (var i = 0; i < unpackers.length; i++) {
|
||||
if (unpackers[i].detect(source)) {
|
||||
unpacked = unpackers[i].unpack(source);
|
||||
if (unpacked != source) {
|
||||
source = unpacker_filter(unpacked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trailing_comments + source;
|
||||
}
|
||||
|
||||
|
||||
function beautify() {
|
||||
if (the.beautify_in_progress) return;
|
||||
|
||||
store_settings_to_cookie();
|
||||
|
||||
the.beautify_in_progress = true;
|
||||
|
||||
var source = the.editor ? the.editor.getValue() : $('#source').val(),
|
||||
output,
|
||||
opts = {};
|
||||
|
||||
opts.indent_size = $('#tabsize').val();
|
||||
opts.indent_char = opts.indent_size == 1 ? '\t' : ' ';
|
||||
opts.max_preserve_newlines = $('#max-preserve-newlines').val();
|
||||
opts.preserve_newlines = opts.max_preserve_newlines !== "-1";
|
||||
opts.keep_array_indentation = $('#keep-array-indentation').prop('checked');
|
||||
opts.break_chained_methods = $('#break-chained-methods').prop('checked');
|
||||
opts.indent_scripts = $('#indent-scripts').val();
|
||||
opts.brace_style = $('#brace-style').val() + ($('#brace-preserve-inline').prop('checked') ? ",preserve-inline" : "");
|
||||
opts.space_before_conditional = $('#space-before-conditional').prop('checked');
|
||||
opts.unescape_strings = $('#unescape-strings').prop('checked');
|
||||
opts.jslint_happy = $('#jslint-happy').prop('checked');
|
||||
opts.end_with_newline = $('#end-with-newline').prop('checked');
|
||||
opts.wrap_line_length = $('#wrap-line-length').val();
|
||||
opts.indent_inner_html = $('#indent-inner-html').prop('checked');
|
||||
opts.comma_first = $('#comma-first').prop('checked');
|
||||
opts.e4x = $('#e4x').prop('checked');
|
||||
|
||||
if (looks_like_html(source)) {
|
||||
output = html_beautify(source, opts);
|
||||
} else {
|
||||
if ($('#detect-packers').prop('checked')) {
|
||||
source = unpacker_filter(source);
|
||||
}
|
||||
output = js_beautify(source, opts);
|
||||
}
|
||||
if (the.editor) {
|
||||
the.editor.setValue(output);
|
||||
} else {
|
||||
$('#source').val(output);
|
||||
}
|
||||
|
||||
the.beautify_in_progress = false;
|
||||
}
|
||||
|
||||
function looks_like_html(source) {
|
||||
// <foo> - looks like html
|
||||
var trimmed = source.replace(/^[ \t\n\r]+/, '');
|
||||
return trimmed && (trimmed.substring(0, 1) === '<');
|
||||
}
|
92
web/common-style.css
Normal file
92
web/common-style.css
Normal file
@ -0,0 +1,92 @@
|
||||
body {
|
||||
background: #eee;
|
||||
color: #333;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
a.self {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: #444;
|
||||
border-bottom: 1px solid #aaa
|
||||
}
|
||||
p, select, label, .blurb, a.turn-off-codemirror {
|
||||
font:13px/1.231 arial, sans-serif;
|
||||
*font-size:small;
|
||||
}
|
||||
a.turn-off-codemirror {
|
||||
margin-left: 25px;
|
||||
}
|
||||
button.submit {
|
||||
width: 100%;
|
||||
padding: 10px 0;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
button.submit em {
|
||||
font-size: 11px;
|
||||
font-style: normal;
|
||||
color: #999;
|
||||
}
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
select {
|
||||
width: 220px;
|
||||
}
|
||||
table#options {
|
||||
float: right;
|
||||
}
|
||||
table#options td {
|
||||
vertical-align: top;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.col-6 {
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
#about {
|
||||
float: left;
|
||||
}
|
||||
#about p {
|
||||
margin: 0 6px 6px 0;
|
||||
}
|
||||
.uses li {
|
||||
padding-top: 3px;
|
||||
line-height: 150%;
|
||||
}
|
||||
.uses li.sep {
|
||||
margin-top: 8px;
|
||||
}
|
||||
#testresults {
|
||||
display: none;
|
||||
font-family: monaco, "lucida console", "courier new", monospace;
|
||||
}
|
||||
.CodeMirror {
|
||||
border: 1px solid #ccc;
|
||||
height: 450px;
|
||||
font-size: 90%;
|
||||
margin-bottom: 6px;
|
||||
background: white;
|
||||
}
|
||||
p {
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
a {
|
||||
white-space: nowrap;
|
||||
color: #36d;
|
||||
}
|
||||
.contributor-sep {
|
||||
clear: left;
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 8px;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 32px;
|
||||
margin-left: 40px;
|
||||
margin-bottom: 0;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
}
|
10
web/google-analytics.js
Normal file
10
web/google-analytics.js
Normal file
@ -0,0 +1,10 @@
|
||||
var _gaq = [
|
||||
['_setAccount', 'UA-7409939-1'],
|
||||
['_trackPageview']
|
||||
];
|
||||
(function (d, t) {
|
||||
var g = d.createElement(t),
|
||||
s = d.getElementsByTagName(t)[0];
|
||||
g.src = '//www.google-analytics.com/ga.js';
|
||||
s.parentNode.insertBefore(g, s);
|
||||
}(document, 'script'));
|
44
web/onload.js
Normal file
44
web/onload.js
Normal file
@ -0,0 +1,44 @@
|
||||
$(function () {
|
||||
|
||||
read_settings_from_cookie();
|
||||
|
||||
var default_text =
|
||||
"// This is just a sample script. Paste your real code (javascript or HTML) here.\n\nif ('this_is'==/an_example/){of_beautifier();}else{var a=b?(c%d):e[f];}";
|
||||
var textArea = $('#source')[0];
|
||||
|
||||
if (the.use_codemirror && typeof CodeMirror !== 'undefined') {
|
||||
the.editor = CodeMirror.fromTextArea(textArea, {
|
||||
theme: 'default',
|
||||
lineNumbers: true
|
||||
});
|
||||
the.editor.focus();
|
||||
|
||||
the.editor.setValue(default_text);
|
||||
$('.CodeMirror').click(function () {
|
||||
if (the.editor.getValue() == default_text) {
|
||||
the.editor.setValue('');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('#source').val(default_text).bind('click focus', function () {
|
||||
if ($(this).val() == default_text) {
|
||||
$(this).val('');
|
||||
}
|
||||
}).bind('blur', function () {
|
||||
if (!$(this).val()) {
|
||||
$(this).val(default_text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(window).bind('keydown', function (e) {
|
||||
if (e.ctrlKey && e.keyCode == 13) {
|
||||
beautify();
|
||||
}
|
||||
})
|
||||
$('.submit').click(beautify);
|
||||
$('select').change(beautify);
|
||||
|
||||
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user