js-beautify 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+