diff --git a/README.md b/README.md index a19f7ef4..9c63d727 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,11 @@ The available options are: --reserved-file File containing reserved names --reserve-domprops Make (most?) DOM properties reserved for --mangle-props - --mangle-props Mangle property names + --mangle-props Mangle property names (default `0`). Set to + `true` or `1` to mangle all property names. Set + to `1` to only mangle unquoted property names. + Use the `keep_quoted_props` beautifier option to + preserve the quotes around property names. --mangle-regex Only mangle property names matching the regex --name-cache File to hold mangled names mappings --pure-funcs List of functions that can be safely removed if diff --git a/bin/uglifyjs b/bin/uglifyjs index 45c92b50..ec791b07 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -69,7 +69,7 @@ You need to pass an argument to this option to specify the name that your module .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") - .describe("mangle-props", "Mangle property names") + .describe("mangle-props", "Mangle property names (0 - disabled, 1 - mangle all properties, 2 - mangle unquoted properies)") .describe("mangle-regex", "Only mangle property names matching the regex") .describe("name-cache", "File to hold mangled names mappings") .describe("pure-funcs", "List of functions that can be safely removed if their return value is not used") @@ -125,7 +125,6 @@ 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("mangle-props") .boolean("reserve-domprops") .wrap(80) @@ -388,6 +387,10 @@ async.eachLimit(files, 1, function (file, cb) { TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list); } + if (ARGS.mangle_props === true) { + ARGS.mangle_props = 1; + } + if (ARGS.mangle_props || ARGS.name_cache) (function(){ var reserved = RESERVED ? RESERVED.props : null; var cache = readNameCache("props"); @@ -401,10 +404,11 @@ async.eachLimit(files, 1, function (file, cb) { } TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, { - reserved : reserved, - cache : cache, - only_cache : !ARGS.mangle_props, - regex : regex + reserved : reserved, + cache : cache, + only_cache : !ARGS.mangle_props, + regex : regex, + ignore_quoted : ARGS.mangle_props == 2 }); writeNameCache("props", cache); })(); diff --git a/lib/propmangle.js b/lib/propmangle.js index 840bda91..c905e85e 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -65,7 +65,8 @@ function mangle_properties(ast, options) { reserved : null, cache : null, only_cache : false, - regex : null + regex : null, + ignore_quoted : false }); var reserved = options.reserved; @@ -81,6 +82,7 @@ function mangle_properties(ast, options) { } var regex = options.regex; + var ignore_quoted = options.ignore_quoted; var names_to_mangle = []; var unmangleable = []; @@ -88,11 +90,13 @@ function mangle_properties(ast, options) { // step 1: find candidates to mangle ast.walk(new TreeWalker(function(node){ if (node instanceof AST_ObjectKeyVal) { - add(node.key); + if (!(ignore_quoted && node.quote)) + add(node.key); } else if (node instanceof AST_ObjectProperty) { // setter or getter, since KeyVal is handled above - add(node.key.name); + if (!(ignore_quoted && node.key.quote)) + add(node.key.name); } else if (node instanceof AST_Dot) { if (this.parent() instanceof AST_Assign) { @@ -101,7 +105,8 @@ function mangle_properties(ast, options) { } else if (node instanceof AST_Sub) { if (this.parent() instanceof AST_Assign) { - addStrings(node.property); + if (!(ignore_quoted && node.property.quote)) + addStrings(node.property); } } })); diff --git a/test/compress/properties.js b/test/compress/properties.js index 39470738..c903d315 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -72,3 +72,35 @@ evaluate_length: { a = ("foo" + b).length; } } + +mangle_properties: { + mangle_props = { + ignore_quoted: false + }; + input: { + a["foo"] = "bar"; + a.color = "red"; + x = {"bar": 10}; + } + expect: { + a["a"] = "bar"; + a.b = "red"; + x = {c: 10}; + } +} + +mangle_unquoted_properties: { + mangle_props = { + ignore_quoted: true + }; + input: { + a["foo"] = "bar"; + a.color = "red"; + x = {"bar": 10}; + } + expect: { + a["foo"] = "bar"; + a.a = "red"; + x = {"bar": 10}; + } +}