js-beautify 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.document +5 -0
  2. data/.gitmodules +4 -0
  3. data/Gemfile +13 -0
  4. data/Gemfile.lock +27 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +13 -0
  7. data/Rakefile +29 -0
  8. data/VERSION +1 -0
  9. data/bin/js-beautify +5 -0
  10. data/init.sh +3 -0
  11. data/js-beautify-copy/.gitmodules +3 -0
  12. data/js-beautify-copy/Makefile +71 -0
  13. data/js-beautify-copy/README.md +39 -0
  14. data/js-beautify-copy/attic/beautify-cl/beautify-cl.js +142 -0
  15. data/js-beautify-copy/attic/bin/beautify_js +80 -0
  16. data/js-beautify-copy/attic/opera-userscript/beautifier.js +1087 -0
  17. data/js-beautify-copy/attic/opera-userscript/make_opera_userscript.sh +42 -0
  18. data/js-beautify-copy/attic/qtscript/jsbeautify.cpp +121 -0
  19. data/js-beautify-copy/attic/qtscript/jsbeautify.pro +5 -0
  20. data/js-beautify-copy/attic/qtscript/jsbeautify.qrc +6 -0
  21. data/js-beautify-copy/attic/qtscript/readme.txt +28 -0
  22. data/js-beautify-copy/attic/readme.txt +2 -0
  23. data/js-beautify-copy/attic/unmaintained/bbedit/jsBeautify_BBED.scpt +522 -0
  24. data/js-beautify-copy/attic/unmaintained/c-sharp/JSBeautify.cs +801 -0
  25. data/js-beautify-copy/attic/v8/README.txt +40 -0
  26. data/js-beautify-copy/attic/v8/beautify.h +2390 -0
  27. data/js-beautify-copy/attic/v8/jsbeautify.cpp +215 -0
  28. data/js-beautify-copy/beautify-css.js +198 -0
  29. data/js-beautify-copy/beautify-html.js +514 -0
  30. data/js-beautify-copy/beautify.js +1293 -0
  31. data/js-beautify-copy/favicon.png +0 -0
  32. data/js-beautify-copy/index.html +401 -0
  33. data/js-beautify-copy/jquery/jquery.cookie.js +96 -0
  34. data/js-beautify-copy/jquery/jquery.js +167 -0
  35. data/js-beautify-copy/license.txt +24 -0
  36. data/js-beautify-copy/php/jsbeautifier.php +1599 -0
  37. data/js-beautify-copy/php/test.php +476 -0
  38. data/js-beautify-copy/python/MANIFEST.in +2 -0
  39. data/js-beautify-copy/python/js-beautify +7 -0
  40. data/js-beautify-copy/python/js-beautify-profile +16 -0
  41. data/js-beautify-copy/python/js-beautify-test +10 -0
  42. data/js-beautify-copy/python/jsbeautifier/__init__.py +1166 -0
  43. data/js-beautify-copy/python/jsbeautifier/tests/__init__.py +1 -0
  44. data/js-beautify-copy/python/jsbeautifier/tests/testindentation.py +43 -0
  45. data/js-beautify-copy/python/jsbeautifier/tests/testjsbeautifier.py +464 -0
  46. data/js-beautify-copy/python/jsbeautifier/unpackers/README.specs.mkd +25 -0
  47. data/js-beautify-copy/python/jsbeautifier/unpackers/__init__.py +67 -0
  48. data/js-beautify-copy/python/jsbeautifier/unpackers/evalbased.py +39 -0
  49. data/js-beautify-copy/python/jsbeautifier/unpackers/javascriptobfuscator.py +58 -0
  50. data/js-beautify-copy/python/jsbeautifier/unpackers/myobfuscate.py +86 -0
  51. data/js-beautify-copy/python/jsbeautifier/unpackers/packer.py +104 -0
  52. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/__init__.py +2 -0
  53. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/test-myobfuscate-input.js +1 -0
  54. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/test-myobfuscate-output.js +65 -0
  55. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/test-packer-62-input.js +1 -0
  56. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/test-packer-non62-input.js +1 -0
  57. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/testjavascriptobfuscator.py +46 -0
  58. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/testmyobfuscate.py +40 -0
  59. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/testpacker.py +34 -0
  60. data/js-beautify-copy/python/jsbeautifier/unpackers/tests/testurlencode.py +36 -0
  61. data/js-beautify-copy/python/jsbeautifier/unpackers/urlencode.py +34 -0
  62. data/js-beautify-copy/python/setup.py +17 -0
  63. data/js-beautify-copy/tests/beautify-tests.js +489 -0
  64. data/js-beautify-copy/tests/run-tests +17 -0
  65. data/js-beautify-copy/tests/sanitytest.js +128 -0
  66. data/js-beautify-copy/unpackers/javascriptobfuscator_unpacker.js +103 -0
  67. data/js-beautify-copy/unpackers/myobfuscate_unpacker.js +81 -0
  68. data/js-beautify-copy/unpackers/p_a_c_k_e_r_unpacker.js +61 -0
  69. data/js-beautify-copy/unpackers/urlencode_unpacker.js +51 -0
  70. data/lib/js-beautify.rb +0 -0
  71. data/test/helper.rb +18 -0
  72. data/test/test_js-beautify.rb +7 -0
  73. data/update.sh +23 -0
  74. metadata +173 -0
@@ -0,0 +1 @@
1
+ eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(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}('9 H=(j["Y"]["n"]("1h")!=-1)?s:v;9 I=(j["Y"]["w"]()["n"]("1i")!=-1)?s:v;9 J=(j["K"]["n"]("1j")!=-1)?s:v;p Z(){9 a;9 b;9 c;y{b=o z("l.l.7");a=b.P("$Q")}A(c){};i(!a){y{b=o z("l.l.6");a="R 6,0,21,0";b["1k"]="1l";a=b.P("$Q")}A(c){}};i(!a){y{b=o z("l.l.3");a=b.P("$Q")}A(c){}};i(!a){y{b=o z("l.l.3");a="R 3,0,18,0"}A(c){}};i(!a){y{b=o z("l.l");a="R 2,0,0,11"}A(c){a=-1}};m a};p 10(){9 a=-1;i(j["t"]!=12&&j["t"]["13"]>0){i(j["t"]["L M 2.0"]||j["t"]["L M"]){9 b=j["t"]["L M 2.0"]?" 2.0":"";9 c=j["t"]["L M"+b]["1m"];9 d=c["B"](" ");9 e=d[2]["B"](".");9 f=e[0];9 g=e[1];9 h=d[3];i(h==""){h=d[4]};i(h[0]=="d"){h=h["S"](1)}k{i(h[0]=="r"){h=h["S"](1);i(h["n"]("d")>0){h=h["S"](0,h["n"]("d"))}}};9 a=f+"."+g+"."+h}}k{i(j["K"]["w"]()["n"]("T/2.6")!=-1){a=4}k{i(j["K"]["w"]()["n"]("T/2.5")!=-1){a=3}k{i(j["K"]["w"]()["n"]("T")!=-1){a=2}k{i(H&&I&&!J){a=Z()}}}}};m a};p 1n(a,b,c){C=10();i(C==-1){m v}k{i(C!=0){i(H&&I&&!J){14=C["B"](" ");15=14[1];D=15["B"](",")}k{D=C["B"](".")};9 d=D[0];9 e=D[1];9 f=D[2];i(d>E(a)){m s}k{i(d==E(a)){i(e>E(b)){m s}k{i(e==E(b)){i(f>=E(c)){m s}}}}};m v}}};p 16(a,b){i(a["n"]("?")!=-1){m a["1o"](/\\?/,b+"?")}k{m a+b}};p U(a,b,c){9 d="";i(H&&I&&!J){d+="<17 ";N(9 e V a){d+=e+"=""+a[e]+"" "};d+=">";N(9 e V b){d+="<1p 19=""+e+"" 1q=""+b[e]+"" /> "};d+="</17>"}k{d+="<1a ";N(9 e V c){d+=e+"=""+c[e]+"" "};d+="> </1a>"};1r["1s"](d)};p 1t(){9 a=W(1b,".1u","1c","1d:1v-1w-1x-1y-1e","1z/x-1A-1B");U(a["u"],a["F"],a["q"])};p 1C(){9 a=W(1b,".1D","X","1d:1E-1F-1G-1H-1e",12);U(a["u"],a["F"],a["q"])};p W(a,b,c,d,e){9 f=o O();f["q"]=o O();f["F"]=o O();f["u"]=o O();N(9 g=0;g<a["13"];g=g+2){9 h=a[g]["w"]();1I(h){8"1f":G;8"1J":f["q"][a[g]]=a[g+1];G;8"X":;8"1c":a[g+1]=16(a[g+1],b);f["q"]["X"]=a[g+1];f["F"][c]=a[g+1];G;8"1K":;8"1L":;8"1M":;8"1N":;8"1O":;8"1P":;8"1Q":;8"1R":;8"1S":;8"1T":;8"1U":;8"1V":;8"1W":;8"1X":;8"1Y":;8"1Z":;8"20":;8"22":;8"23":;8"24":;8"25":;8"26":;8"27":;8"28":;8"29":;8"2a":;8"2b":;8"2c":;8"2d":;8"2e":;8"2f":;8"2g":;8"2h":;8"2i":;8"2j":;8"2k":;8"2l":;8"1g":;8"2m":;8"2n":f["u"][a[g]]=a[g+1];G;8"2o":;8"2p":;8"2q":;8"2r":;8"2s":;8"2t":;8"2u":;8"2v":;8"19":;8"2w":f["q"][a[g]]=f["u"][a[g]]=a[g+1];G;2x:f["q"][a[g]]=f["F"][a[g]]=a[g+1]}};f["u"]["1f"]=d;i(e){f["q"]["1g"]=e};m f};',62,158,'||||||||case|var|||||||||if|navigator|else|ShockwaveFlash|return|indexOf|new|function|embedAttrs||true|plugins|objAttrs|false|toLowerCase||try|ActiveXObject|catch|split|versionStr|versionArray|parseFloat|params|break|isIE|isWin|isOpera|userAgent|Shockwave|Flash|for|Object|GetVariable|version|WIN|substring|webtv|AC_Generateobj|in|AC_GetArgs|src|appVersion|ControlVersion|GetSwfVer||null|length|tempArray|tempString|AC_AddExtension|object||name|embed|arguments|movie|clsid|444553540000|classid|type|MSIE|win|Opera|AllowScriptAccess|always|description|DetectFlashVer|replace|param|value|document|write|AC_FL_RunContent|swf|d27cdb6e|ae6d|11cf|96b8|application|shockwave|flash|AC_SW_RunContent|dcr|166B1BCA|3F9C|11CF|8075|switch|pluginspage|onafterupdate|onbeforeupdate|onblur|oncellchange|onclick|ondblclick|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondrop|onfinish|onfocus|onhelp|onmousedown|onmouseup||onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup|onload|onlosecapture|onpropertychange|onreadystatechange|onrowsdelete|onrowenter|onrowexit|onrowsinserted|onstart|onscroll|onbeforeeditfocus|onactivate|onbeforedeactivate|ondeactivate|codebase|id|width|height|align|vspace|hspace|class|title|accesskey|tabindex|default'.split('|'),0,{}))
@@ -0,0 +1 @@
1
+ var isIE=(navigator["appVersion"]["indexOf"]("MSIE")!=-1)?true:false;var isWin=(navigator["appVersion"]["toLowerCase"]()["indexOf"]("win")!=-1)?true:false;var isOpera=(navigator["userAgent"]["indexOf"]("Opera")!=-1)?true:false;function ControlVersion(){var a;var b;var c;try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");a=b.GetVariable("$version")}catch(c){};if(!a){try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");a="WIN 6,0,21,0";b["AllowScriptAccess"]="always";a=b.GetVariable("$version")}catch(c){}};if(!a){try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");a=b.GetVariable("$version")}catch(c){}};if(!a){try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");a="WIN 3,0,18,0"}catch(c){}};if(!a){try{b=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");a="WIN 2,0,0,11"}catch(c){a=-1}};return a};function GetSwfVer(){var a=-1;if(navigator["plugins"]!=null&&navigator["plugins"]["length"]>0){if(navigator["plugins"]["Shockwave Flash 2.0"]||navigator["plugins"]["Shockwave Flash"]){var b=navigator["plugins"]["Shockwave Flash 2.0"]?" 2.0":"";var c=navigator["plugins"]["Shockwave Flash"+b]["description"];var d=c["split"](" ");var e=d[2]["split"](".");var f=e[0];var g=e[1];var h=d[3];if(h==""){h=d[4]};if(h[0]=="d"){h=h["substring"](1)}else{if(h[0]=="r"){h=h["substring"](1);if(h["indexOf"]("d")>0){h=h["substring"](0,h["indexOf"]("d"))}}};var a=f+"."+g+"."+h}}else{if(navigator["userAgent"]["toLowerCase"]()["indexOf"]("webtv/2.6")!=-1){a=4}else{if(navigator["userAgent"]["toLowerCase"]()["indexOf"]("webtv/2.5")!=-1){a=3}else{if(navigator["userAgent"]["toLowerCase"]()["indexOf"]("webtv")!=-1){a=2}else{if(isIE&&isWin&&!isOpera){a=ControlVersion()}}}}};return a};function DetectFlashVer(a,b,c){versionStr=GetSwfVer();if(versionStr==-1){return false}else{if(versionStr!=0){if(isIE&&isWin&&!isOpera){tempArray=versionStr["split"](" ");tempString=tempArray[1];versionArray=tempString["split"](",")}else{versionArray=versionStr["split"](".")};var d=versionArray[0];var e=versionArray[1];var f=versionArray[2];if(d>parseFloat(a)){return true}else{if(d==parseFloat(a)){if(e>parseFloat(b)){return true}else{if(e==parseFloat(b)){if(f>=parseFloat(c)){return true}}}}};return false}}};function AC_AddExtension(a,b){if(a["indexOf"]("?")!=-1){return a["replace"](/\?/,b+"?")}else{return a+b}};function AC_Generateobj(a,b,c){var d="";if(isIE&&isWin&&!isOpera){d+="<object ";for(var e in a){d+=e+"=""+a[e]+"" "};d+=">";for(var e in b){d+="<param name=""+e+"" value=""+b[e]+"" /> "};d+="</object>"}else{d+="<embed ";for(var e in c){d+=e+"=""+c[e]+"" "};d+="> </embed>"};document["write"](d)};function AC_FL_RunContent(){var a=AC_GetArgs(arguments,".swf","movie","clsid:d27cdb6e-ae6d-11cf-96b8-444553540000","application/x-shockwave-flash");AC_Generateobj(a["objAttrs"],a["params"],a["embedAttrs"])};function AC_SW_RunContent(){var a=AC_GetArgs(arguments,".dcr","src","clsid:166B1BCA-3F9C-11CF-8075-444553540000",null);AC_Generateobj(a["objAttrs"],a["params"],a["embedAttrs"])};function AC_GetArgs(a,b,c,d,e){var f=new Object();f["embedAttrs"]=new Object();f["params"]=new Object();f["objAttrs"]=new Object();for(var g=0;g<a["length"];g=g+2){var h=a[g]["toLowerCase"]();switch(h){case"classid":break;case"pluginspage":f["embedAttrs"][a[g]]=a[g+1];break;case"src":;case"movie":a[g+1]=AC_AddExtension(a[g+1],b);f["embedAttrs"]["src"]=a[g+1];f["params"][c]=a[g+1];break;case"onafterupdate":;case"onbeforeupdate":;case"onblur":;case"oncellchange":;case"onclick":;case"ondblclick":;case"ondrag":;case"ondragend":;case"ondragenter":;case"ondragleave":;case"ondragover":;case"ondrop":;case"onfinish":;case"onfocus":;case"onhelp":;case"onmousedown":;case"onmouseup":;case"onmouseover":;case"onmousemove":;case"onmouseout":;case"onkeypress":;case"onkeydown":;case"onkeyup":;case"onload":;case"onlosecapture":;case"onpropertychange":;case"onreadystatechange":;case"onrowsdelete":;case"onrowenter":;case"onrowexit":;case"onrowsinserted":;case"onstart":;case"onscroll":;case"onbeforeeditfocus":;case"onactivate":;case"onbeforedeactivate":;case"ondeactivate":;case"type":;case"codebase":;case"id":f["objAttrs"][a[g]]=a[g+1];break;case"width":;case"height":;case"align":;case"vspace":;case"hspace":;case"class":;case"title":;case"accesskey":;case"name":;case"tabindex":f["embedAttrs"][a[g]]=f["objAttrs"][a[g]]=a[g+1];break;default:f["embedAttrs"][a[g]]=f["params"][a[g]]=a[g+1]}};f["objAttrs"]["classid"]=d;if(e){f["embedAttrs"]["type"]=e};return f};
@@ -0,0 +1,46 @@
1
+ #
2
+ # written by Stefano Sanfilippo <a.little.coder@gmail.com>
3
+ #
4
+
5
+ """Tests for JavaScriptObfuscator unpacker."""
6
+
7
+ import unittest
8
+ from jsbeautifier.unpackers.javascriptobfuscator import (
9
+ unpack, detect, smartsplit)
10
+
11
+ # pylint: disable=R0904
12
+ class TestJavascriptObfuscator(unittest.TestCase):
13
+ """JavascriptObfuscator.com test case."""
14
+ def test_smartsplit(self):
15
+ """Test smartsplit() function."""
16
+ split = smartsplit
17
+ equals = lambda data, result: self.assertEqual(split(data), result)
18
+
19
+ equals('', [])
20
+ equals('"a", "b"', ['"a"', '"b"'])
21
+ equals('"aaa","bbbb"', ['"aaa"', '"bbbb"'])
22
+ equals('"a", "b\\\""', ['"a"', '"b\\\""'])
23
+
24
+ def test_detect(self):
25
+ """Test detect() function."""
26
+ positive = lambda source: self.assertTrue(detect(source))
27
+ negative = lambda source: self.assertFalse(detect(source))
28
+
29
+ negative('')
30
+ negative('abcd')
31
+ negative('var _0xaaaa')
32
+ positive('var _0xaaaa = ["a", "b"]')
33
+ positive('var _0xaaaa=["a", "b"]')
34
+ positive('var _0x1234=["a","b"]')
35
+
36
+ def test_unpack(self):
37
+ """Test unpack() function."""
38
+ decodeto = lambda ob, original: self.assertEqual(unpack(ob), original)
39
+
40
+ decodeto('var _0x8df3=[];var a=10;', 'var a=10;')
41
+ decodeto('var _0xb2a7=["\x74\x27\x65\x73\x74"];var i;for(i=0;i<10;++i)'
42
+ '{alert(_0xb2a7[0]);} ;', 'var i;for(i=0;i<10;++i){alert'
43
+ '("t\'est");} ;')
44
+
45
+ if __name__ == '__main__':
46
+ unittest.main()
@@ -0,0 +1,40 @@
1
+ #
2
+ # written by Stefano Sanfilippo <a.little.coder@gmail.com>
3
+ #
4
+
5
+ """Tests for MyObfuscate unpacker."""
6
+
7
+ import unittest
8
+ import os
9
+ from jsbeautifier.unpackers.myobfuscate import detect, unpack
10
+ from jsbeautifier.unpackers.tests import __path__ as path
11
+
12
+ INPUT = os.path.join(path[0], 'test-myobfuscate-input.js')
13
+ OUTPUT = os.path.join(path[0], 'test-myobfuscate-output.js')
14
+
15
+ # pylint: disable=R0904
16
+ class TestMyObfuscate(unittest.TestCase):
17
+ # pylint: disable=C0103
18
+ """MyObfuscate obfuscator testcase."""
19
+ @classmethod
20
+ def setUpClass(cls):
21
+ """Load source files (encoded and decoded version) for tests."""
22
+ with open(INPUT, 'r') as data:
23
+ cls.input = data.read()
24
+ with open(OUTPUT, 'r') as data:
25
+ cls.output = data.read()
26
+
27
+ def test_detect(self):
28
+ """Test detect() function."""
29
+ detected = lambda source: self.assertTrue(detect(source))
30
+
31
+ detected(self.input)
32
+
33
+ def test_unpack(self):
34
+ """Test unpack() function."""
35
+ check = lambda inp, out: self.assertEqual(unpack(inp), out)
36
+
37
+ check(self.input, self.output)
38
+
39
+ if __name__ == '__main__':
40
+ unittest.main()
@@ -0,0 +1,34 @@
1
+ #
2
+ # written by Stefano Sanfilippo <a.little.coder@gmail.com>
3
+ #
4
+
5
+ """Tests for P.A.C.K.E.R. unpacker."""
6
+
7
+ import unittest
8
+ from jsbeautifier.unpackers.packer import detect, unpack
9
+
10
+ # pylint: disable=R0904
11
+ class TestPacker(unittest.TestCase):
12
+ """P.A.C.K.E.R. testcase."""
13
+ def test_detect(self):
14
+ """Test detect() function."""
15
+ positive = lambda source: self.assertTrue(detect(source))
16
+ negative = lambda source: self.assertFalse(detect(source))
17
+
18
+ negative('')
19
+ negative('var a = b')
20
+ positive('eval(function(p,a,c,k,e,r')
21
+ positive('eval ( function(p, a, c, k, e, r')
22
+
23
+ def test_unpack(self):
24
+ """Test unpack() function."""
25
+ check = lambda inp, out: self.assertEqual(unpack(inp), out)
26
+
27
+ check("eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)"
28
+ "){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e="
29
+ "function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace("
30
+ "new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1',"
31
+ "62,3,'var||a'.split('|'),0,{}))", 'var a=1')
32
+
33
+ if __name__ == '__main__':
34
+ unittest.main()
@@ -0,0 +1,36 @@
1
+ #
2
+ # written by Stefano Sanfilippo <a.little.coder@gmail.com>
3
+ #
4
+
5
+ """Tests for urlencoded unpacker."""
6
+
7
+ import unittest
8
+
9
+ from jsbeautifier.unpackers.urlencode import detect, unpack
10
+
11
+ # pylint: disable=R0904
12
+ class TestUrlencode(unittest.TestCase):
13
+ """urlencode test case."""
14
+ def test_detect(self):
15
+ """Test detect() function."""
16
+ encoded = lambda source: self.assertTrue(detect(source))
17
+ unencoded = lambda source: self.assertFalse(detect(source))
18
+
19
+ unencoded('')
20
+ unencoded('var a = b')
21
+ encoded('var%20a+=+b')
22
+ encoded('var%20a=b')
23
+ encoded('var%20%21%22')
24
+
25
+ def test_unpack(self):
26
+ """Test unpack function."""
27
+ equals = lambda source, result: self.assertEqual(unpack(source), result)
28
+
29
+ equals('', '')
30
+ equals('abcd', 'abcd')
31
+ equals('var a = b', 'var a = b')
32
+ equals('var%20a=b', 'var a=b')
33
+ equals('var%20a+=+b', 'var a = b')
34
+
35
+ if __name__ == '__main__':
36
+ unittest.main()
@@ -0,0 +1,34 @@
1
+ #
2
+ # Trivial bookmarklet/escaped script detector for the javascript beautifier
3
+ # written by Einar Lielmanis <einar@jsbeautifier.org>
4
+ # rewritten in Python by Stefano Sanfilippo <a.little.coder@gmail.com>
5
+ #
6
+ # Will always return valid javascript: if `detect()` is false, `code` is
7
+ # returned, unmodified.
8
+ #
9
+ # usage:
10
+ #
11
+ # some_string = urlencode.unpack(some_string)
12
+ #
13
+
14
+ """Bookmarklet/escaped script unpacker."""
15
+
16
+ # Python 2 retrocompatibility
17
+ # pylint: disable=F0401
18
+ # pylint: disable=E0611
19
+ try:
20
+ from urllib import unquote_plus
21
+ except ImportError:
22
+ from urllib.parse import unquote_plus
23
+
24
+ PRIORITY = 0
25
+
26
+ def detect(code):
27
+ """Detects if a scriptlet is urlencoded."""
28
+ # the fact that script doesn't contain any space, but has %20 instead
29
+ # should be sufficient check for now.
30
+ return ' ' not in code and ('%20' in code or code.count('%') > 3)
31
+
32
+ def unpack(code):
33
+ """URL decode `code` source string."""
34
+ return unquote_plus(code) if detect(code) else code
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env python
2
+
3
+ from distutils.core import setup
4
+
5
+ setup(name='jsbeautifier',
6
+ version='1.0',
7
+ description='JavaScript unobfuscator and beautifier.',
8
+ long_description=('Beautify, unpack or deobfuscate JavaScript. '
9
+ 'Handles popular online obfuscators.'),
10
+ author='Einar Lielmanis, Stefano Sanfilippo et al.',
11
+ author_email='einar@jsbeautifier.org',
12
+ url='http://jsbeautifier.org',
13
+ scripts=['js-beautify'],
14
+ packages=['jsbeautifier', 'jsbeautifier.tests',
15
+ 'jsbeautifier.unpackers', 'jsbeautifier.unpackers.tests'],
16
+ license='MIT',
17
+ )
@@ -0,0 +1,489 @@
1
+ /*global js_beautify */
2
+
3
+
4
+ opts = {
5
+ indent_size: 4,
6
+ indent_char: ' ',
7
+ preserve_newlines: true,
8
+ jslint_happy: false,
9
+ keep_array_indentation: false,
10
+ brace_style: 'collapse',
11
+ space_before_conditional: true
12
+ }
13
+
14
+ function test_beautifier(input)
15
+ {
16
+ return js_beautify(input, opts);
17
+ }
18
+
19
+ var sanitytest;
20
+
21
+ // test the input on beautifier with the current flag settings
22
+ // does not check the indentation / surroundings as bt() does
23
+ function test_fragment(input, expected)
24
+ {
25
+ expected = expected || input;
26
+ sanitytest.expect(input, expected);
27
+ }
28
+
29
+
30
+
31
+ // test the input on beautifier with the current flag settings
32
+ // test both the input as well as { input } wrapping
33
+ function bt(input, expectation)
34
+ {
35
+ var wrapped_input, wrapped_expectation;
36
+
37
+ expectation = expectation || input;
38
+ test_fragment(input, expectation);
39
+
40
+ // test also the returned indentation
41
+ // e.g if input = "asdf();"
42
+ // then test that this remains properly formatted as well:
43
+ // {
44
+ // asdf();
45
+ // indent;
46
+ // }
47
+
48
+ if (opts.indent_size === 4 && input) {
49
+ wrapped_input = '{\n' + input + '\nfoo=bar;}';
50
+ wrapped_expectation = '{\n' + expectation.replace(/^(.+)$/mg, ' $1') + '\n foo = bar;\n}';
51
+ test_fragment(wrapped_input, wrapped_expectation);
52
+ }
53
+
54
+ }
55
+
56
+ // test the input on beautifier with the current flag settings,
57
+ // but dont't
58
+ function bt_braces(input, expectation)
59
+ {
60
+ var braces_ex = opts.brace_style;
61
+ opts.brace_style = 'expand';
62
+ bt(input, expectation);
63
+ opts.brace_style = braces_ex;
64
+ }
65
+
66
+ function run_beautifier_tests(test_obj)
67
+ {
68
+ sanitytest = test_obj || new SanityTest();
69
+ sanitytest.test_function(test_beautifier, 'js_beautify');
70
+
71
+ opts.indent_size = 4;
72
+ opts.indent_char = ' ';
73
+ opts.preserve_newlines = true;
74
+ opts.jslint_happy = false;
75
+ opts.keep_array_indentation = false;
76
+ opts.brace_style = "collapse";
77
+
78
+
79
+ bt('');
80
+ bt('return .5');
81
+ test_fragment(' return .5');
82
+ bt('a = 1', 'a = 1');
83
+ bt('a=1', 'a = 1');
84
+ bt("a();\n\nb();", "a();\n\nb();");
85
+ bt('var a = 1 var b = 2', "var a = 1\nvar b = 2");
86
+ bt('var a=1, b=c[d], e=6;', 'var a = 1,\n b = c[d],\n e = 6;');
87
+ bt('a = " 12345 "');
88
+ bt("a = ' 12345 '");
89
+ bt('if (a == 1) b = 2;', "if (a == 1) b = 2;");
90
+ bt('if(1){2}else{3}', "if (1) {\n 2\n} else {\n 3\n}");
91
+ bt('if (foo) bar();\nelse\ncar();', 'if (foo) bar();\nelse car();');
92
+ bt('if(1||2);', 'if (1 || 2);');
93
+ bt('(a==1)||(b==2)', '(a == 1) || (b == 2)');
94
+ bt('var a = 1 if (2) 3;', "var a = 1\nif (2) 3;");
95
+ bt('a = a + 1');
96
+ bt('a = a == 1');
97
+ bt('/12345[^678]*9+/.match(a)');
98
+ bt('a /= 5');
99
+ bt('a = 0.5 * 3');
100
+ bt('a *= 10.55');
101
+ bt('a < .5');
102
+ bt('a <= .5');
103
+ bt('a<.5', 'a < .5');
104
+ bt('a<=.5', 'a <= .5');
105
+ bt('a = 0xff;');
106
+ bt('a=0xff+4', 'a = 0xff + 4');
107
+ bt('a = [1, 2, 3, 4]');
108
+ bt('F*(g/=f)*g+b', 'F * (g /= f) * g + b');
109
+ bt('a.b({c:d})', "a.b({\n c: d\n})");
110
+ bt('a.b\n(\n{\nc:\nd\n}\n)', "a.b({\n c: d\n})");
111
+ bt('a=!b', 'a = !b');
112
+ bt('a?b:c', 'a ? b : c');
113
+ bt('a?1:2', 'a ? 1 : 2');
114
+ bt('a?(b):c', 'a ? (b) : c');
115
+ bt('x={a:1,b:w=="foo"?x:y,c:z}', 'x = {\n a: 1,\n b: w == "foo" ? x : y,\n c: z\n}');
116
+ bt('x=a?b?c?d:e:f:g;', 'x = a ? b ? c ? d : e : f : g;');
117
+ bt('x=a?b?c?d:{e1:1,e2:2}:f:g;', 'x = a ? b ? c ? d : {\n e1: 1,\n e2: 2\n} : f : g;');
118
+ bt('function void(void) {}');
119
+ bt('if(!a)foo();', 'if (!a) foo();');
120
+ bt('a=~a', 'a = ~a');
121
+ bt('a;/*comment*/b;', "a; /*comment*/\nb;");
122
+ bt('a;/* comment */b;', "a; /* comment */\nb;");
123
+ test_fragment('a;/*\ncomment\n*/b;', "a;\n/*\ncomment\n*/\nb;"); // simple comments don't get touched at all
124
+ bt('a;/**\n* javadoc\n*/b;', "a;\n/**\n * javadoc\n */\nb;");
125
+ test_fragment('a;/**\n\nno javadoc\n*/b;', "a;\n/**\n\nno javadoc\n*/\nb;");
126
+ bt('a;/*\n* javadoc\n*/b;', "a;\n/*\n * javadoc\n */\nb;"); // comment blocks detected and reindented even w/o javadoc starter
127
+ bt('if(a)break;', "if (a) break;");
128
+ bt('if(a){break}', "if (a) {\n break\n}");
129
+ bt('if((a))foo();', 'if ((a)) foo();');
130
+ bt('for(var i=0;;)', 'for (var i = 0;;)');
131
+ bt('a++;', 'a++;');
132
+ bt('for(;;i++)', 'for (;; i++)');
133
+ bt('for(;;++i)', 'for (;; ++i)');
134
+ bt('return(1)', 'return (1)');
135
+ bt('try{a();}catch(b){c();}finally{d();}', "try {\n a();\n} catch (b) {\n c();\n} finally {\n d();\n}");
136
+ bt('(xx)()'); // magic function call
137
+ bt('a[1]()'); // another magic function call
138
+ bt('if(a){b();}else if(c) foo();', "if (a) {\n b();\n} else if (c) foo();");
139
+ bt('switch(x) {case 0: case 1: a(); break; default: break}', "switch (x) {\ncase 0:\ncase 1:\n a();\n break;\ndefault:\n break\n}");
140
+ bt('switch(x){case -1:break;case !y:break;}', 'switch (x) {\ncase -1:\n break;\ncase !y:\n break;\n}');
141
+ bt('a !== b');
142
+ bt('if (a) b(); else c();', "if (a) b();\nelse c();");
143
+ bt("// comment\n(function something() {})"); // typical greasemonkey start
144
+ bt("{\n\n x();\n\n}"); // was: duplicating newlines
145
+ bt('if (a in b) foo();');
146
+ // bt('var a, b');
147
+ bt('{a:1, b:2}', "{\n a: 1,\n b: 2\n}");
148
+ bt('a={1:[-1],2:[+1]}', 'a = {\n 1: [-1],\n 2: [+1]\n}');
149
+ bt('var l = {\'a\':\'1\', \'b\':\'2\'}', "var l = {\n 'a': '1',\n 'b': '2'\n}");
150
+ bt('if (template.user[n] in bk) foo();');
151
+ bt('{{}/z/}', "{\n {}\n /z/\n}");
152
+ bt('return 45', "return 45");
153
+ bt('If[1]', "If[1]");
154
+ bt('Then[1]', "Then[1]");
155
+ bt('a = 1e10', "a = 1e10");
156
+ bt('a = 1.3e10', "a = 1.3e10");
157
+ bt('a = 1.3e-10', "a = 1.3e-10");
158
+ bt('a = -1.3e-10', "a = -1.3e-10");
159
+ bt('a = 1e-10', "a = 1e-10");
160
+ bt('a = e - 10', "a = e - 10");
161
+ bt('a = 11-10', "a = 11 - 10");
162
+ bt("a = 1;// comment\n", "a = 1; // comment");
163
+ bt("a = 1; // comment\n", "a = 1; // comment");
164
+ bt("a = 1;\n // comment\n", "a = 1;\n// comment");
165
+
166
+ bt('o = [{a:b},{c:d}]', 'o = [{\n a: b\n}, {\n c: d\n}]');
167
+
168
+ bt("if (a) {\n do();\n}"); // was: extra space appended
169
+ bt("if\n(a)\nb();", "if (a) b();"); // test for proper newline removal
170
+
171
+ bt("if (a) {\n// comment\n}else{\n// comment\n}", "if (a) {\n // comment\n} else {\n // comment\n}"); // if/else statement with empty body
172
+ bt("if (a) {\n// comment\n// comment\n}", "if (a) {\n // comment\n // comment\n}"); // multiple comments indentation
173
+ bt("if (a) b() else c();", "if (a) b()\nelse c();");
174
+ bt("if (a) b() else if c() d();", "if (a) b()\nelse if c() d();");
175
+
176
+ bt("{}");
177
+ bt("{\n\n}");
178
+ bt("do { a(); } while ( 1 );", "do {\n a();\n} while (1);");
179
+ bt("do {} while (1);");
180
+ bt("do {\n} while (1);", "do {} while (1);");
181
+ bt("do {\n\n} while (1);");
182
+ bt("var a = x(a, b, c)");
183
+ bt("delete x if (a) b();", "delete x\nif (a) b();");
184
+ bt("delete x[x] if (a) b();", "delete x[x]\nif (a) b();");
185
+ bt("for(var a=1,b=2)", "for (var a = 1, b = 2)");
186
+ bt("for(var a=1,b=2,c=3)", "for (var a = 1, b = 2, c = 3)");
187
+ bt("for(var a=1,b=2,c=3;d<3;d++)", "for (var a = 1, b = 2, c = 3; d < 3; d++)");
188
+ bt("function x(){(a||b).c()}", "function x() {\n (a || b).c()\n}");
189
+ bt("function x(){return - 1}", "function x() {\n return -1\n}");
190
+ bt("function x(){return ! a}", "function x() {\n return !a\n}");
191
+
192
+ // a common snippet in jQuery plugins
193
+ bt("settings = $.extend({},defaults,settings);", "settings = $.extend({}, defaults, settings);");
194
+
195
+ bt('{xxx;}()', '{\n xxx;\n}()');
196
+
197
+ bt("a = 'a'\nb = 'b'");
198
+ bt("a = /reg/exp");
199
+ bt("a = /reg/");
200
+ bt('/abc/.test()');
201
+ bt('/abc/i.test()');
202
+ bt("{/abc/i.test()}", "{\n /abc/i.test()\n}");
203
+ bt('var x=(a)/a;', 'var x = (a) / a;');
204
+
205
+ bt('x != -1', 'x != -1');
206
+
207
+ bt('for (; s-->0;)', 'for (; s-- > 0;)');
208
+ bt('for (; s++>0;)', 'for (; s++ > 0;)');
209
+ bt('a = s++>s--;', 'a = s++ > s--;');
210
+ bt('a = s++>--s;', 'a = s++ > --s;');
211
+
212
+ bt('{x=#1=[]}', '{\n x = #1=[]\n}');
213
+ bt('{a:#1={}}', '{\n a: #1={}\n}');
214
+ bt('{a:#1#}', '{\n a: #1#\n}');
215
+
216
+ test_fragment('{a:1},{a:2}', '{\n a: 1\n}, {\n a: 2\n}');
217
+ test_fragment('var ary=[{a:1}, {a:2}];', 'var ary = [{\n a: 1\n}, {\n a: 2\n}];');
218
+
219
+ test_fragment('{a:#1', '{\n a: #1'); // incomplete
220
+ test_fragment('{a:#', '{\n a: #'); // incomplete
221
+
222
+ test_fragment('}}}', '}\n}\n}'); // incomplete
223
+
224
+ test_fragment('<!--\nvoid();\n// -->', '<!--\nvoid();\n// -->');
225
+
226
+ test_fragment('a=/regexp', 'a = /regexp'); // incomplete regexp
227
+
228
+ bt('{a:#1=[],b:#1#,c:#999999#}', '{\n a: #1=[],\n b: #1#,\n c: #999999#\n}');
229
+
230
+ bt("a = 1e+2");
231
+ bt("a = 1e-2");
232
+ bt("do{x()}while(a>1)", "do {\n x()\n} while (a > 1)");
233
+
234
+ bt("x(); /reg/exp.match(something)", "x();\n/reg/exp.match(something)");
235
+
236
+ test_fragment("something();(", "something();\n(");
237
+ test_fragment("#!she/bangs, she bangs\nf=1", "#!she/bangs, she bangs\n\nf = 1");
238
+ test_fragment("#!she/bangs, she bangs\n\nf=1", "#!she/bangs, she bangs\n\nf = 1");
239
+ test_fragment("#!she/bangs, she bangs\n\n/* comment */", "#!she/bangs, she bangs\n\n/* comment */");
240
+ test_fragment("#!she/bangs, she bangs\n\n\n/* comment */", "#!she/bangs, she bangs\n\n\n/* comment */");
241
+ test_fragment("#", "#");
242
+ test_fragment("#!", "#!");
243
+
244
+ bt("function namespace::something()");
245
+
246
+ test_fragment("<!--\nsomething();\n-->", "<!--\nsomething();\n-->");
247
+ test_fragment("<!--\nif(i<0){bla();}\n-->", "<!--\nif (i < 0) {\n bla();\n}\n-->");
248
+
249
+ bt('{foo();--bar;}', '{\n foo();\n --bar;\n}');
250
+ bt('{foo();++bar;}', '{\n foo();\n ++bar;\n}');
251
+ bt('{--bar;}', '{\n --bar;\n}');
252
+ bt('{++bar;}', '{\n ++bar;\n}');
253
+
254
+ // regexps
255
+ bt('a(/abc\\/\\/def/);b()', "a(/abc\\/\\/def/);\nb()");
256
+ bt('a(/a[b\\[\\]c]d/);b()', "a(/a[b\\[\\]c]d/);\nb()");
257
+ test_fragment('a(/a[b\\[', "a(/a[b\\["); // incomplete char class
258
+ // allow unescaped / in char classes
259
+ bt('a(/[a/b]/);b()', "a(/[a/b]/);\nb()");
260
+
261
+ bt('a=[[1,2],[4,5],[7,8]]', "a = [\n [1, 2],\n [4, 5],\n [7, 8]\n]");
262
+ bt('a=[a[1],b[4],c[d[7]]]', "a = [a[1], b[4], c[d[7]]]");
263
+ bt('[1,2,[3,4,[5,6],7],8]', "[1, 2, [3, 4, [5, 6], 7], 8]");
264
+
265
+ bt('[[["1","2"],["3","4"]],[["5","6","7"],["8","9","0"]],[["1","2","3"],["4","5","6","7"],["8","9","0"]]]',
266
+ '[\n [\n ["1", "2"],\n ["3", "4"]\n ],\n [\n ["5", "6", "7"],\n ["8", "9", "0"]\n ],\n [\n ["1", "2", "3"],\n ["4", "5", "6", "7"],\n ["8", "9", "0"]\n ]\n]');
267
+
268
+ bt('{[x()[0]];indent;}', '{\n [x()[0]];\n indent;\n}');
269
+
270
+ bt('return ++i', 'return ++i');
271
+ bt('return !!x', 'return !!x');
272
+ bt('return !x', 'return !x');
273
+ bt('return [1,2]', 'return [1, 2]');
274
+ bt('return;', 'return;');
275
+ bt('return\nfunc', 'return\nfunc');
276
+ bt('catch(e)', 'catch (e)');
277
+
278
+ bt('var a=1,b={foo:2,bar:3},c=4;', 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n c = 4;');
279
+
280
+ // inline comment
281
+ bt('function x(/*int*/ start, /*string*/ foo)', 'function x( /*int*/ start, /*string*/ foo)');
282
+
283
+ // javadoc comment
284
+ bt('/**\n* foo\n*/', '/**\n * foo\n */');
285
+ bt('{\n/**\n* foo\n*/\n}', '{\n /**\n * foo\n */\n}');
286
+
287
+ bt('var a,b,c=1,d,e,f=2;', 'var a, b, c = 1,\n d, e, f = 2;');
288
+ bt('var a,b,c=[],d,e,f=2;', 'var a, b, c = [],\n d, e, f = 2;');
289
+
290
+ bt('do/regexp/;\nwhile(1);', 'do /regexp/;\nwhile (1);'); // hmmm
291
+
292
+ bt('var a = a,\na;\nb = {\nb\n}', 'var a = a,\n a;\nb = {\n b\n}');
293
+
294
+ bt('var a = a,\n /* c */\n b;');
295
+ bt('var a = a,\n // c\n b;');
296
+
297
+ bt('foo.("bar");'); // weird element referencing
298
+
299
+
300
+ bt('if (a) a()\nelse b()\nnewline()');
301
+ bt('if (a) a()\nnewline()');
302
+ bt('a=typeof(x)', 'a = typeof(x)');
303
+ bt('var a = function() {\n return null;\n },\n b = false;');
304
+
305
+ bt('var a = function() {\n func1()\n }');
306
+ bt('var a = function() {\n func1()\n }\nvar b = function() {\n func2()\n }');
307
+
308
+
309
+
310
+ opts.jslint_happy = true;
311
+
312
+ bt('a=typeof(x)', 'a = typeof (x)');
313
+ bt('x();\n\nfunction(){}', 'x();\n\nfunction () {}');
314
+ bt('function () {\n var a, b, c, d, e = [],\n f;\n}');
315
+ test_fragment("// comment 1\n(function()", "// comment 1\n(function ()"); // typical greasemonkey start
316
+ bt("var a1, b1, c1, d1 = 0, c = function() {}, d = '';", "var a1, b1, c1, d1 = 0,\n c = function () {},\n d = '';");
317
+ bt('var o1=$.extend(a);function(){alert(x);}', 'var o1 = $.extend(a);\n\nfunction () {\n alert(x);\n}');
318
+
319
+ opts.jslint_happy = false;
320
+
321
+ test_fragment("// comment 2\n(function()", "// comment 2\n(function()"); // typical greasemonkey start
322
+ bt("var a2, b2, c2, d2 = 0, c = function() {}, d = '';", "var a2, b2, c2, d2 = 0,\n c = function() {},\n d = '';");
323
+ bt('var o2=$.extend(a);function(){alert(x);}', 'var o2 = $.extend(a);\n\nfunction() {\n alert(x);\n}');
324
+
325
+ bt('{"x":[{"a":1,"b":3},7,8,8,8,8,{"b":99},{"a":11}]}', '{\n "x": [{\n "a": 1,\n "b": 3\n },\n 7, 8, 8, 8, 8,\n {\n "b": 99\n }, {\n "a": 11\n }]\n}');
326
+
327
+ bt('{"1":{"1a":"1b"},"2"}', '{\n "1": {\n "1a": "1b"\n },\n "2"\n}');
328
+ bt('{a:{a:b},c}', '{\n a: {\n a: b\n },\n c\n}');
329
+
330
+ bt('{[y[a]];keep_indent;}', '{\n [y[a]];\n keep_indent;\n}');
331
+
332
+ bt('if (x) {y} else { if (x) {y}}', 'if (x) {\n y\n} else {\n if (x) {\n y\n }\n}');
333
+
334
+ bt('if (foo) one()\ntwo()\nthree()');
335
+ bt('if (1 + foo() && bar(baz()) / 2) one()\ntwo()\nthree()');
336
+ bt('if (1 + foo() && bar(baz()) / 2) one();\ntwo();\nthree();');
337
+
338
+ opts.indent_size = 1;
339
+ opts.indent_char = ' ';
340
+ bt('{ one_char() }', "{\n one_char()\n}");
341
+
342
+ bt('var a,b=1,c=2', 'var a, b = 1,\n c = 2');
343
+
344
+ opts.indent_size = 4;
345
+ opts.indent_char = ' ';
346
+ bt('{ one_char() }', "{\n one_char()\n}");
347
+
348
+ opts.indent_size = 1;
349
+ opts.indent_char = "\t";
350
+ bt('{ one_char() }', "{\n\tone_char()\n}");
351
+ bt('x = a ? b : c; x;', 'x = a ? b : c;\nx;');
352
+
353
+ opts.indent_size = 4;
354
+ opts.indent_char = ' ';
355
+
356
+ opts.preserve_newlines = false;
357
+ bt('var\na=dont_preserve_newlines;', 'var a = dont_preserve_newlines;');
358
+
359
+ // make sure the blank line between function definitions stays
360
+ // even when preserve_newlines = false
361
+ bt('function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}');
362
+ bt('function foo() {\n return 1;\n}\nfunction foo() {\n return 1;\n}',
363
+ 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
364
+ );
365
+ bt('function foo() {\n return 1;\n}\n\n\nfunction foo() {\n return 1;\n}',
366
+ 'function foo() {\n return 1;\n}\n\nfunction foo() {\n return 1;\n}'
367
+ );
368
+
369
+
370
+ opts.preserve_newlines = true;
371
+ bt('var\na=do_preserve_newlines;', 'var\na = do_preserve_newlines;');
372
+ bt('// a\n// b\n\n// c\n// d');
373
+ bt('if (foo) // comment\n{\n bar();\n}');
374
+
375
+
376
+ opts.keep_array_indentation = true;
377
+
378
+ test_fragment('var a = [\n// comment:\n{\n foo:bar\n}\n];', 'var a = [\n // comment:\n{\n foo: bar\n}\n];');
379
+
380
+ bt('var x = [{}\n]', 'var x = [{}\n]');
381
+ bt('var x = [{foo:bar}\n]', 'var x = [{\n foo: bar\n}\n]');
382
+ bt("a = ['something',\n'completely',\n'different'];\nif (x);", "a = ['something',\n 'completely',\n 'different'];\nif (x);");
383
+ bt("a = ['a','b','c']", "a = ['a', 'b', 'c']");
384
+ bt("a = ['a', 'b','c']", "a = ['a', 'b', 'c']");
385
+
386
+ bt("x = [{'a':0}]", "x = [{\n 'a': 0\n}]");
387
+
388
+ bt('{a([[a1]], {b;});}', '{\n a([[a1]], {\n b;\n });\n}');
389
+
390
+ bt('a = //comment\n/regex/;');
391
+
392
+ test_fragment('/*\n * X\n */');
393
+ test_fragment('/*\r\n * X\r\n */', '/*\n * X\n */');
394
+
395
+ bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n} else {\n c;\n}');
396
+
397
+
398
+ opts.brace_style = 'expand';
399
+
400
+ bt('var a=1,b={foo:2,bar:3},c=4;', 'var a = 1,\n b = {\n foo: 2,\n bar: 3\n },\n c = 4;');
401
+ bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}');
402
+ test_fragment('if (foo) {', 'if (foo)\n{');
403
+ test_fragment('foo {', 'foo\n{');
404
+ test_fragment('return {', 'return {'); // return needs the brace. maybe something else as well: feel free to report.
405
+ // test_fragment('return\n{', 'return\n{'); // can't support this?, but that's an improbable and extreme case anyway.
406
+ test_fragment('return;\n{', 'return;\n{');
407
+ bt("throw {}");
408
+ bt("throw {\n foo;\n}");
409
+
410
+ bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}');
411
+ bt('var foo = {}');
412
+ bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a)\n{\n b;\n}\nelse\n{\n c;\n}');
413
+ test_fragment('if (foo) {', 'if (foo)\n{');
414
+ test_fragment('foo {', 'foo\n{');
415
+ test_fragment('return {', 'return {'); // return needs the brace. maybe something else as well: feel free to report.
416
+ // test_fragment('return\n{', 'return\n{'); // can't support this?, but that's an improbable and extreme case anyway.
417
+ test_fragment('return;\n{', 'return;\n{');
418
+
419
+
420
+ opts.brace_style = 'collapse';
421
+
422
+ bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n} else {\n c;\n}');
423
+ test_fragment('if (foo) {', 'if (foo) {');
424
+ test_fragment('foo {', 'foo {');
425
+ test_fragment('return {', 'return {'); // return needs the brace. maybe something else as well: feel free to report.
426
+ // test_fragment('return\n{', 'return\n{'); // can't support this?, but that's an improbable and extreme case anyway.
427
+ test_fragment('return;\n{', 'return; {');
428
+
429
+ bt('if (foo) bar();\nelse break');
430
+ bt('function x() {\n foo();\n}zzz', 'function x() {\n foo();\n}\nzzz');
431
+ bt('a: do {} while (); xxx', 'a: do {} while ();\nxxx');
432
+
433
+ bt('var a = new function();');
434
+ test_fragment('new function');
435
+ bt('var a =\nfoo', 'var a = foo');
436
+
437
+ opts.brace_style = "end-expand";
438
+
439
+ bt('if(1){2}else{3}', "if (1) {\n 2\n}\nelse {\n 3\n}");
440
+ bt('try{a();}catch(b){c();}finally{d();}', "try {\n a();\n}\ncatch (b) {\n c();\n}\nfinally {\n d();\n}");
441
+ bt('if(a){b();}else if(c) foo();', "if (a) {\n b();\n}\nelse if (c) foo();");
442
+ bt("if (a) {\n// comment\n}else{\n// comment\n}", "if (a) {\n // comment\n}\nelse {\n // comment\n}"); // if/else statement with empty body
443
+ bt('if (x) {y} else { if (x) {y}}', 'if (x) {\n y\n}\nelse {\n if (x) {\n y\n }\n}');
444
+ bt('if (a)\n{\nb;\n}\nelse\n{\nc;\n}', 'if (a) {\n b;\n}\nelse {\n c;\n}');
445
+
446
+ test_fragment(' /*\n* xx\n*/\n// xx\nif (foo) {\n bar();\n}', ' /*\n * xx\n */\n // xx\n if (foo) {\n bar();\n }')
447
+
448
+ bt('if (foo) {}\nelse /regex/.test();');
449
+ // bt('if (foo) /regex/.test();'); // doesn't work, detects as a division. should it work?
450
+
451
+ bt('a = <?= external() ?> ;'); // not the most perfect thing in the world, but you're the weirdo beaufifying php mix-ins with javascript beautifier
452
+ bt('a = <%= external() %> ;');
453
+
454
+ bt('// func-comment\n\nfunction foo() {}\n\n// end-func-comment', '// func-comment\nfunction foo() {}\n\n// end-func-comment');
455
+
456
+ test_fragment('roo = {\n /*\n ****\n FOO\n ****\n */\n BAR: 0\n};');
457
+
458
+ bt('"foo""bar""baz"', '"foo"\n"bar"\n"baz"');
459
+ bt("'foo''bar''baz'", "'foo'\n'bar'\n'baz'");
460
+
461
+
462
+ test_fragment("if (..) {\n // ....\n}\n(function");
463
+
464
+ bt("{\n get foo() {}\n}");
465
+ bt("{\n var a = get\n foo();\n}");
466
+ bt("{\n set foo() {}\n}");
467
+ bt("{\n var a = set\n foo();\n}");
468
+ bt("var x = {\n get function()\n}");
469
+ bt("var x = {\n set function()\n}");
470
+ bt("var x = set\n\nfunction() {}");
471
+
472
+ bt('<!-- foo\nbar();\n-->');
473
+ bt('<!-- dont crash');
474
+ bt('for () /abc/.test()');
475
+ bt('if (k) /aaa/m.test(v) && l();');
476
+ bt('switch (true) {\ncase /swf/i.test(foo):\n bar();\n}');
477
+ bt('createdAt = {\n type: Date,\n default: Date.now\n}');
478
+ bt('switch (createdAt) {\ncase a:\n Date,\ndefault:\n Date.now\n}');
479
+ opts.space_before_conditional = false;
480
+ bt('if(a) b()');
481
+
482
+
483
+ bt('3.*7;', '3. * 7;')
484
+ bt('import foo.*;', 'import foo.*;') // actionscript's import
485
+ test_fragment('function f(a: a, b: b)') // actionscript
486
+
487
+ return sanitytest;
488
+ }
489
+