diff --git a/bin/uglifyjs b/bin/uglifyjs index ce2e9411e00..0eeb0583946 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -69,6 +69,7 @@ You need to pass an argument to this option to specify the name that your module .describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.") .describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.") .describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.") + .describe("keep-fparens", "Do not drop parentheses around function definitions. Useful for marking a function to be compiled eagerly by browser.") .describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)") .describe("reserved-file", "File containing reserved names") .describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props") @@ -132,6 +133,7 @@ You need to pass an argument to this option to specify the name that your module .boolean("noerr") .boolean("bare-returns") .boolean("keep-fnames") + .boolean("keep-fparens") .boolean("reserve-domprops") .boolean("wrap-iife") @@ -256,6 +258,10 @@ if (ARGS.wrap_iife) { OUTPUT_OPTIONS.wrap_iife = true; } +if (ARGS.keep_fparens) { + OUTPUT_OPTIONS.keep_fparens = true; +} + if (BEAUTIFY) UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY); diff --git a/lib/output.js b/lib/output.js index 63a78c6075a..740ef843047 100644 --- a/lib/output.js +++ b/lib/output.js @@ -69,6 +69,7 @@ function OutputStream(options) { quote_style : 0, keep_quoted_props: false, wrap_iife : false, + keep_fparens : false }, true); // Convert comment option to RegExp if neccessary and set up comments filter @@ -558,6 +559,14 @@ function OutputStream(options) { return true; } + // If option is on then keep wrapping parenthesises + if (output.option('keep_fparens')) { + if (this.start && this.start instanceof AST_Token && this.start.value === '(' && + this.end && this.end instanceof AST_Token && this.end.value === ')') { + return true; + } + } + if (output.option('wrap_iife')) { var p = output.parent(); return p instanceof AST_Call && p.expression === this; diff --git a/test/mocha/wrapping-parentheses.js b/test/mocha/wrapping-parentheses.js new file mode 100644 index 00000000000..316d270496d --- /dev/null +++ b/test/mocha/wrapping-parentheses.js @@ -0,0 +1,25 @@ +var assert = require("assert"); +var uglify = require("../../"); + +describe("Keep wrapping parentheses", function() { + it("Should keep wrapping parentheses if keep-fparens option is turned on", function() { + var originalCode = "define(\"module\",(function() {module.exports = 42;}));"; + var expectedCode = "define(\"module\",(function(){module.exports=42}));"; + var result = uglify.minify(originalCode, { + output: { + keep_fparens: true + }, + fromString: true + }); + assert.strictEqual(result.code, expectedCode); + }); + + it("Should strip wrapping parentheses if keep-fparens option is turned off or not set", function() { + var originalCode = "define(\"module\",(function() {module.exports = 42;}));"; + var expectedCode = "define(\"module\",function(){module.exports=42});"; + var result = uglify.minify(originalCode, { + fromString: true + }); + assert.strictEqual(result.code, expectedCode); + }); +});