clean up webkit quirks (#3229)
This commit is contained in:
@@ -48,51 +48,51 @@ function Compressor(options, false_by_default) {
|
||||
return new Compressor(options, false_by_default);
|
||||
TreeTransformer.call(this, this.before, this.after);
|
||||
this.options = defaults(options, {
|
||||
arguments : !false_by_default,
|
||||
booleans : !false_by_default,
|
||||
collapse_vars : !false_by_default,
|
||||
comparisons : !false_by_default,
|
||||
conditionals : !false_by_default,
|
||||
dead_code : !false_by_default,
|
||||
directives : !false_by_default,
|
||||
drop_console : false,
|
||||
drop_debugger : !false_by_default,
|
||||
evaluate : !false_by_default,
|
||||
expression : false,
|
||||
global_defs : false,
|
||||
hoist_funs : false,
|
||||
hoist_props : !false_by_default,
|
||||
hoist_vars : false,
|
||||
ie8 : false,
|
||||
if_return : !false_by_default,
|
||||
inline : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
keep_infinity : false,
|
||||
loops : !false_by_default,
|
||||
negate_iife : !false_by_default,
|
||||
passes : 1,
|
||||
properties : !false_by_default,
|
||||
pure_getters : !false_by_default && "strict",
|
||||
pure_funcs : null,
|
||||
reduce_funcs : !false_by_default,
|
||||
reduce_vars : !false_by_default,
|
||||
sequences : !false_by_default,
|
||||
side_effects : !false_by_default,
|
||||
switches : !false_by_default,
|
||||
top_retain : null,
|
||||
toplevel : !!(options && options["top_retain"]),
|
||||
typeofs : !false_by_default,
|
||||
unsafe : false,
|
||||
unsafe_comps : false,
|
||||
unsafe_Function: false,
|
||||
unsafe_math : false,
|
||||
unsafe_proto : false,
|
||||
unsafe_regexp : false,
|
||||
arguments : !false_by_default,
|
||||
booleans : !false_by_default,
|
||||
collapse_vars : !false_by_default,
|
||||
comparisons : !false_by_default,
|
||||
conditionals : !false_by_default,
|
||||
dead_code : !false_by_default,
|
||||
directives : !false_by_default,
|
||||
drop_console : false,
|
||||
drop_debugger : !false_by_default,
|
||||
evaluate : !false_by_default,
|
||||
expression : false,
|
||||
global_defs : false,
|
||||
hoist_funs : false,
|
||||
hoist_props : !false_by_default,
|
||||
hoist_vars : false,
|
||||
ie8 : false,
|
||||
if_return : !false_by_default,
|
||||
inline : !false_by_default,
|
||||
join_vars : !false_by_default,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
keep_infinity : false,
|
||||
loops : !false_by_default,
|
||||
negate_iife : !false_by_default,
|
||||
passes : 1,
|
||||
properties : !false_by_default,
|
||||
pure_getters : !false_by_default && "strict",
|
||||
pure_funcs : null,
|
||||
reduce_funcs : !false_by_default,
|
||||
reduce_vars : !false_by_default,
|
||||
sequences : !false_by_default,
|
||||
side_effects : !false_by_default,
|
||||
switches : !false_by_default,
|
||||
top_retain : null,
|
||||
toplevel : !!(options && options["top_retain"]),
|
||||
typeofs : !false_by_default,
|
||||
unsafe : false,
|
||||
unsafe_comps : false,
|
||||
unsafe_Function : false,
|
||||
unsafe_math : false,
|
||||
unsafe_proto : false,
|
||||
unsafe_regexp : false,
|
||||
unsafe_undefined: false,
|
||||
unused : !false_by_default,
|
||||
warnings : false,
|
||||
unused : !false_by_default,
|
||||
warnings : false,
|
||||
}, true);
|
||||
var global_defs = this.options["global_defs"];
|
||||
if (typeof global_defs == "object") for (var key in global_defs) {
|
||||
|
||||
@@ -694,23 +694,15 @@ function OutputStream(options) {
|
||||
// a function expression needs parens around it when it's provably
|
||||
// the first token to appear in a statement.
|
||||
PARENS(AST_Function, function(output) {
|
||||
if (!output.has_parens() && first_in_statement(output)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!output.has_parens() && first_in_statement(output)) return true;
|
||||
if (output.option('webkit')) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
||||
return true;
|
||||
}
|
||||
if (p instanceof AST_PropAccess && p.expression === this) return true;
|
||||
}
|
||||
|
||||
if (output.option('wrap_iife')) {
|
||||
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
|
||||
@@ -784,17 +776,17 @@ function OutputStream(options) {
|
||||
});
|
||||
|
||||
PARENS(AST_Call, function(output) {
|
||||
var p = output.parent(), p1;
|
||||
if (p instanceof AST_New && p.expression === this)
|
||||
return true;
|
||||
|
||||
// workaround for Safari bug.
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_New && p.expression === this) return true;
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
||||
return this.expression instanceof AST_Function
|
||||
&& p instanceof AST_PropAccess
|
||||
&& p.expression === this
|
||||
&& (p1 = output.parent(1)) instanceof AST_Assign
|
||||
&& p1.left === p;
|
||||
if (output.option('webkit')) {
|
||||
var g = output.parent(1);
|
||||
return this.expression instanceof AST_Function
|
||||
&& p instanceof AST_PropAccess
|
||||
&& p.expression === this
|
||||
&& g instanceof AST_Assign
|
||||
&& g.left === p;
|
||||
}
|
||||
});
|
||||
|
||||
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 holes = scope.cname_holes;
|
||||
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 ];
|
||||
def.references.forEach(function(sym) {
|
||||
var scope = sym.scope;
|
||||
|
||||
@@ -236,32 +236,6 @@ issue_203: {
|
||||
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: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
|
||||
60
test/compress/webkit.js
Normal file
60
test/compress/webkit.js
Normal file
@@ -0,0 +1,60 @@
|
||||
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"
|
||||
}
|
||||
@@ -23,10 +23,9 @@ module.exports = function(url, callback) {
|
||||
var options = parse(url);
|
||||
options.rejectUnauthorized = false;
|
||||
require(options.protocol.slice(0, -1)).get(options, function(res) {
|
||||
if (res.statusCode !== 200) return callback(res);
|
||||
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
||||
callback(null, read(url));
|
||||
}));
|
||||
if (res.statusCode !== 200) return callback(res.statusCode);
|
||||
res.pipe(fs.createWriteStream(local(url)));
|
||||
callback(null, res);
|
||||
});
|
||||
}).on("open", function() {
|
||||
callback(null, result);
|
||||
|
||||
@@ -25,30 +25,35 @@ if (typeof phantom == "undefined") {
|
||||
request.resume();
|
||||
var url = site + request.url;
|
||||
fetch(url, function(err, res) {
|
||||
if (err) throw err;
|
||||
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);
|
||||
if (err) {
|
||||
if (typeof err != "number") throw err;
|
||||
response.writeHead(err);
|
||||
response.end();
|
||||
} 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();
|
||||
|
||||
Reference in New Issue
Block a user