Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a | ||
|
|
5c1ae3662d | ||
|
|
cfebeb2f63 | ||
|
|
fc78423f1d |
125
lib/compress.js
125
lib/compress.js
@@ -48,51 +48,51 @@ function Compressor(options, false_by_default) {
|
|||||||
return new Compressor(options, false_by_default);
|
return new Compressor(options, false_by_default);
|
||||||
TreeTransformer.call(this, this.before, this.after);
|
TreeTransformer.call(this, this.before, this.after);
|
||||||
this.options = defaults(options, {
|
this.options = defaults(options, {
|
||||||
arguments : !false_by_default,
|
arguments : !false_by_default,
|
||||||
booleans : !false_by_default,
|
booleans : !false_by_default,
|
||||||
collapse_vars : !false_by_default,
|
collapse_vars : !false_by_default,
|
||||||
comparisons : !false_by_default,
|
comparisons : !false_by_default,
|
||||||
conditionals : !false_by_default,
|
conditionals : !false_by_default,
|
||||||
dead_code : !false_by_default,
|
dead_code : !false_by_default,
|
||||||
directives : !false_by_default,
|
directives : !false_by_default,
|
||||||
drop_console : false,
|
drop_console : false,
|
||||||
drop_debugger : !false_by_default,
|
drop_debugger : !false_by_default,
|
||||||
evaluate : !false_by_default,
|
evaluate : !false_by_default,
|
||||||
expression : false,
|
expression : false,
|
||||||
global_defs : false,
|
global_defs : false,
|
||||||
hoist_funs : false,
|
hoist_funs : false,
|
||||||
hoist_props : !false_by_default,
|
hoist_props : !false_by_default,
|
||||||
hoist_vars : false,
|
hoist_vars : false,
|
||||||
ie8 : false,
|
ie8 : false,
|
||||||
if_return : !false_by_default,
|
if_return : !false_by_default,
|
||||||
inline : !false_by_default,
|
inline : !false_by_default,
|
||||||
join_vars : !false_by_default,
|
join_vars : !false_by_default,
|
||||||
keep_fargs : true,
|
keep_fargs : true,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
keep_infinity : false,
|
keep_infinity : false,
|
||||||
loops : !false_by_default,
|
loops : !false_by_default,
|
||||||
negate_iife : !false_by_default,
|
negate_iife : !false_by_default,
|
||||||
passes : 1,
|
passes : 1,
|
||||||
properties : !false_by_default,
|
properties : !false_by_default,
|
||||||
pure_getters : !false_by_default && "strict",
|
pure_getters : !false_by_default && "strict",
|
||||||
pure_funcs : null,
|
pure_funcs : null,
|
||||||
reduce_funcs : !false_by_default,
|
reduce_funcs : !false_by_default,
|
||||||
reduce_vars : !false_by_default,
|
reduce_vars : !false_by_default,
|
||||||
sequences : !false_by_default,
|
sequences : !false_by_default,
|
||||||
side_effects : !false_by_default,
|
side_effects : !false_by_default,
|
||||||
switches : !false_by_default,
|
switches : !false_by_default,
|
||||||
top_retain : null,
|
top_retain : null,
|
||||||
toplevel : !!(options && options["top_retain"]),
|
toplevel : !!(options && options["top_retain"]),
|
||||||
typeofs : !false_by_default,
|
typeofs : !false_by_default,
|
||||||
unsafe : false,
|
unsafe : false,
|
||||||
unsafe_comps : false,
|
unsafe_comps : false,
|
||||||
unsafe_Function: false,
|
unsafe_Function : false,
|
||||||
unsafe_math : false,
|
unsafe_math : false,
|
||||||
unsafe_proto : false,
|
unsafe_proto : false,
|
||||||
unsafe_regexp : false,
|
unsafe_regexp : false,
|
||||||
unsafe_undefined: false,
|
unsafe_undefined: false,
|
||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
warnings : false,
|
warnings : false,
|
||||||
}, true);
|
}, true);
|
||||||
var global_defs = this.options["global_defs"];
|
var global_defs = this.options["global_defs"];
|
||||||
if (typeof global_defs == "object") for (var key in global_defs) {
|
if (typeof global_defs == "object") for (var key in global_defs) {
|
||||||
@@ -450,8 +450,7 @@ merge(Compressor.prototype, {
|
|||||||
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
return value instanceof AST_Node && def.fixed.parent_scope === scope;
|
||||||
}
|
}
|
||||||
return all(def.orig, function(sym) {
|
return all(def.orig, function(sym) {
|
||||||
return !(sym instanceof AST_SymbolDefun
|
return !(sym instanceof AST_SymbolDefun || sym instanceof AST_SymbolLambda);
|
||||||
|| sym instanceof AST_SymbolLambda);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1699,6 +1698,19 @@ merge(Compressor.prototype, {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ab && !stat.alternative && stat.body instanceof AST_BlockStatement && next instanceof AST_Jump) {
|
||||||
|
var negated = stat.condition.negate(compressor);
|
||||||
|
if (negated.print_to_string().length <= stat.condition.print_to_string().length) {
|
||||||
|
CHANGED = true;
|
||||||
|
stat = stat.clone();
|
||||||
|
stat.condition = negated;
|
||||||
|
statements[j] = stat.body;
|
||||||
|
stat.body = next;
|
||||||
|
statements[i] = stat.transform(compressor);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ab = aborts(stat.alternative);
|
var ab = aborts(stat.alternative);
|
||||||
if (can_merge_flow(ab)) {
|
if (can_merge_flow(ab)) {
|
||||||
if (ab.label) {
|
if (ab.label) {
|
||||||
@@ -3316,13 +3328,14 @@ merge(Compressor.prototype, {
|
|||||||
} else if (node instanceof AST_Unary && node.write_only) {
|
} else if (node instanceof AST_Unary && node.write_only) {
|
||||||
sym = node.expression;
|
sym = node.expression;
|
||||||
}
|
}
|
||||||
if (/strict/.test(compressor.option("pure_getters"))) {
|
if (!/strict/.test(compressor.option("pure_getters"))) return sym instanceof AST_SymbolRef && sym;
|
||||||
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
||||||
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
||||||
sym = sym.expression;
|
sym = sym.expression;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sym;
|
return sym instanceof AST_SymbolRef && all(sym.definition().orig, function(sym) {
|
||||||
|
return !(sym instanceof AST_SymbolLambda);
|
||||||
|
}) && sym;
|
||||||
};
|
};
|
||||||
var in_use = [];
|
var in_use = [];
|
||||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||||
@@ -3417,7 +3430,7 @@ merge(Compressor.prototype, {
|
|||||||
var parent = tt.parent();
|
var parent = tt.parent();
|
||||||
if (drop_vars) {
|
if (drop_vars) {
|
||||||
var props = [], sym = assign_as_unused(node, props);
|
var props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef) {
|
if (sym) {
|
||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
var in_use = def.id in in_use_ids;
|
var in_use = def.id in in_use_ids;
|
||||||
var value = null;
|
var value = null;
|
||||||
@@ -3616,8 +3629,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function scan_ref_scoped(node, descend) {
|
function scan_ref_scoped(node, descend) {
|
||||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||||
if (sym instanceof AST_SymbolRef
|
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
|
||||||
&& self.variables.get(sym.name) === (node_def = sym.definition())) {
|
|
||||||
props.forEach(function(prop) {
|
props.forEach(function(prop) {
|
||||||
prop.walk(tw);
|
prop.walk(tw);
|
||||||
});
|
});
|
||||||
@@ -5758,9 +5770,10 @@ merge(Compressor.prototype, {
|
|||||||
if (fixed instanceof AST_Defun) {
|
if (fixed instanceof AST_Defun) {
|
||||||
fixed._squeezed = true;
|
fixed._squeezed = true;
|
||||||
fixed = make_node(AST_Function, fixed, fixed);
|
fixed = make_node(AST_Function, fixed, fixed);
|
||||||
|
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
|
||||||
}
|
}
|
||||||
var value;
|
var value;
|
||||||
if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
|
if (d.recursive_refs > 0) {
|
||||||
value = fixed.clone(true);
|
value = fixed.clone(true);
|
||||||
var defun_def = value.name.definition();
|
var defun_def = value.name.definition();
|
||||||
var lambda_def = value.variables.get(value.name.name);
|
var lambda_def = value.variables.get(value.name.name);
|
||||||
|
|||||||
@@ -694,23 +694,15 @@ function OutputStream(options) {
|
|||||||
// a function expression needs parens around it when it's provably
|
// a function expression needs parens around it when it's provably
|
||||||
// the first token to appear in a statement.
|
// the first token to appear in a statement.
|
||||||
PARENS(AST_Function, function(output) {
|
PARENS(AST_Function, function(output) {
|
||||||
if (!output.has_parens() && first_in_statement(output)) {
|
if (!output.has_parens() && first_in_statement(output)) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output.option('webkit')) {
|
if (output.option('webkit')) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
if (p instanceof AST_PropAccess && p.expression === this) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output.option('wrap_iife')) {
|
if (output.option('wrap_iife')) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_Call && p.expression === this;
|
if (p instanceof AST_Call && p.expression === this) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// same goes for an object literal, because otherwise it would be
|
// same goes for an object literal, because otherwise it would be
|
||||||
@@ -784,17 +776,17 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Call, function(output) {
|
PARENS(AST_Call, function(output) {
|
||||||
var p = output.parent(), p1;
|
var p = output.parent();
|
||||||
if (p instanceof AST_New && p.expression === this)
|
if (p instanceof AST_New && p.expression === this) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
// workaround for Safari bug.
|
|
||||||
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
||||||
return this.expression instanceof AST_Function
|
if (output.option('webkit')) {
|
||||||
&& p instanceof AST_PropAccess
|
var g = output.parent(1);
|
||||||
&& p.expression === this
|
return this.expression instanceof AST_Function
|
||||||
&& (p1 = output.parent(1)) instanceof AST_Assign
|
&& p instanceof AST_PropAccess
|
||||||
&& p1.left === p;
|
&& p.expression === this
|
||||||
|
&& g instanceof AST_Assign
|
||||||
|
&& g.left === p;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_New, function(output) {
|
PARENS(AST_New, function(output) {
|
||||||
|
|||||||
@@ -320,14 +320,6 @@ function next_mangled_name(scope, options, def) {
|
|||||||
var in_use = names_in_use(scope, options);
|
var in_use = names_in_use(scope, options);
|
||||||
var holes = scope.cname_holes;
|
var holes = scope.cname_holes;
|
||||||
var names = Object.create(null);
|
var names = Object.create(null);
|
||||||
// #179, #326
|
|
||||||
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
|
|
||||||
// a function expression's argument cannot shadow the function expression's name
|
|
||||||
if (scope instanceof AST_Function && scope.name && def.orig[0] instanceof AST_SymbolFunarg) {
|
|
||||||
var tricky_def = scope.name.definition();
|
|
||||||
// the function's mangled_name is null when keep_fnames is true
|
|
||||||
names[tricky_def.mangled_name || tricky_def.name] = true;
|
|
||||||
}
|
|
||||||
var scopes = [ scope ];
|
var scopes = [ scope ];
|
||||||
def.references.forEach(function(sym) {
|
def.references.forEach(function(sym) {
|
||||||
var scope = sym.scope;
|
var scope = sym.scope;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.4.6",
|
"version": "3.4.8",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.16.0",
|
"commander": "~2.17.1",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1982,3 +1982,26 @@ issue_3192: {
|
|||||||
"foo bar",
|
"foo bar",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3233: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function b() {
|
||||||
|
b.c = "PASS";
|
||||||
|
};
|
||||||
|
a();
|
||||||
|
console.log(a.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function b() {
|
||||||
|
b.c = "PASS";
|
||||||
|
};
|
||||||
|
a();
|
||||||
|
console.log(a.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -236,32 +236,6 @@ issue_203: {
|
|||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
no_webkit: {
|
|
||||||
beautify = {
|
|
||||||
webkit: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function() {
|
|
||||||
1 + 1;
|
|
||||||
}.a = 1);
|
|
||||||
}
|
|
||||||
expect_exact: "console.log(function(){1+1}.a=1);"
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
webkit: {
|
|
||||||
beautify = {
|
|
||||||
webkit: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function() {
|
|
||||||
1 + 1;
|
|
||||||
}.a = 1);
|
|
||||||
}
|
|
||||||
expect_exact: "console.log((function(){1+1}).a=1);"
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2084: {
|
issue_2084: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
|||||||
@@ -396,3 +396,151 @@ if_if_return_return: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_body_return_1: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_2: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (0 + a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (0 + a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if_body_return_3: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (1 == a) {
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
function f(a, b) {
|
||||||
|
if (1 != a) return true;
|
||||||
|
if (b) throw new Error(c);
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
console.log(f(0, 0));
|
||||||
|
console.log(f(0, 1));
|
||||||
|
console.log(f(1, 0));
|
||||||
|
try {
|
||||||
|
f(1, 1);
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"true",
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
109
test/compress/webkit.js
Normal file
109
test/compress/webkit.js
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
lambda_call_dot_assign: {
|
||||||
|
beautify = {
|
||||||
|
webkit: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return {};
|
||||||
|
}().a = 1);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(function(){return{}}().a=1);"
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
lambda_call_dot_assign_webkit: {
|
||||||
|
beautify = {
|
||||||
|
webkit: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return {};
|
||||||
|
}().a = 1);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((function(){return{}}()).a=1);"
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
lambda_dot_assign: {
|
||||||
|
beautify = {
|
||||||
|
webkit: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
1 + 1;
|
||||||
|
}.a = 1);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(function(){1+1}.a=1);"
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
lambda_dot_assign_webkit: {
|
||||||
|
beautify = {
|
||||||
|
webkit: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
1 + 1;
|
||||||
|
}.a = 1);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((function(){1+1}).a=1);"
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
lambda_name_mangle: {
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function foo(bar) {});
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof function o(n){});"
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
lambda_name_mangle_ie8: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function foo(bar) {});
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof function n(o){});"
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_name_mangle: {
|
||||||
|
options = {
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function foo(bar) {}
|
||||||
|
console.log(typeof foo);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: "(function(){console.log(typeof function o(n){})})();"
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_name_mangle_ie8: {
|
||||||
|
options = {
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function foo(bar) {}
|
||||||
|
console.log(typeof foo);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: "(function(){console.log(typeof function n(o){})})();"
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
@@ -23,10 +23,9 @@ module.exports = function(url, callback) {
|
|||||||
var options = parse(url);
|
var options = parse(url);
|
||||||
options.rejectUnauthorized = false;
|
options.rejectUnauthorized = false;
|
||||||
require(options.protocol.slice(0, -1)).get(options, function(res) {
|
require(options.protocol.slice(0, -1)).get(options, function(res) {
|
||||||
if (res.statusCode !== 200) return callback(res);
|
if (res.statusCode !== 200) return callback(res.statusCode);
|
||||||
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
res.pipe(fs.createWriteStream(local(url)));
|
||||||
callback(null, read(url));
|
callback(null, res);
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
}).on("open", function() {
|
}).on("open", function() {
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
|
|||||||
@@ -25,30 +25,35 @@ if (typeof phantom == "undefined") {
|
|||||||
request.resume();
|
request.resume();
|
||||||
var url = site + request.url;
|
var url = site + request.url;
|
||||||
fetch(url, function(err, res) {
|
fetch(url, function(err, res) {
|
||||||
if (err) throw err;
|
if (err) {
|
||||||
response.writeHead(200, {
|
if (typeof err != "number") throw err;
|
||||||
"Content-Type": {
|
response.writeHead(err);
|
||||||
css: "text/css",
|
response.end();
|
||||||
js: "application/javascript",
|
|
||||||
png: "image/png"
|
|
||||||
}[url.slice(url.lastIndexOf(".") + 1)] || "text/html; charset=utf-8"
|
|
||||||
});
|
|
||||||
if (/\.js$/.test(url)) {
|
|
||||||
var stderr = "";
|
|
||||||
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
|
||||||
silent: true
|
|
||||||
}).on("exit", function(code) {
|
|
||||||
console.log("uglifyjs", url.slice(site.length + 1), args.join(" "));
|
|
||||||
console.log(stderr);
|
|
||||||
if (code) throw new Error("uglifyjs failed with code " + code);
|
|
||||||
});
|
|
||||||
uglifyjs.stderr.on("data", function(data) {
|
|
||||||
stderr += data;
|
|
||||||
}).setEncoding("utf8");
|
|
||||||
uglifyjs.stdout.pipe(response);
|
|
||||||
res.pipe(uglifyjs.stdin);
|
|
||||||
} else {
|
} else {
|
||||||
res.pipe(response);
|
response.writeHead(200, {
|
||||||
|
"Content-Type": {
|
||||||
|
css: "text/css",
|
||||||
|
js: "application/javascript",
|
||||||
|
png: "image/png"
|
||||||
|
}[url.slice(url.lastIndexOf(".") + 1)] || "text/html; charset=utf-8"
|
||||||
|
});
|
||||||
|
if (/\.js$/.test(url)) {
|
||||||
|
var stderr = "";
|
||||||
|
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
||||||
|
silent: true
|
||||||
|
}).on("exit", function(code) {
|
||||||
|
console.log("uglifyjs", url.slice(site.length + 1), args.join(" "));
|
||||||
|
console.log(stderr);
|
||||||
|
if (code) throw new Error("uglifyjs failed with code " + code);
|
||||||
|
});
|
||||||
|
uglifyjs.stderr.on("data", function(data) {
|
||||||
|
stderr += data;
|
||||||
|
}).setEncoding("utf8");
|
||||||
|
uglifyjs.stdout.pipe(response);
|
||||||
|
res.pipe(uglifyjs.stdin);
|
||||||
|
} else {
|
||||||
|
res.pipe(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).listen();
|
}).listen();
|
||||||
|
|||||||
@@ -651,7 +651,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with explicit --no-rename", function(done) {
|
it("Should work with explicit --no-rename", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/rename/input.js -mc --no-rename";
|
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
||||||
@@ -659,7 +659,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with implicit --rename", function(done) {
|
it("Should work with implicit --rename", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/rename/input.js -mc";
|
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(n){return n}\n");
|
assert.strictEqual(stdout, "function f(n){return n}\n");
|
||||||
@@ -667,7 +667,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with implicit --no-rename", function(done) {
|
it("Should work with implicit --no-rename", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/rename/input.js -c";
|
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
||||||
|
|||||||
@@ -1,21 +1,6 @@
|
|||||||
var semver = require("semver");
|
var semver = require("semver");
|
||||||
var vm = require("vm");
|
var vm = require("vm");
|
||||||
|
|
||||||
function createContext() {
|
|
||||||
return vm.createContext(Object.defineProperty({}, "console", {
|
|
||||||
value: {
|
|
||||||
log: function(msg) {
|
|
||||||
if (arguments.length == 1 && typeof msg == "string") {
|
|
||||||
return console.log("%s", msg);
|
|
||||||
}
|
|
||||||
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
|
||||||
return safe_log(arg, 3);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function safe_log(arg, level) {
|
function safe_log(arg, level) {
|
||||||
if (arg) switch (typeof arg) {
|
if (arg) switch (typeof arg) {
|
||||||
case "function":
|
case "function":
|
||||||
@@ -25,21 +10,21 @@ function safe_log(arg, level) {
|
|||||||
arg.constructor.toString();
|
arg.constructor.toString();
|
||||||
if (level--) for (var key in arg) {
|
if (level--) for (var key in arg) {
|
||||||
var desc = Object.getOwnPropertyDescriptor(arg, key);
|
var desc = Object.getOwnPropertyDescriptor(arg, key);
|
||||||
if (!desc || !desc.get) {
|
if (!desc || !desc.get) arg[key] = safe_log(arg[key], level);
|
||||||
arg[key] = safe_log(arg[key], level);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
function strip_func_ids(text) {
|
function log(msg) {
|
||||||
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
if (arguments.length == 1 && typeof msg == "string") return console.log("%s", msg);
|
||||||
|
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
||||||
|
return safe_log(arg, 3);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
var context;
|
var func_toString = new vm.Script([
|
||||||
var FUNC_TOSTRING = [
|
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String ].forEach(function(f) {",
|
||||||
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String].forEach(function(f) {",
|
|
||||||
" f.toString = Function.prototype.toString;",
|
" f.toString = Function.prototype.toString;",
|
||||||
"});",
|
"});",
|
||||||
"Function.prototype.toString = function() {",
|
"Function.prototype.toString = function() {",
|
||||||
@@ -59,7 +44,15 @@ var FUNC_TOSTRING = [
|
|||||||
' return "function(){}";',
|
' return "function(){}";',
|
||||||
" };",
|
" };",
|
||||||
"}();",
|
"}();",
|
||||||
]).join("\n");
|
]).join("\n"));
|
||||||
|
|
||||||
|
function createContext() {
|
||||||
|
var ctx = vm.createContext(Object.defineProperty({}, "console", { value: { log: log } }));
|
||||||
|
func_toString.runInContext(ctx);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
var context;
|
||||||
exports.run_code = function(code, reuse) {
|
exports.run_code = function(code, reuse) {
|
||||||
var stdout = "";
|
var stdout = "";
|
||||||
var original_write = process.stdout.write;
|
var original_write = process.stdout.write;
|
||||||
@@ -69,7 +62,6 @@ exports.run_code = function(code, reuse) {
|
|||||||
try {
|
try {
|
||||||
if (!reuse || !context) context = createContext();
|
if (!reuse || !context) context = createContext();
|
||||||
vm.runInContext([
|
vm.runInContext([
|
||||||
FUNC_TOSTRING,
|
|
||||||
"!function() {",
|
"!function() {",
|
||||||
code,
|
code,
|
||||||
"}();",
|
"}();",
|
||||||
@@ -86,6 +78,11 @@ exports.run_code = function(code, reuse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function strip_func_ids(text) {
|
||||||
|
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||||
|
}
|
||||||
|
|
||||||
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {
|
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {
|
||||||
if (typeof expected != typeof actual) return false;
|
if (typeof expected != typeof actual) return false;
|
||||||
if (typeof expected != "string") {
|
if (typeof expected != "string") {
|
||||||
|
|||||||
Reference in New Issue
Block a user