diff --git a/README.md b/README.md index b6abc379..c2434547 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,8 @@ The available options are: --mangle-props Mangle 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 + their return value is not used [array] ``` Specify `--output` (`-o`) to declare the output file. Otherwise the output diff --git a/bin/uglifyjs b/bin/uglifyjs index f82d43cb..ca75f159 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -72,6 +72,7 @@ You need to pass an argument to this option to specify the name that your module .describe("mangle-props", "Mangle property names") .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") .alias("p", "prefix") .alias("o", "output") @@ -104,6 +105,7 @@ You need to pass an argument to this option to specify the name that your module .string("prefix") .string("name-cache") .array("reserved-file") + .array("pure-funcs") .boolean("expr") .boolean("source-map-include-sources") @@ -175,6 +177,10 @@ if (ARGS.d) { if (COMPRESS) COMPRESS.global_defs = getOptions("d"); } +if (ARGS.pure_funcs) { + if (COMPRESS) COMPRESS.pure_funcs = ARGS.pure_funcs; +} + if (ARGS.r) { if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/); } diff --git a/lib/output.js b/lib/output.js index 5aeed667..177a772c 100644 --- a/lib/output.js +++ b/lib/output.js @@ -88,13 +88,14 @@ function OutputStream(options) { function make_string(str, quote) { var dq = 0, sq = 0; - str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){ + str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){ switch (s) { case "\\": return "\\\\"; case "\b": return "\\b"; case "\f": return "\\f"; case "\n": return "\\n"; case "\r": return "\\r"; + case "\v": return "\\v"; case "\u2028": return "\\u2028"; case "\u2029": return "\\u2029"; case '"': ++dq; return '"'; @@ -125,8 +126,11 @@ function OutputStream(options) { function encode_string(str, quote) { var ret = make_string(str, quote); - if (options.inline_script) + if (options.inline_script) { ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); + ret = ret.replace(/\x3c!--/g, "\\x3c!--"); + ret = ret.replace(/--\x3e/g, "--\\x3e"); + } return ret; }; @@ -1114,16 +1118,24 @@ function OutputStream(options) { output.print(self.operator); }); DEFPRINT(AST_Binary, function(self, output){ + var op = self.operator; self.left.print(output); - output.space(); - output.print(self.operator); - if (self.operator == "<" + if (op[0] == ">" /* ">>" ">>>" ">" ">=" */ + && self.left instanceof AST_UnaryPostfix + && self.left.operator == "--") { + // space is mandatory to avoid outputting --> + output.print(" "); + } else { + // the space is optional depending on "beautify" + output.space(); + } + output.print(op); + if ((op == "<" || op == "<<") && self.right instanceof AST_UnaryPrefix && self.right.operator == "!" && self.right.expression instanceof AST_UnaryPrefix && self.right.expression.operator == "--") { // space is mandatory to avoid outputting comment in"; } + } + expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}'; +} diff --git a/test/run-tests.js b/test/run-tests.js index ea8d03e4..5abca810 100755 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -194,7 +194,7 @@ function parse_test(file) { function make_code(ast, beautify) { if (arguments.length == 1) beautify = true; - var stream = U.OutputStream({ beautify: beautify }); + var stream = U.OutputStream({ beautify: beautify, inline_script: true }); ast.print(stream); return stream.get(); }