Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ccdf3337b | ||
|
|
dafed54764 | ||
|
|
a84beafd1b | ||
|
|
f01cc1e413 | ||
|
|
338dd144b8 | ||
|
|
c719552317 | ||
|
|
855964a87a | ||
|
|
a438e2fca9 | ||
|
|
00833e893a | ||
|
|
f1a77e4fc0 | ||
|
|
b55a2fd531 | ||
|
|
e8a2c0b5bf | ||
|
|
21cd7e3f57 | ||
|
|
5172ba5f2a | ||
|
|
a57b069409 | ||
|
|
4454656c3b | ||
|
|
fa43768ce0 | ||
|
|
a74e600fa0 | ||
|
|
4b21526310 |
@@ -636,6 +636,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
||||||
from terminal statements without `return`, e.g. in bookmarklets.
|
from terminal statements without `return`, e.g. in bookmarklets.
|
||||||
|
|
||||||
|
- `functions` (default: `true`) -- convert declarations from `var`to `function`
|
||||||
|
whenever possible.
|
||||||
|
|
||||||
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
||||||
|
|
||||||
- `hoist_funs` (default: `false`) -- hoist function declarations
|
- `hoist_funs` (default: `false`) -- hoist function declarations
|
||||||
|
|||||||
@@ -773,7 +773,7 @@ var AST_Label = DEFNODE("Label", "references", {
|
|||||||
}
|
}
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolRef = DEFNODE("SymbolRef", null, {
|
var AST_SymbolRef = DEFNODE("SymbolRef", "fixed", {
|
||||||
$documentation: "Reference to some symbol (not definition/declaration)",
|
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
|||||||
245
lib/compress.js
245
lib/compress.js
@@ -60,6 +60,7 @@ function Compressor(options, false_by_default) {
|
|||||||
drop_debugger : !false_by_default,
|
drop_debugger : !false_by_default,
|
||||||
evaluate : !false_by_default,
|
evaluate : !false_by_default,
|
||||||
expression : false,
|
expression : false,
|
||||||
|
functions : !false_by_default,
|
||||||
global_defs : false,
|
global_defs : false,
|
||||||
hoist_funs : false,
|
hoist_funs : false,
|
||||||
hoist_props : !false_by_default,
|
hoist_props : !false_by_default,
|
||||||
@@ -113,7 +114,7 @@ function Compressor(options, false_by_default) {
|
|||||||
};
|
};
|
||||||
} else if (Array.isArray(pure_funcs)) {
|
} else if (Array.isArray(pure_funcs)) {
|
||||||
this.pure_funcs = function(node) {
|
this.pure_funcs = function(node) {
|
||||||
return pure_funcs.indexOf(node.expression.print_to_string()) < 0;
|
return !member(node.expression.print_to_string(), pure_funcs);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.pure_funcs = return_true;
|
this.pure_funcs = return_true;
|
||||||
@@ -130,7 +131,7 @@ function Compressor(options, false_by_default) {
|
|||||||
top_retain = top_retain.split(/,/);
|
top_retain = top_retain.split(/,/);
|
||||||
}
|
}
|
||||||
this.top_retain = function(def) {
|
this.top_retain = function(def) {
|
||||||
return top_retain.indexOf(def.name) >= 0;
|
return member(def.name, top_retain);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var toplevel = this.options["toplevel"];
|
var toplevel = this.options["toplevel"];
|
||||||
@@ -150,7 +151,7 @@ Compressor.prototype = new TreeTransformer;
|
|||||||
merge(Compressor.prototype, {
|
merge(Compressor.prototype, {
|
||||||
option: function(key) { return this.options[key] },
|
option: function(key) { return this.options[key] },
|
||||||
exposed: function(def) {
|
exposed: function(def) {
|
||||||
if (def.global) for (var i = 0, len = def.orig.length; i < len; i++)
|
if (def.global) for (var i = 0; i < def.orig.length; i++)
|
||||||
if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
|
if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@@ -311,8 +312,22 @@ merge(Compressor.prototype, {
|
|||||||
return value instanceof AST_SymbolRef && value.fixed_value() || value;
|
return value instanceof AST_SymbolRef && value.fixed_value() || value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_read_only_fn(value, name) {
|
||||||
|
if (value instanceof AST_Boolean) return native_fns.Boolean[name];
|
||||||
|
if (value instanceof AST_Number) return native_fns.Number[name];
|
||||||
|
if (value instanceof AST_String) return native_fns.String[name];
|
||||||
|
if (name == "valueOf") return false;
|
||||||
|
if (value instanceof AST_Array) return native_fns.Array[name];
|
||||||
|
if (value instanceof AST_Function) return native_fns.Function[name];
|
||||||
|
if (value instanceof AST_Object) return native_fns.Object[name];
|
||||||
|
if (value instanceof AST_RegExp) return native_fns.RegExp[name];
|
||||||
|
}
|
||||||
|
|
||||||
function is_modified(compressor, tw, node, value, level, immutable) {
|
function is_modified(compressor, tw, node, value, level, immutable) {
|
||||||
var parent = tw.parent(level);
|
var parent = tw.parent(level);
|
||||||
|
if (compressor.option("unsafe") && parent instanceof AST_Dot && is_read_only_fn(value, parent.property)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var lhs = is_lhs(node, parent);
|
var lhs = is_lhs(node, parent);
|
||||||
if (lhs) return lhs;
|
if (lhs) return lhs;
|
||||||
if (!immutable
|
if (!immutable
|
||||||
@@ -343,7 +358,7 @@ merge(Compressor.prototype, {
|
|||||||
def.assignments = 0;
|
def.assignments = 0;
|
||||||
def.chained = false;
|
def.chained = false;
|
||||||
def.direct_access = false;
|
def.direct_access = false;
|
||||||
def.escaped = false;
|
def.escaped = [];
|
||||||
def.fixed = !def.scope.pinned()
|
def.fixed = !def.scope.pinned()
|
||||||
&& !compressor.exposed(def)
|
&& !compressor.exposed(def)
|
||||||
&& !(def.init instanceof AST_Function && def.init !== def.scope)
|
&& !(def.init instanceof AST_Function && def.init !== def.scope)
|
||||||
@@ -482,8 +497,9 @@ merge(Compressor.prototype, {
|
|||||||
|| parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
|
|| parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
|
||||||
|| parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
|
|| parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
|
||||||
|| parent instanceof AST_VarDef && node === parent.value) {
|
|| parent instanceof AST_VarDef && node === parent.value) {
|
||||||
|
d.escaped.push(parent);
|
||||||
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
||||||
if (!d.escaped || d.escaped > depth) d.escaped = depth;
|
if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth;
|
||||||
return;
|
return;
|
||||||
} else if (parent instanceof AST_Array
|
} else if (parent instanceof AST_Array
|
||||||
|| parent instanceof AST_Binary && lazy_op[parent.operator]
|
|| parent instanceof AST_Binary && lazy_op[parent.operator]
|
||||||
@@ -535,6 +551,7 @@ merge(Compressor.prototype, {
|
|||||||
mark_assignment_to_arguments(sym);
|
mark_assignment_to_arguments(sym);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sym.fixed) delete sym.fixed;
|
||||||
var d = sym.definition();
|
var d = sym.definition();
|
||||||
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
||||||
d.assignments++;
|
d.assignments++;
|
||||||
@@ -544,7 +561,7 @@ merge(Compressor.prototype, {
|
|||||||
var value = eq ? node.right : node;
|
var value = eq ? node.right : node;
|
||||||
if (is_modified(compressor, tw, node, value, 0)) return;
|
if (is_modified(compressor, tw, node, value, 0)) return;
|
||||||
if (!eq) d.chained = true;
|
if (!eq) d.chained = true;
|
||||||
d.fixed = eq ? function() {
|
sym.fixed = d.fixed = eq ? function() {
|
||||||
return node.right;
|
return node.right;
|
||||||
} : function() {
|
} : function() {
|
||||||
return make_node(AST_Binary, node, {
|
return make_node(AST_Binary, node, {
|
||||||
@@ -558,7 +575,7 @@ merge(Compressor.prototype, {
|
|||||||
mark(tw, d, false);
|
mark(tw, d, false);
|
||||||
node.right.walk(tw);
|
node.right.walk(tw);
|
||||||
mark(tw, d, true);
|
mark(tw, d, true);
|
||||||
mark_escaped(tw, d, sym.scope, node, value, 0, 1);
|
if (eq) mark_escaped(tw, d, sym.scope, node, value, 0, 1);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
def(AST_Binary, function(tw) {
|
def(AST_Binary, function(tw) {
|
||||||
@@ -714,6 +731,7 @@ merge(Compressor.prototype, {
|
|||||||
this.definition().fixed = false;
|
this.definition().fixed = false;
|
||||||
});
|
});
|
||||||
def(AST_SymbolRef, function(tw, descend, compressor) {
|
def(AST_SymbolRef, function(tw, descend, compressor) {
|
||||||
|
if (this.fixed) delete this.fixed;
|
||||||
var d = this.definition();
|
var d = this.definition();
|
||||||
d.references.push(this);
|
d.references.push(this);
|
||||||
if (d.references.length == 1
|
if (d.references.length == 1
|
||||||
@@ -726,7 +744,7 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
} else if (d.fixed) {
|
} else if (d.fixed) {
|
||||||
value = this.fixed_value();
|
value = this.fixed_value();
|
||||||
if (value instanceof AST_Lambda && recursive_ref(tw, d)) {
|
if (recursive_ref(tw, d)) {
|
||||||
d.recursive_refs++;
|
d.recursive_refs++;
|
||||||
} else if (value && ref_once(tw, compressor, d)) {
|
} else if (value && ref_once(tw, compressor, d)) {
|
||||||
d.single_use = value instanceof AST_Lambda && !value.pinned()
|
d.single_use = value instanceof AST_Lambda && !value.pinned()
|
||||||
@@ -741,8 +759,8 @@ merge(Compressor.prototype, {
|
|||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mark_escaped(tw, d, this.scope, this, value, 0, 1);
|
||||||
}
|
}
|
||||||
mark_escaped(tw, d, this.scope, this, value, 0, 1);
|
|
||||||
var parent;
|
var parent;
|
||||||
if (d.fixed instanceof AST_Defun
|
if (d.fixed instanceof AST_Defun
|
||||||
&& !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) {
|
&& !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) {
|
||||||
@@ -781,13 +799,14 @@ merge(Compressor.prototype, {
|
|||||||
mark_assignment_to_arguments(exp);
|
mark_assignment_to_arguments(exp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (exp.fixed) delete exp.fixed;
|
||||||
var d = exp.definition();
|
var d = exp.definition();
|
||||||
var safe = safe_to_assign(tw, d, exp.scope, true);
|
var safe = safe_to_assign(tw, d, exp.scope, true);
|
||||||
d.assignments++;
|
d.assignments++;
|
||||||
var fixed = d.fixed;
|
var fixed = d.fixed;
|
||||||
if (!fixed) return;
|
if (!fixed) return;
|
||||||
d.chained = true;
|
d.chained = true;
|
||||||
d.fixed = function() {
|
exp.fixed = d.fixed = function() {
|
||||||
return make_node(AST_Binary, node, {
|
return make_node(AST_Binary, node, {
|
||||||
operator: node.operator.slice(0, -1),
|
operator: node.operator.slice(0, -1),
|
||||||
left: make_node(AST_UnaryPrefix, node, {
|
left: make_node(AST_UnaryPrefix, node, {
|
||||||
@@ -858,10 +877,11 @@ merge(Compressor.prototype, {
|
|||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("fixed_value", function() {
|
AST_Symbol.DEFMETHOD("fixed_value", function(final) {
|
||||||
var fixed = this.definition().fixed;
|
var fixed = this.definition().fixed;
|
||||||
if (!fixed || fixed instanceof AST_Node) return fixed;
|
if (!fixed) return fixed;
|
||||||
return fixed();
|
if (!final && this.fixed) fixed = this.fixed;
|
||||||
|
return fixed instanceof AST_Node ? fixed : fixed();
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
|
AST_SymbolRef.DEFMETHOD("is_immutable", function() {
|
||||||
@@ -1241,7 +1261,7 @@ merge(Compressor.prototype, {
|
|||||||
// Scan case expressions first in a switch statement
|
// Scan case expressions first in a switch statement
|
||||||
if (node instanceof AST_Switch) {
|
if (node instanceof AST_Switch) {
|
||||||
node.expression = node.expression.transform(scanner);
|
node.expression = node.expression.transform(scanner);
|
||||||
for (var i = 0, len = node.body.length; !abort && i < len; i++) {
|
for (var i = 0; !abort && i < node.body.length; i++) {
|
||||||
var branch = node.body[i];
|
var branch = node.body[i];
|
||||||
if (branch instanceof AST_Case) {
|
if (branch instanceof AST_Case) {
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
@@ -1271,7 +1291,9 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_Try) return true;
|
if (node instanceof AST_Try) return true;
|
||||||
if (node instanceof AST_With) return true;
|
if (node instanceof AST_With) return true;
|
||||||
if (replace_all) return false;
|
if (replace_all) return false;
|
||||||
return node instanceof AST_SymbolRef && !node.is_declared(compressor);
|
return node instanceof AST_SymbolRef
|
||||||
|
&& !node.is_declared(compressor)
|
||||||
|
&& !(parent instanceof AST_Assign && parent.left === node);
|
||||||
}
|
}
|
||||||
|
|
||||||
function in_conditional(node, parent) {
|
function in_conditional(node, parent) {
|
||||||
@@ -1578,9 +1600,14 @@ merge(Compressor.prototype, {
|
|||||||
lvalues[candidate.name.name] = lhs;
|
lvalues[candidate.name.name] = lhs;
|
||||||
}
|
}
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
var sym = root_expr(node);
|
var value;
|
||||||
if (sym instanceof AST_SymbolRef || sym instanceof AST_This) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
lvalues[sym.name] = lvalues[sym.name] || is_modified(compressor, tw, node, node, 0);
|
value = node.fixed_value() || node;
|
||||||
|
} else if (node instanceof AST_This) {
|
||||||
|
value = node;
|
||||||
|
}
|
||||||
|
if (value && !lvalues[node.name]) {
|
||||||
|
lvalues[node.name] = is_modified(compressor, tw, node, value, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
expr.walk(tw);
|
expr.walk(tw);
|
||||||
@@ -1690,7 +1717,7 @@ merge(Compressor.prototype, {
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
statements.splice(i, 1);
|
statements.splice(i, 1);
|
||||||
} else if (stat instanceof AST_Directive) {
|
} else if (stat instanceof AST_Directive) {
|
||||||
if (seen_dirs.indexOf(stat.value) < 0) {
|
if (!member(stat.value, seen_dirs)) {
|
||||||
i++;
|
i++;
|
||||||
seen_dirs.push(stat.value);
|
seen_dirs.push(stat.value);
|
||||||
} else {
|
} else {
|
||||||
@@ -1887,7 +1914,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function next_index(i) {
|
function next_index(i) {
|
||||||
for (var j = i + 1, len = statements.length; j < len; j++) {
|
for (var j = i + 1; j < statements.length; j++) {
|
||||||
var stat = statements[j];
|
var stat = statements[j];
|
||||||
if (!(stat instanceof AST_Var && declarations_only(stat))) {
|
if (!(stat instanceof AST_Var && declarations_only(stat))) {
|
||||||
break;
|
break;
|
||||||
@@ -1978,7 +2005,7 @@ merge(Compressor.prototype, {
|
|||||||
function to_simple_statement(block, decls) {
|
function to_simple_statement(block, decls) {
|
||||||
if (!(block instanceof AST_BlockStatement)) return block;
|
if (!(block instanceof AST_BlockStatement)) return block;
|
||||||
var stat = null;
|
var stat = null;
|
||||||
for (var i = 0, len = block.body.length; i < len; i++) {
|
for (var i = 0; i < block.body.length; i++) {
|
||||||
var line = block.body[i];
|
var line = block.body[i];
|
||||||
if (line instanceof AST_Var && declarations_only(line)) {
|
if (line instanceof AST_Var && declarations_only(line)) {
|
||||||
decls.push(line);
|
decls.push(line);
|
||||||
@@ -2118,7 +2145,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function join_consecutive_vars(statements) {
|
function join_consecutive_vars(statements) {
|
||||||
var defs;
|
var defs;
|
||||||
for (var i = 0, j = -1, len = statements.length; i < len; i++) {
|
for (var i = 0, j = -1; i < statements.length; i++) {
|
||||||
var stat = statements[i];
|
var stat = statements[i];
|
||||||
var prev = statements[j];
|
var prev = statements[j];
|
||||||
if (stat instanceof AST_Definitions) {
|
if (stat instanceof AST_Definitions) {
|
||||||
@@ -2576,9 +2603,9 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function convert_to_predicate(obj) {
|
function convert_to_predicate(obj) {
|
||||||
for (var key in obj) {
|
Object.keys(obj).forEach(function(key) {
|
||||||
obj[key] = makePredicate(obj[key]);
|
obj[key] = makePredicate(obj[key]);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var object_fns = [
|
var object_fns = [
|
||||||
@@ -2719,7 +2746,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Array, function(compressor, cached, depth) {
|
def(AST_Array, function(compressor, cached, depth) {
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
var elements = [];
|
var elements = [];
|
||||||
for (var i = 0, len = this.elements.length; i < len; i++) {
|
for (var i = 0; i < this.elements.length; i++) {
|
||||||
var element = this.elements[i];
|
var element = this.elements[i];
|
||||||
var value = element._eval(compressor, cached, depth);
|
var value = element._eval(compressor, cached, depth);
|
||||||
if (element === value) return this;
|
if (element === value) return this;
|
||||||
@@ -2732,7 +2759,7 @@ merge(Compressor.prototype, {
|
|||||||
def(AST_Object, function(compressor, cached, depth) {
|
def(AST_Object, function(compressor, cached, depth) {
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
var val = {};
|
var val = {};
|
||||||
for (var i = 0, len = this.properties.length; i < len; i++) {
|
for (var i = 0; i < this.properties.length; i++) {
|
||||||
var prop = this.properties[i];
|
var prop = this.properties[i];
|
||||||
var key = prop.key;
|
var key = prop.key;
|
||||||
if (key instanceof AST_Symbol) {
|
if (key instanceof AST_Symbol) {
|
||||||
@@ -2832,7 +2859,7 @@ merge(Compressor.prototype, {
|
|||||||
var fixed = this.fixed_value();
|
var fixed = this.fixed_value();
|
||||||
if (!fixed) return this;
|
if (!fixed) return this;
|
||||||
var value;
|
var value;
|
||||||
if (cached.indexOf(fixed) >= 0) {
|
if (member(fixed, cached)) {
|
||||||
value = fixed._eval();
|
value = fixed._eval();
|
||||||
} else {
|
} else {
|
||||||
this._eval = return_this;
|
this._eval = return_this;
|
||||||
@@ -2846,9 +2873,25 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (value && typeof value == "object") {
|
if (value && typeof value == "object") {
|
||||||
var escaped = this.definition().escaped;
|
var escaped = this.definition().escaped;
|
||||||
if (escaped && depth > escaped) return this;
|
switch (escaped.length) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (contains_ref(escaped[0], this)) break;
|
||||||
|
default:
|
||||||
|
if (depth > escaped.depth) return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
function contains_ref(expr, ref) {
|
||||||
|
var found = false;
|
||||||
|
expr.walk(new TreeWalker(function(node) {
|
||||||
|
if (found) return true;
|
||||||
|
if (node === ref) return found = true;
|
||||||
|
}));
|
||||||
|
return found;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var global_objs = {
|
var global_objs = {
|
||||||
Array: Array,
|
Array: Array,
|
||||||
@@ -2927,7 +2970,7 @@ merge(Compressor.prototype, {
|
|||||||
if (!native_fn || !native_fn[key]) return this;
|
if (!native_fn || !native_fn[key]) return this;
|
||||||
}
|
}
|
||||||
var args = [];
|
var args = [];
|
||||||
for (var i = 0, len = this.args.length; i < len; i++) {
|
for (var i = 0; i < this.args.length; i++) {
|
||||||
var arg = this.args[i];
|
var arg = this.args[i];
|
||||||
var value = arg._eval(compressor, cached, depth);
|
var value = arg._eval(compressor, cached, depth);
|
||||||
if (arg === value) return this;
|
if (arg === value) return this;
|
||||||
@@ -3463,9 +3506,7 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_Definitions && scope === self) {
|
if (node instanceof AST_Definitions && scope === self) {
|
||||||
node.definitions.forEach(function(def) {
|
node.definitions.forEach(function(def) {
|
||||||
var node_def = def.name.definition();
|
var node_def = def.name.definition();
|
||||||
if (def.name instanceof AST_SymbolVar) {
|
var_defs_by_id.add(node_def.id, def);
|
||||||
var_defs_by_id.add(node_def.id, def);
|
|
||||||
}
|
|
||||||
if (!drop_vars) {
|
if (!drop_vars) {
|
||||||
if (!(node_def.id in in_use_ids)) {
|
if (!(node_def.id in in_use_ids)) {
|
||||||
in_use_ids[node_def.id] = true;
|
in_use_ids[node_def.id] = true;
|
||||||
@@ -3477,7 +3518,7 @@ merge(Compressor.prototype, {
|
|||||||
if (def.value.has_side_effects(compressor)) {
|
if (def.value.has_side_effects(compressor)) {
|
||||||
def.value.walk(tw);
|
def.value.walk(tw);
|
||||||
}
|
}
|
||||||
if (!node_def.chained && def.name.fixed_value() === def.value) {
|
if (!node_def.chained && def.name.fixed_value(true) === def.value) {
|
||||||
fixed_ids[node_def.id] = def;
|
fixed_ids[node_def.id] = def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3572,29 +3613,49 @@ merge(Compressor.prototype, {
|
|||||||
if (def.value && sym.id in fixed_ids && fixed_ids[sym.id] !== def) {
|
if (def.value && sym.id in fixed_ids && fixed_ids[sym.id] !== def) {
|
||||||
def.value = def.value.drop_side_effect_free(compressor);
|
def.value = def.value.drop_side_effect_free(compressor);
|
||||||
}
|
}
|
||||||
if (def.name instanceof AST_SymbolVar) {
|
var var_defs = var_defs_by_id.get(sym.id);
|
||||||
var var_defs = var_defs_by_id.get(sym.id);
|
if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
|
||||||
if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
|
compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
|
||||||
compressor.warn("Dropping duplicated definition of variable {name} [{file}:{line},{col}]", template(def.name));
|
if (def.value) {
|
||||||
if (def.value) {
|
var ref = make_node(AST_SymbolRef, def.name, def.name);
|
||||||
var ref = make_node(AST_SymbolRef, def.name, def.name);
|
sym.references.push(ref);
|
||||||
sym.references.push(ref);
|
var assign = make_node(AST_Assign, def, {
|
||||||
var assign = make_node(AST_Assign, def, {
|
operator: "=",
|
||||||
operator: "=",
|
left: ref,
|
||||||
left: ref,
|
right: def.value
|
||||||
right: def.value
|
});
|
||||||
});
|
if (fixed_ids[sym.id] === def) {
|
||||||
if (fixed_ids[sym.id] === def) {
|
fixed_ids[sym.id] = assign;
|
||||||
fixed_ids[sym.id] = assign;
|
|
||||||
}
|
|
||||||
side_effects.push(assign.transform(tt));
|
|
||||||
}
|
}
|
||||||
remove(var_defs, def);
|
side_effects.push(assign.transform(tt));
|
||||||
sym.eliminated++;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
remove(var_defs, def);
|
||||||
|
sym.eliminated++;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (def.value) {
|
if (!def.value) {
|
||||||
|
head.push(def);
|
||||||
|
} else if (compressor.option("functions")
|
||||||
|
&& def.value === def.name.fixed_value()
|
||||||
|
&& def.value instanceof AST_Function
|
||||||
|
&& can_rename(def.value, def.name.name)
|
||||||
|
&& (!compressor.has_directive("use strict") || parent instanceof AST_Scope)) {
|
||||||
|
compressor.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name));
|
||||||
|
var defun = make_node(AST_Defun, def, def.value);
|
||||||
|
defun.name = make_node(AST_SymbolDefun, def.name, def.name);
|
||||||
|
var name_def = def.name.scope.resolve().def_function(defun.name);
|
||||||
|
if (def.value.name) {
|
||||||
|
var old_def = def.value.name.definition();
|
||||||
|
def.value.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_SymbolRef && node.definition() === old_def) {
|
||||||
|
node.name = name_def.name;
|
||||||
|
node.thedef = name_def;
|
||||||
|
node.reference({});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
body.push(defun);
|
||||||
|
} else {
|
||||||
if (side_effects.length > 0) {
|
if (side_effects.length > 0) {
|
||||||
if (tail.length > 0) {
|
if (tail.length > 0) {
|
||||||
side_effects.push(def.value);
|
side_effects.push(def.value);
|
||||||
@@ -3607,8 +3668,6 @@ merge(Compressor.prototype, {
|
|||||||
side_effects = [];
|
side_effects = [];
|
||||||
}
|
}
|
||||||
tail.push(def);
|
tail.push(def);
|
||||||
} else {
|
|
||||||
head.push(def);
|
|
||||||
}
|
}
|
||||||
} else if (sym.orig[0] instanceof AST_SymbolCatch) {
|
} else if (sym.orig[0] instanceof AST_SymbolCatch) {
|
||||||
var value = def.value && def.value.drop_side_effect_free(compressor);
|
var value = def.value && def.value.drop_side_effect_free(compressor);
|
||||||
@@ -3625,6 +3684,11 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
sym.eliminated++;
|
sym.eliminated++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function can_rename(fn, name) {
|
||||||
|
var def = fn.variables.get(name);
|
||||||
|
return !def || fn.name && def === fn.name.definition();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (head.length > 0 || tail.length > 0) {
|
if (head.length > 0 || tail.length > 0) {
|
||||||
node.definitions = head.concat(tail);
|
node.definitions = head.concat(tail);
|
||||||
@@ -3650,6 +3714,7 @@ merge(Compressor.prototype, {
|
|||||||
// https://github.com/mishoo/UglifyJS2/issues/44
|
// https://github.com/mishoo/UglifyJS2/issues/44
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/1830
|
// https://github.com/mishoo/UglifyJS2/issues/1830
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/1838
|
// https://github.com/mishoo/UglifyJS2/issues/1838
|
||||||
|
// https://github.com/mishoo/UglifyJS2/issues/3371
|
||||||
// that's an invalid AST.
|
// that's an invalid AST.
|
||||||
// We fix it at this stage by moving the `var` outside the `for`.
|
// We fix it at this stage by moving the `var` outside the `for`.
|
||||||
if (node instanceof AST_For) {
|
if (node instanceof AST_For) {
|
||||||
@@ -3660,7 +3725,15 @@ merge(Compressor.prototype, {
|
|||||||
node.init = block.body.pop();
|
node.init = block.body.pop();
|
||||||
block.body.push(node);
|
block.body.push(node);
|
||||||
}
|
}
|
||||||
if (node.init instanceof AST_SimpleStatement) {
|
if (node.init instanceof AST_Defun) {
|
||||||
|
if (!block) {
|
||||||
|
block = make_node(AST_BlockStatement, node, {
|
||||||
|
body: [ node ]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
block.body.splice(-1, 0, node.init);
|
||||||
|
node.init = null;
|
||||||
|
} else if (node.init instanceof AST_SimpleStatement) {
|
||||||
node.init = node.init.body;
|
node.init = node.init.body;
|
||||||
} else if (is_empty(node.init)) {
|
} else if (is_empty(node.init)) {
|
||||||
node.init = null;
|
node.init = null;
|
||||||
@@ -3716,7 +3789,7 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_Assign) {
|
if (node instanceof AST_Assign) {
|
||||||
node.right.walk(tw);
|
node.right.walk(tw);
|
||||||
if (node.left === sym) {
|
if (node.left === sym) {
|
||||||
if (!node_def.chained && sym.fixed_value() === node.right) {
|
if (!node_def.chained && sym.fixed_value(true) === node.right) {
|
||||||
fixed_ids[node_def.id] = node;
|
fixed_ids[node_def.id] = node;
|
||||||
}
|
}
|
||||||
if (!node.write_only) {
|
if (!node.write_only) {
|
||||||
@@ -3966,7 +4039,7 @@ merge(Compressor.prototype, {
|
|||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
if (def.assignments != count) return;
|
if (def.assignments != count) return;
|
||||||
if (def.direct_access) return;
|
if (def.direct_access) return;
|
||||||
if (def.escaped == 1) return;
|
if (def.escaped.depth == 1) return;
|
||||||
if (def.references.length == count) return;
|
if (def.references.length == count) return;
|
||||||
if (def.single_use) return;
|
if (def.single_use) return;
|
||||||
if (top_retain(def)) return;
|
if (top_retain(def)) return;
|
||||||
@@ -4669,7 +4742,7 @@ merge(Compressor.prototype, {
|
|||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.pinned()) {
|
&& !fn.pinned()) {
|
||||||
var pos = 0, last = 0;
|
var pos = 0, last = 0;
|
||||||
for (var i = 0, len = self.args.length; i < len; i++) {
|
for (var i = 0; i < self.args.length; i++) {
|
||||||
var trim = i >= fn.argnames.length;
|
var trim = i >= fn.argnames.length;
|
||||||
if (trim || fn.argnames[i].__unused) {
|
if (trim || fn.argnames[i].__unused) {
|
||||||
var node = self.args[i].drop_side_effect_free(compressor);
|
var node = self.args[i].drop_side_effect_free(compressor);
|
||||||
@@ -5035,7 +5108,7 @@ merge(Compressor.prototype, {
|
|||||||
})) {
|
})) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (line instanceof AST_EmptyStatement) {
|
} else if (line instanceof AST_Defun || line instanceof AST_EmptyStatement) {
|
||||||
continue;
|
continue;
|
||||||
} else if (stat) {
|
} else if (stat) {
|
||||||
return false;
|
return false;
|
||||||
@@ -5046,33 +5119,32 @@ merge(Compressor.prototype, {
|
|||||||
return return_value(stat);
|
return return_value(stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function var_exists(catches, name) {
|
||||||
|
return catches[name] || identifier_atom[name] || scope.var_names()[name];
|
||||||
|
}
|
||||||
|
|
||||||
function can_inject_args(catches, safe_to_inject) {
|
function can_inject_args(catches, safe_to_inject) {
|
||||||
for (var i = 0, len = fn.argnames.length; i < len; i++) {
|
for (var i = 0; i < fn.argnames.length; i++) {
|
||||||
var arg = fn.argnames[i];
|
var arg = fn.argnames[i];
|
||||||
if (arg.__unused) continue;
|
if (arg.__unused) continue;
|
||||||
if (!safe_to_inject
|
if (!safe_to_inject || var_exists(catches, arg.name)) return false;
|
||||||
|| catches[arg.name]
|
|
||||||
|| identifier_atom[arg.name]
|
|
||||||
|| scope.var_names()[arg.name]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (in_loop) in_loop.push(arg.definition());
|
if (in_loop) in_loop.push(arg.definition());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function can_inject_vars(catches, safe_to_inject) {
|
function can_inject_vars(catches, safe_to_inject) {
|
||||||
for (var i = 0, len = fn.body.length; i < len; i++) {
|
for (var i = 0; i < fn.body.length; i++) {
|
||||||
var stat = fn.body[i];
|
var stat = fn.body[i];
|
||||||
|
if (stat instanceof AST_Defun) {
|
||||||
|
if (!safe_to_inject || var_exists(catches, stat.name.name)) return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!(stat instanceof AST_Var)) continue;
|
if (!(stat instanceof AST_Var)) continue;
|
||||||
if (!safe_to_inject) return false;
|
if (!safe_to_inject) return false;
|
||||||
for (var j = stat.definitions.length; --j >= 0;) {
|
for (var j = stat.definitions.length; --j >= 0;) {
|
||||||
var name = stat.definitions[j].name;
|
var name = stat.definitions[j].name;
|
||||||
if (catches[name.name]
|
if (var_exists(catches, name.name)) return false;
|
||||||
|| identifier_atom[name.name]
|
|
||||||
|| scope.var_names()[name.name]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (in_loop) in_loop.push(name.definition());
|
if (in_loop) in_loop.push(name.definition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5142,10 +5214,10 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function flatten_vars(decls, expressions) {
|
function flatten_vars(decls, expressions) {
|
||||||
var pos = expressions.length;
|
var pos = expressions.length;
|
||||||
for (var i = 0, lines = fn.body.length; i < lines; i++) {
|
for (var i = 0; i < fn.body.length; i++) {
|
||||||
var stat = fn.body[i];
|
var stat = fn.body[i];
|
||||||
if (!(stat instanceof AST_Var)) continue;
|
if (!(stat instanceof AST_Var)) continue;
|
||||||
for (var j = 0, defs = stat.definitions.length; j < defs; j++) {
|
for (var j = 0; j < stat.definitions.length; j++) {
|
||||||
var var_def = stat.definitions[j];
|
var var_def = stat.definitions[j];
|
||||||
var name = var_def.name;
|
var name = var_def.name;
|
||||||
var redef = name.definition().redefined();
|
var redef = name.definition().redefined();
|
||||||
@@ -5176,12 +5248,21 @@ merge(Compressor.prototype, {
|
|||||||
flatten_args(decls, expressions);
|
flatten_args(decls, expressions);
|
||||||
flatten_vars(decls, expressions);
|
flatten_vars(decls, expressions);
|
||||||
expressions.push(value);
|
expressions.push(value);
|
||||||
if (decls.length) {
|
var args = fn.body.filter(function(stat) {
|
||||||
i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
|
if (stat instanceof AST_Defun) {
|
||||||
scope.body.splice(i, 0, make_node(AST_Var, fn, {
|
var def = stat.name.definition();
|
||||||
definitions: decls
|
scope.functions.set(def.name, def);
|
||||||
}));
|
scope.variables.set(def.name, def);
|
||||||
}
|
scope.enclosed.push(def);
|
||||||
|
scope.var_names()[def.name] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
args.unshift(scope.body.indexOf(compressor.parent(level - 1)) + 1, 0);
|
||||||
|
if (decls.length) args.push(make_node(AST_Var, fn, {
|
||||||
|
definitions: decls
|
||||||
|
}));
|
||||||
|
[].splice.apply(scope.body, args);
|
||||||
return expressions;
|
return expressions;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -5846,7 +5927,7 @@ merge(Compressor.prototype, {
|
|||||||
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
||||||
if (single_use && fixed instanceof AST_Lambda) {
|
if (single_use && fixed instanceof AST_Lambda) {
|
||||||
if (def.scope !== self.scope
|
if (def.scope !== self.scope
|
||||||
&& (!compressor.option("reduce_funcs") || def.escaped == 1 || fixed.inlined)) {
|
&& (!compressor.option("reduce_funcs") || def.escaped.depth == 1 || fixed.inlined)) {
|
||||||
single_use = false;
|
single_use = false;
|
||||||
} else if (recursive_ref(compressor, def)) {
|
} else if (recursive_ref(compressor, def)) {
|
||||||
single_use = false;
|
single_use = false;
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
} : function(str) {
|
} : function(str) {
|
||||||
var s = "";
|
var s = "";
|
||||||
for (var i = 0, len = str.length; i < len; i++) {
|
for (var i = 0; i < str.length; i++) {
|
||||||
if (is_surrogate_pair_head(str[i]) && !is_surrogate_pair_tail(str[i + 1])
|
if (is_surrogate_pair_head(str[i]) && !is_surrogate_pair_tail(str[i + 1])
|
||||||
|| is_surrogate_pair_tail(str[i]) && !is_surrogate_pair_head(str[i - 1])) {
|
|| is_surrogate_pair_tail(str[i]) && !is_surrogate_pair_head(str[i - 1])) {
|
||||||
s += "\\u" + str.charCodeAt(i).toString(16);
|
s += "\\u" + str.charCodeAt(i).toString(16);
|
||||||
|
|||||||
10
lib/parse.js
10
lib/parse.js
@@ -164,10 +164,6 @@ function is_unicode_connector_punctuation(ch) {
|
|||||||
return UNICODE.connector_punctuation.test(ch);
|
return UNICODE.connector_punctuation.test(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_identifier(name) {
|
|
||||||
return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_identifier_start(code) {
|
function is_identifier_start(code) {
|
||||||
return code == 36 || code == 95 || is_letter(code);
|
return code == 36 || code == 95 || is_letter(code);
|
||||||
}
|
}
|
||||||
@@ -272,10 +268,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
function find_eol() {
|
function find_eol() {
|
||||||
var text = S.text;
|
var text = S.text;
|
||||||
for (var i = S.pos, n = S.text.length; i < n; ++i) {
|
for (var i = S.pos; i < S.text.length; ++i) {
|
||||||
var ch = text[i];
|
if (NEWLINE_CHARS[text[i]]) return i;
|
||||||
if (NEWLINE_CHARS[ch])
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
32
lib/scope.js
32
lib/scope.js
@@ -61,8 +61,6 @@ SymbolDef.next_id = 1;
|
|||||||
|
|
||||||
SymbolDef.prototype = {
|
SymbolDef.prototype = {
|
||||||
unmangleable: function(options) {
|
unmangleable: function(options) {
|
||||||
if (!options) options = {};
|
|
||||||
|
|
||||||
return this.global && !options.toplevel
|
return this.global && !options.toplevel
|
||||||
|| this.undeclared
|
|| this.undeclared
|
||||||
|| !options.eval && this.scope.pinned()
|
|| !options.eval && this.scope.pinned()
|
||||||
@@ -198,24 +196,20 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
var def = node.thedef;
|
var def = node.thedef;
|
||||||
if (def.orig.length == 1) {
|
redefine(node, node.scope.parent_scope);
|
||||||
redefine(node, node.scope.parent_scope);
|
node.thedef.init = def.init;
|
||||||
node.thedef.init = def.init;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function redefine(node, scope) {
|
function redefine(node, scope) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
var refs = node.thedef.references;
|
var old_def = node.thedef;
|
||||||
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
var new_def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||||
refs.forEach(function(ref) {
|
old_def.orig.concat(old_def.references).forEach(function(node) {
|
||||||
ref.thedef = def;
|
node.thedef = new_def;
|
||||||
ref.reference(options);
|
node.reference(options);
|
||||||
});
|
});
|
||||||
node.thedef = def;
|
|
||||||
node.reference(options);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -300,7 +294,7 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
|||||||
|
|
||||||
AST_Lambda.DEFMETHOD("resolve", return_this);
|
AST_Lambda.DEFMETHOD("resolve", return_this);
|
||||||
AST_Scope.DEFMETHOD("resolve", function() {
|
AST_Scope.DEFMETHOD("resolve", function() {
|
||||||
return this.parent_scope;
|
return this.parent_scope.resolve();
|
||||||
});
|
});
|
||||||
AST_Toplevel.DEFMETHOD("resolve", return_this);
|
AST_Toplevel.DEFMETHOD("resolve", return_this);
|
||||||
|
|
||||||
@@ -337,7 +331,7 @@ function next_mangled_name(scope, options, def) {
|
|||||||
} while (scope = scope.parent_scope);
|
} while (scope = scope.parent_scope);
|
||||||
});
|
});
|
||||||
var name;
|
var name;
|
||||||
for (var i = 0, len = holes.length; i < len; i++) {
|
for (var i = 0; i < holes.length; i++) {
|
||||||
name = base54(holes[i]);
|
name = base54(holes[i]);
|
||||||
if (names[name]) continue;
|
if (names[name]) continue;
|
||||||
holes.splice(i, 1);
|
holes.splice(i, 1);
|
||||||
@@ -346,7 +340,7 @@ function next_mangled_name(scope, options, def) {
|
|||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
name = base54(++scope.cname);
|
name = base54(++scope.cname);
|
||||||
if (in_use[name] || !is_identifier(name) || options.reserved.has[name]) continue;
|
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
|
||||||
if (!names[name]) break;
|
if (!names[name]) break;
|
||||||
holes.push(scope.cname);
|
holes.push(scope.cname);
|
||||||
}
|
}
|
||||||
@@ -426,7 +420,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|||||||
var name;
|
var name;
|
||||||
do {
|
do {
|
||||||
name = base54(++lname);
|
name = base54(++lname);
|
||||||
} while (!is_identifier(name));
|
} while (RESERVED_WORDS[name]);
|
||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -497,7 +491,7 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
|||||||
var name;
|
var name;
|
||||||
do {
|
do {
|
||||||
name = base54(cname++);
|
name = base54(cname++);
|
||||||
} while (avoid[name] || !is_identifier(name));
|
} while (avoid[name] || RESERVED_WORDS[name]);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,7 +553,7 @@ var base54 = (function() {
|
|||||||
var freq = Object.create(null);
|
var freq = Object.create(null);
|
||||||
function init(chars) {
|
function init(chars) {
|
||||||
var array = [];
|
var array = [];
|
||||||
for (var i = 0, len = chars.length; i < len; i++) {
|
for (var i = 0; i < chars.length; i++) {
|
||||||
var ch = chars[i];
|
var ch = chars[i];
|
||||||
array.push(ch);
|
array.push(ch);
|
||||||
freq[ch] = -1e-2 * i;
|
freq[ch] = -1e-2 * i;
|
||||||
|
|||||||
@@ -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.5.2",
|
"version": "3.5.7",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.19.0",
|
"commander": "~2.20.0",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~6.1.1",
|
"acorn": "~6.1.1",
|
||||||
"semver": "~5.6.0"
|
"semver": "~6.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
|
|||||||
@@ -289,3 +289,25 @@ increment_decrement_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3375: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function(b) {
|
||||||
|
var a = b += 1;
|
||||||
|
--b;
|
||||||
|
return a;
|
||||||
|
}("object"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function(b) {
|
||||||
|
var a = b += 1;
|
||||||
|
--b;
|
||||||
|
return a;
|
||||||
|
}("object"));
|
||||||
|
}
|
||||||
|
expect_stdout: "string"
|
||||||
|
}
|
||||||
|
|||||||
@@ -6157,3 +6157,24 @@ sub_property: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assign_undeclared: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var A = (console.log(42), function() {});
|
||||||
|
B = new A();
|
||||||
|
console.log(typeof B);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
B = new (console.log(42), function() {})();
|
||||||
|
console.log(typeof B);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"object",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -2005,3 +2005,24 @@ issue_3233: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3375: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1;
|
||||||
|
var a = c = [], c = --b + ("function" == typeof f && f());
|
||||||
|
var a = c && c[a];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1;
|
||||||
|
var a = [], c = --b + ("function" == typeof f && f());
|
||||||
|
a = c && c[a];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 0"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1124,14 +1124,14 @@ issue_2207_1: {
|
|||||||
console.log(Math.max(3, 6, 2, 7, 3, 4));
|
console.log(Math.max(3, 6, 2, 7, 3, 4));
|
||||||
console.log(Math.cos(1.2345));
|
console.log(Math.cos(1.2345));
|
||||||
console.log(Math.cos(1.2345) - Math.sin(4.321));
|
console.log(Math.cos(1.2345) - Math.sin(4.321));
|
||||||
console.log(Math.pow(Math.PI, Math.E - Math.LN10));
|
console.log(Math.pow(Math.PI, Math.E - Math.LN10).toFixed(15));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log("A");
|
console.log("A");
|
||||||
console.log(7);
|
console.log(7);
|
||||||
console.log(Math.cos(1.2345));
|
console.log(Math.cos(1.2345));
|
||||||
console.log(1.2543732512566947);
|
console.log(1.2543732512566947);
|
||||||
console.log(1.6093984514472044);
|
console.log("1.609398451447204");
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -1687,3 +1687,28 @@ try_increment: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe_escaped: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(function(index) {
|
||||||
|
return a[index];
|
||||||
|
}(function(term) {
|
||||||
|
return a.indexOf(term);
|
||||||
|
}("PASS")));
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2703,3 +2703,365 @@ loop_inline: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
functions: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a = function a() {
|
||||||
|
return a && "a";
|
||||||
|
};
|
||||||
|
var b = function x() {
|
||||||
|
return !!x;
|
||||||
|
};
|
||||||
|
var c = function(c) {
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
if (c(b(a()))) {
|
||||||
|
var d = function() {};
|
||||||
|
var e = function y() {
|
||||||
|
return typeof y;
|
||||||
|
};
|
||||||
|
var f = function(f) {
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
function a() {
|
||||||
|
return a && "a";
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
return !!b;
|
||||||
|
}
|
||||||
|
var c = function(c) {
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
if (c(b(a()))) {
|
||||||
|
function d() {}
|
||||||
|
function e() {
|
||||||
|
return typeof e;
|
||||||
|
}
|
||||||
|
var f = function(f) {
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "a true 42 function function function"
|
||||||
|
}
|
||||||
|
|
||||||
|
functions_use_strict: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
!function() {
|
||||||
|
var a = function a() {
|
||||||
|
return a && "a";
|
||||||
|
};
|
||||||
|
var b = function x() {
|
||||||
|
return !!x;
|
||||||
|
};
|
||||||
|
var c = function(c) {
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
if (c(b(a()))) {
|
||||||
|
var d = function() {};
|
||||||
|
var e = function y() {
|
||||||
|
return typeof y;
|
||||||
|
};
|
||||||
|
var f = function(f) {
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
!function() {
|
||||||
|
function a() {
|
||||||
|
return a && "a";
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
return !!b;
|
||||||
|
}
|
||||||
|
var c = function(c) {
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
if (c(b(a()))) {
|
||||||
|
var d = function() {};
|
||||||
|
var e = function y() {
|
||||||
|
return typeof y;
|
||||||
|
};
|
||||||
|
var f = function(f) {
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "a true 42 function function function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2437: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
functions: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
return bar();
|
||||||
|
}
|
||||||
|
function bar() {
|
||||||
|
if (xhrDesc) {
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
var result = !!req.onreadystatechange;
|
||||||
|
Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', xhrDesc || {});
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
var detectFunc = function(){};
|
||||||
|
req.onreadystatechange = detectFunc;
|
||||||
|
var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
|
||||||
|
req.onreadystatechange = null;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(foo());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
if (xhrDesc) {
|
||||||
|
var result = !!(req = new XMLHttpRequest()).onreadystatechange;
|
||||||
|
return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
|
||||||
|
result;
|
||||||
|
}
|
||||||
|
function detectFunc() {}
|
||||||
|
var req;
|
||||||
|
(req = new XMLHttpRequest()).onreadystatechange = detectFunc;
|
||||||
|
result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
|
||||||
|
return req.onreadystatechange = null, result;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2485: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = function(bar) {
|
||||||
|
var n = function(a, b) {
|
||||||
|
return a + b;
|
||||||
|
};
|
||||||
|
var sumAll = function(arg) {
|
||||||
|
return arg.reduce(n, 0);
|
||||||
|
};
|
||||||
|
var runSumAll = function(arg) {
|
||||||
|
return sumAll(arg);
|
||||||
|
};
|
||||||
|
bar.baz = function(arg) {
|
||||||
|
var n = runSumAll(arg);
|
||||||
|
return (n.get = 1), n;
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
};
|
||||||
|
var bar = foo({});
|
||||||
|
console.log(bar.baz([1, 2, 3]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = function(bar) {
|
||||||
|
function n(a, b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
function runSumAll(arg) {
|
||||||
|
return function(arg) {
|
||||||
|
return arg.reduce(n, 0);
|
||||||
|
}(arg);
|
||||||
|
}
|
||||||
|
bar.baz = function(arg) {
|
||||||
|
var n = runSumAll(arg);
|
||||||
|
return (n.get = 1), n;
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
};
|
||||||
|
var bar = foo({});
|
||||||
|
console.log(bar.baz([1, 2, 3]));
|
||||||
|
}
|
||||||
|
expect_stdout: "6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3364: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var s = 2, a = 100, b = 10, c = 0;
|
||||||
|
function f(p, e, r) {
|
||||||
|
try {
|
||||||
|
for (var i = 1; i-- > 0;)
|
||||||
|
var a = function(x) {
|
||||||
|
function g(y) {
|
||||||
|
y && y[a++];
|
||||||
|
}
|
||||||
|
var x = g(--s >= 0 && f(c++));
|
||||||
|
for (var j = 1; --j > 0;);
|
||||||
|
}();
|
||||||
|
} catch (e) {
|
||||||
|
try {
|
||||||
|
return;
|
||||||
|
} catch (z) {
|
||||||
|
for (var k = 1; --k > 0;) {
|
||||||
|
for (var l = 1; l > 0; --l) {
|
||||||
|
var n = function() {};
|
||||||
|
for (var k in n)
|
||||||
|
var o = (n, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var r = f();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var s = 2, c = 0;
|
||||||
|
(function n(r, o, a) {
|
||||||
|
try {
|
||||||
|
for (var f = 1; f-- >0;)
|
||||||
|
var t = function(r) {
|
||||||
|
(function(r) {
|
||||||
|
r && r[t++];
|
||||||
|
})(--s >= 0 && n(c++));
|
||||||
|
for (var o = 1; --o > 0;);
|
||||||
|
}();
|
||||||
|
} catch (o) {
|
||||||
|
try {
|
||||||
|
return;
|
||||||
|
} catch (r) {
|
||||||
|
for (var v = 1; --v > 0;)
|
||||||
|
for (var i = 1; i > 0;--i) {
|
||||||
|
function u() {}
|
||||||
|
for (var v in u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3366: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
return function() {};
|
||||||
|
}
|
||||||
|
var a = g();
|
||||||
|
(function() {
|
||||||
|
this && a && console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
void function() {
|
||||||
|
this && a && console.log("PASS");
|
||||||
|
}();
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3371: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var a = function f() {
|
||||||
|
(function() {
|
||||||
|
console.log(typeof f);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
while (a());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function a() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
while (a());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
class_iife: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var A = function() {
|
||||||
|
function B() {}
|
||||||
|
B.prototype.m = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return B;
|
||||||
|
}();
|
||||||
|
new A().m();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var A = (B.prototype.m = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}, B);
|
||||||
|
function B() {}
|
||||||
|
new A().m();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -861,3 +861,111 @@ issue_3215_4: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3355_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f() {
|
||||||
|
var f;
|
||||||
|
})();
|
||||||
|
(function g() {
|
||||||
|
})();
|
||||||
|
console.log(typeof f === typeof g);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function o() {
|
||||||
|
var o;
|
||||||
|
})();
|
||||||
|
(function o() {
|
||||||
|
})();
|
||||||
|
console.log(typeof f === typeof g);
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3355_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f() {
|
||||||
|
var f;
|
||||||
|
})();
|
||||||
|
(function g() {
|
||||||
|
})();
|
||||||
|
console.log(typeof f === typeof g);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f() {
|
||||||
|
var f;
|
||||||
|
})();
|
||||||
|
(function g() {
|
||||||
|
})();
|
||||||
|
console.log(typeof f === typeof g);
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3355_3: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(a) {
|
||||||
|
"aaaaaaaaaa";
|
||||||
|
a();
|
||||||
|
var b = function c() {
|
||||||
|
var c = 42;
|
||||||
|
console.log("FAIL");
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(a) {
|
||||||
|
"aaaaaaaaaa";
|
||||||
|
a();
|
||||||
|
var o = function a() {
|
||||||
|
var a = 42;
|
||||||
|
console.log("FAIL");
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3355_4: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(a) {
|
||||||
|
"aaaaaaaaaa";
|
||||||
|
a();
|
||||||
|
var b = function c() {
|
||||||
|
var c = 42;
|
||||||
|
console.log("FAIL");
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(a) {
|
||||||
|
"aaaaaaaaaa";
|
||||||
|
a();
|
||||||
|
var o = function n() {
|
||||||
|
var n = 42;
|
||||||
|
console.log("FAIL");
|
||||||
|
};
|
||||||
|
}(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -646,3 +646,30 @@ issue_2904: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3371: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
join_vars: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var a = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
while (a());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function a() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
for (; a(); );
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -281,8 +281,8 @@ unsafe_evaluate_escaped: {
|
|||||||
console.log(function(){ var o={p:3},a=[o]; console.log(a[0].p++); return o.p; }());
|
console.log(function(){ var o={p:3},a=[o]; console.log(a[0].p++); return o.p; }());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(){ var o={p:1}; console.log(o, o.p); return o.p; }());
|
console.log(function(){ var o={p:1}; console.log(o, 1); return o.p; }());
|
||||||
console.log(function(){ var o={p:2}; console.log(o.p, o); return o.p; }());
|
console.log(function(){ var o={p:2}; console.log(2, o); return o.p; }());
|
||||||
console.log(function(){ var o={p:3},a=[o]; console.log(a[0].p++); return o.p; }());
|
console.log(function(){ var o={p:3},a=[o]; console.log(a[0].p++); return o.p; }());
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -6737,3 +6737,21 @@ drop_side_effect_free: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "123"
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3377: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f() {
|
||||||
|
return f[0], (f = 42);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f() {
|
||||||
|
return f[0], (f = 42);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
exports["base54"] = base54;
|
|
||||||
exports["Compressor"] = Compressor;
|
exports["Compressor"] = Compressor;
|
||||||
exports["defaults"] = defaults;
|
exports["defaults"] = defaults;
|
||||||
exports["is_identifier"] = is_identifier;
|
|
||||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
@@ -9,7 +7,6 @@ exports["OutputStream"] = OutputStream;
|
|||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
exports["push_uniq"] = push_uniq;
|
exports["push_uniq"] = push_uniq;
|
||||||
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
||||||
exports["SourceMap"] = SourceMap;
|
|
||||||
exports["string_template"] = string_template;
|
exports["string_template"] = string_template;
|
||||||
exports["tokenizer"] = tokenizer;
|
exports["tokenizer"] = tokenizer;
|
||||||
exports["TreeTransformer"] = TreeTransformer;
|
exports["TreeTransformer"] = TreeTransformer;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var site = "https://browserbench.org/JetStream";
|
var site = "https://browserbench.org/JetStream1.1";
|
||||||
if (typeof phantom == "undefined") {
|
if (typeof phantom == "undefined") {
|
||||||
require("../tools/exit");
|
require("../tools/exit");
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
|
|||||||
@@ -73,8 +73,10 @@ exports.run_code = function(code, reuse) {
|
|||||||
process.stdout.write = original_write;
|
process.stdout.write = original_write;
|
||||||
if (!reuse || code.indexOf(".prototype") >= 0) {
|
if (!reuse || code.indexOf(".prototype") >= 0) {
|
||||||
context = null;
|
context = null;
|
||||||
} else for (var key in context) {
|
} else {
|
||||||
delete context[key];
|
vm.runInContext(Object.keys(context).map(function(name) {
|
||||||
|
return "delete " + name;
|
||||||
|
}).join("\n"), context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
1240
tools/domprops.json
1240
tools/domprops.json
File diff suppressed because it is too large
Load Diff
591
tools/props.html
591
tools/props.html
@@ -1,61 +1,540 @@
|
|||||||
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<body>
|
||||||
</head>
|
<script>
|
||||||
<body>
|
!function() {
|
||||||
<script>(function(){
|
var names = [];
|
||||||
var props = {};
|
var scanned = [];
|
||||||
|
var to_scan = [];
|
||||||
|
|
||||||
function addObject(obj) {
|
function scan(obj) {
|
||||||
if (obj == null) return;
|
if (obj && typeof obj == "object" && !~scanned.indexOf(obj)) {
|
||||||
try {
|
scanned.push(obj);
|
||||||
Object.getOwnPropertyNames(obj).forEach(add);
|
to_scan.push(obj);
|
||||||
} catch(ex) {}
|
}
|
||||||
if (obj.prototype) {
|
}
|
||||||
Object.getOwnPropertyNames(obj.prototype).forEach(add);
|
|
||||||
}
|
|
||||||
if (typeof obj == "function") {
|
|
||||||
try {
|
|
||||||
Object.getOwnPropertyNames(new obj).forEach(add);
|
|
||||||
} catch(ex) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add(name) {
|
scan(self);
|
||||||
props[name] = true;
|
[
|
||||||
}
|
"a",
|
||||||
|
"abbr",
|
||||||
|
"acronym",
|
||||||
|
"address",
|
||||||
|
"applet",
|
||||||
|
"area",
|
||||||
|
"article",
|
||||||
|
"aside",
|
||||||
|
"audio",
|
||||||
|
"b",
|
||||||
|
"base",
|
||||||
|
"basefont",
|
||||||
|
"bdi",
|
||||||
|
"bdo",
|
||||||
|
"bgsound",
|
||||||
|
"big",
|
||||||
|
"blink",
|
||||||
|
"blockquote",
|
||||||
|
"body",
|
||||||
|
"br",
|
||||||
|
"button",
|
||||||
|
"canvas",
|
||||||
|
"caption",
|
||||||
|
"center",
|
||||||
|
"checked",
|
||||||
|
"cite",
|
||||||
|
"code",
|
||||||
|
"col",
|
||||||
|
"colgroup",
|
||||||
|
"command",
|
||||||
|
"comment",
|
||||||
|
"compact",
|
||||||
|
"content",
|
||||||
|
"data",
|
||||||
|
"datalist",
|
||||||
|
"dd",
|
||||||
|
"declare",
|
||||||
|
"defer",
|
||||||
|
"del",
|
||||||
|
"details",
|
||||||
|
"dfn",
|
||||||
|
"dialog",
|
||||||
|
"dir",
|
||||||
|
"disabled",
|
||||||
|
"div",
|
||||||
|
"dl",
|
||||||
|
"dt",
|
||||||
|
"element",
|
||||||
|
"em",
|
||||||
|
"embed",
|
||||||
|
"fieldset",
|
||||||
|
"figcaption",
|
||||||
|
"figure",
|
||||||
|
"font",
|
||||||
|
"footer",
|
||||||
|
"form",
|
||||||
|
"frame",
|
||||||
|
"frameset",
|
||||||
|
"h1",
|
||||||
|
"h2",
|
||||||
|
"h3",
|
||||||
|
"h4",
|
||||||
|
"h5",
|
||||||
|
"h6",
|
||||||
|
"head",
|
||||||
|
"header",
|
||||||
|
"hgroup",
|
||||||
|
"hr",
|
||||||
|
"html",
|
||||||
|
"i",
|
||||||
|
"iframe",
|
||||||
|
"image",
|
||||||
|
"img",
|
||||||
|
"input",
|
||||||
|
"ins",
|
||||||
|
"isindex",
|
||||||
|
"ismap",
|
||||||
|
"kbd",
|
||||||
|
"keygen",
|
||||||
|
"label",
|
||||||
|
"legend",
|
||||||
|
"li",
|
||||||
|
"link",
|
||||||
|
"listing",
|
||||||
|
"main",
|
||||||
|
"map",
|
||||||
|
"mark",
|
||||||
|
"marquee",
|
||||||
|
"math",
|
||||||
|
"menu",
|
||||||
|
"menuitem",
|
||||||
|
"meta",
|
||||||
|
"meter",
|
||||||
|
"multicol",
|
||||||
|
"multiple",
|
||||||
|
"nav",
|
||||||
|
"nobr",
|
||||||
|
"noembed",
|
||||||
|
"noframes",
|
||||||
|
"nohref",
|
||||||
|
"noresize",
|
||||||
|
"noscript",
|
||||||
|
"noshade",
|
||||||
|
"nowrap",
|
||||||
|
"object",
|
||||||
|
"ol",
|
||||||
|
"optgroup",
|
||||||
|
"option",
|
||||||
|
"output",
|
||||||
|
"p",
|
||||||
|
"param",
|
||||||
|
"picture",
|
||||||
|
"plaintext",
|
||||||
|
"pre",
|
||||||
|
"progress",
|
||||||
|
"q",
|
||||||
|
"rb",
|
||||||
|
"readonly",
|
||||||
|
"rp",
|
||||||
|
"rt",
|
||||||
|
"rtc",
|
||||||
|
"ruby",
|
||||||
|
"s",
|
||||||
|
"samp",
|
||||||
|
"script",
|
||||||
|
"section",
|
||||||
|
"select",
|
||||||
|
"selected",
|
||||||
|
"shadow",
|
||||||
|
"small",
|
||||||
|
"source",
|
||||||
|
"spacer",
|
||||||
|
"span",
|
||||||
|
"strike",
|
||||||
|
"strong",
|
||||||
|
"style",
|
||||||
|
"sub",
|
||||||
|
"summary",
|
||||||
|
"sup",
|
||||||
|
"svg",
|
||||||
|
"table",
|
||||||
|
"tbody",
|
||||||
|
"td",
|
||||||
|
"template",
|
||||||
|
"textarea",
|
||||||
|
"tfoot",
|
||||||
|
"th",
|
||||||
|
"thead",
|
||||||
|
"time",
|
||||||
|
"title",
|
||||||
|
"tr",
|
||||||
|
"track",
|
||||||
|
"tt",
|
||||||
|
"u",
|
||||||
|
"ul",
|
||||||
|
"var",
|
||||||
|
"video",
|
||||||
|
"wbr",
|
||||||
|
"xmp",
|
||||||
|
"XXX",
|
||||||
|
].forEach(function(tag) {
|
||||||
|
scan(document.createElement(tag));
|
||||||
|
});
|
||||||
|
[
|
||||||
|
"abort",
|
||||||
|
"absolutedeviceorientation",
|
||||||
|
"activate",
|
||||||
|
"active",
|
||||||
|
"addsourcebuffer",
|
||||||
|
"addstream",
|
||||||
|
"addtrack",
|
||||||
|
"afterprint",
|
||||||
|
"afterscriptexecute",
|
||||||
|
"afterupdate",
|
||||||
|
"animationcancel",
|
||||||
|
"animationend",
|
||||||
|
"animationiteration",
|
||||||
|
"animationstart",
|
||||||
|
"appinstalled",
|
||||||
|
"audioend",
|
||||||
|
"audioprocess",
|
||||||
|
"audiostart",
|
||||||
|
"autocomplete",
|
||||||
|
"autocompleteerror",
|
||||||
|
"auxclick",
|
||||||
|
"beforeactivate",
|
||||||
|
"beforecopy",
|
||||||
|
"beforecut",
|
||||||
|
"beforedeactivate",
|
||||||
|
"beforeeditfocus",
|
||||||
|
"beforeinstallprompt",
|
||||||
|
"beforepaste",
|
||||||
|
"beforeprint",
|
||||||
|
"beforescriptexecute",
|
||||||
|
"beforeunload",
|
||||||
|
"beforeupdate",
|
||||||
|
"blocked",
|
||||||
|
"blur",
|
||||||
|
"bounce",
|
||||||
|
"boundary",
|
||||||
|
"cached",
|
||||||
|
"cancel",
|
||||||
|
"candidatewindowhide",
|
||||||
|
"candidatewindowshow",
|
||||||
|
"candidatewindowupdate",
|
||||||
|
"canplay",
|
||||||
|
"canplaythrough",
|
||||||
|
"cellchange",
|
||||||
|
"change",
|
||||||
|
"chargingchange",
|
||||||
|
"chargingtimechange",
|
||||||
|
"checking",
|
||||||
|
"click",
|
||||||
|
"close",
|
||||||
|
"compassneedscalibration",
|
||||||
|
"complete",
|
||||||
|
"connect",
|
||||||
|
"connecting",
|
||||||
|
"connectionstatechange",
|
||||||
|
"contextmenu",
|
||||||
|
"controllerchange",
|
||||||
|
"controlselect",
|
||||||
|
"copy",
|
||||||
|
"cuechange",
|
||||||
|
"cut",
|
||||||
|
"dataavailable",
|
||||||
|
"datachannel",
|
||||||
|
"datasetchanged",
|
||||||
|
"datasetcomplete",
|
||||||
|
"dblclick",
|
||||||
|
"deactivate",
|
||||||
|
"devicechange",
|
||||||
|
"devicelight",
|
||||||
|
"devicemotion",
|
||||||
|
"deviceorientation",
|
||||||
|
"deviceorientationabsolute",
|
||||||
|
"deviceproximity",
|
||||||
|
"dischargingtimechange",
|
||||||
|
"disconnect",
|
||||||
|
"display",
|
||||||
|
"downloading",
|
||||||
|
"drag",
|
||||||
|
"dragend",
|
||||||
|
"dragenter",
|
||||||
|
"dragexit",
|
||||||
|
"dragleave",
|
||||||
|
"dragover",
|
||||||
|
"dragstart",
|
||||||
|
"drop",
|
||||||
|
"durationchange",
|
||||||
|
"emptied",
|
||||||
|
"encrypted",
|
||||||
|
"end",
|
||||||
|
"ended",
|
||||||
|
"enter",
|
||||||
|
"enterpictureinpicture",
|
||||||
|
"error",
|
||||||
|
"errorupdate",
|
||||||
|
"exit",
|
||||||
|
"filterchange",
|
||||||
|
"finish",
|
||||||
|
"focus",
|
||||||
|
"focusin",
|
||||||
|
"focusout",
|
||||||
|
"freeze",
|
||||||
|
"fullscreenchange",
|
||||||
|
"fullscreenerror",
|
||||||
|
"gesturechange",
|
||||||
|
"gestureend",
|
||||||
|
"gesturestart",
|
||||||
|
"gotpointercapture",
|
||||||
|
"hashchange",
|
||||||
|
"help",
|
||||||
|
"icecandidate",
|
||||||
|
"iceconnectionstatechange",
|
||||||
|
"icegatheringstatechange",
|
||||||
|
"inactive",
|
||||||
|
"input",
|
||||||
|
"invalid",
|
||||||
|
"keydown",
|
||||||
|
"keypress",
|
||||||
|
"keyup",
|
||||||
|
"languagechange",
|
||||||
|
"layoutcomplete",
|
||||||
|
"leavepictureinpicture",
|
||||||
|
"levelchange",
|
||||||
|
"load",
|
||||||
|
"loadeddata",
|
||||||
|
"loadedmetadata",
|
||||||
|
"loadend",
|
||||||
|
"loading",
|
||||||
|
"loadingdone",
|
||||||
|
"loadingerror",
|
||||||
|
"loadstart",
|
||||||
|
"losecapture",
|
||||||
|
"lostpointercapture",
|
||||||
|
"mark",
|
||||||
|
"message",
|
||||||
|
"messageerror",
|
||||||
|
"mousedown",
|
||||||
|
"mouseenter",
|
||||||
|
"mouseleave",
|
||||||
|
"mousemove",
|
||||||
|
"mouseout",
|
||||||
|
"mouseover",
|
||||||
|
"mouseup",
|
||||||
|
"mousewheel",
|
||||||
|
"move",
|
||||||
|
"moveend",
|
||||||
|
"movestart",
|
||||||
|
"mozfullscreenchange",
|
||||||
|
"mozfullscreenerror",
|
||||||
|
"mozorientationchange",
|
||||||
|
"mozpointerlockchange",
|
||||||
|
"mozpointerlockerror",
|
||||||
|
"mscontentzoom",
|
||||||
|
"msfullscreenchange",
|
||||||
|
"msfullscreenerror",
|
||||||
|
"msgesturechange",
|
||||||
|
"msgesturedoubletap",
|
||||||
|
"msgestureend",
|
||||||
|
"msgesturehold",
|
||||||
|
"msgesturestart",
|
||||||
|
"msgesturetap",
|
||||||
|
"msgotpointercapture",
|
||||||
|
"msinertiastart",
|
||||||
|
"mslostpointercapture",
|
||||||
|
"msmanipulationstatechanged",
|
||||||
|
"msneedkey",
|
||||||
|
"msorientationchange",
|
||||||
|
"mspointercancel",
|
||||||
|
"mspointerdown",
|
||||||
|
"mspointerenter",
|
||||||
|
"mspointerhover",
|
||||||
|
"mspointerleave",
|
||||||
|
"mspointermove",
|
||||||
|
"mspointerout",
|
||||||
|
"mspointerover",
|
||||||
|
"mspointerup",
|
||||||
|
"mssitemodejumplistitemremoved",
|
||||||
|
"msthumbnailclick",
|
||||||
|
"negotiationneeded",
|
||||||
|
"nomatch",
|
||||||
|
"noupdate",
|
||||||
|
"obsolete",
|
||||||
|
"offline",
|
||||||
|
"online",
|
||||||
|
"open",
|
||||||
|
"orientationchange",
|
||||||
|
"pagechange",
|
||||||
|
"pagehide",
|
||||||
|
"pageshow",
|
||||||
|
"paste",
|
||||||
|
"pause",
|
||||||
|
"play",
|
||||||
|
"playing",
|
||||||
|
"pluginstreamstart",
|
||||||
|
"pointercancel",
|
||||||
|
"pointerdown",
|
||||||
|
"pointerenter",
|
||||||
|
"pointerleave",
|
||||||
|
"pointerlockchange",
|
||||||
|
"pointerlockerror",
|
||||||
|
"pointermove",
|
||||||
|
"pointerout",
|
||||||
|
"pointerover",
|
||||||
|
"pointerup",
|
||||||
|
"popstate",
|
||||||
|
"progress",
|
||||||
|
"propertychange",
|
||||||
|
"ratechange",
|
||||||
|
"reading",
|
||||||
|
"readystatechange",
|
||||||
|
"rejectionhandled",
|
||||||
|
"removesourcebuffer",
|
||||||
|
"removestream",
|
||||||
|
"removetrack",
|
||||||
|
"reset",
|
||||||
|
"resize",
|
||||||
|
"resizeend",
|
||||||
|
"resizestart",
|
||||||
|
"resourcetimingbufferfull",
|
||||||
|
"result",
|
||||||
|
"resume",
|
||||||
|
"rowenter",
|
||||||
|
"rowexit",
|
||||||
|
"rowsdelete",
|
||||||
|
"rowsinserted",
|
||||||
|
"scroll",
|
||||||
|
"search",
|
||||||
|
"seeked",
|
||||||
|
"seeking",
|
||||||
|
"select",
|
||||||
|
"selectionchange",
|
||||||
|
"selectstart",
|
||||||
|
"show",
|
||||||
|
"signalingstatechange",
|
||||||
|
"soundend",
|
||||||
|
"soundstart",
|
||||||
|
"sourceclose",
|
||||||
|
"sourceclosed",
|
||||||
|
"sourceended",
|
||||||
|
"sourceopen",
|
||||||
|
"speechend",
|
||||||
|
"speechstart",
|
||||||
|
"stalled",
|
||||||
|
"start",
|
||||||
|
"statechange",
|
||||||
|
"stop",
|
||||||
|
"storage",
|
||||||
|
"storagecommit",
|
||||||
|
"submit",
|
||||||
|
"success",
|
||||||
|
"suspend",
|
||||||
|
"textinput",
|
||||||
|
"timeout",
|
||||||
|
"timeupdate",
|
||||||
|
"toggle",
|
||||||
|
"touchcancel",
|
||||||
|
"touchend",
|
||||||
|
"touchmove",
|
||||||
|
"touchstart",
|
||||||
|
"track",
|
||||||
|
"transitioncancel",
|
||||||
|
"transitionend",
|
||||||
|
"transitionrun",
|
||||||
|
"transitionstart",
|
||||||
|
"unhandledrejection",
|
||||||
|
"unload",
|
||||||
|
"updateready",
|
||||||
|
"upgradeneeded",
|
||||||
|
"userproximity",
|
||||||
|
"versionchange",
|
||||||
|
"visibilitychange",
|
||||||
|
"voiceschanged",
|
||||||
|
"volumechange",
|
||||||
|
"vrdisplayactivate",
|
||||||
|
"vrdisplayconnect",
|
||||||
|
"vrdisplaydeactivate",
|
||||||
|
"vrdisplaydisconnect",
|
||||||
|
"vrdisplaypresentchange",
|
||||||
|
"waiting",
|
||||||
|
"waitingforkey",
|
||||||
|
"warning",
|
||||||
|
"webkitanimationend",
|
||||||
|
"webkitanimationiteration",
|
||||||
|
"webkitanimationstart",
|
||||||
|
"webkitcurrentplaybacktargetiswirelesschanged",
|
||||||
|
"webkitfullscreenchange",
|
||||||
|
"webkitfullscreenerror",
|
||||||
|
"webkitkeyadded",
|
||||||
|
"webkitkeyerror",
|
||||||
|
"webkitkeymessage",
|
||||||
|
"webkitneedkey",
|
||||||
|
"webkitorientationchange",
|
||||||
|
"webkitplaybacktargetavailabilitychanged",
|
||||||
|
"webkitpointerlockchange",
|
||||||
|
"webkitpointerlockerror",
|
||||||
|
"webkitresourcetimingbufferfull",
|
||||||
|
"webkittransitionend",
|
||||||
|
"wheel",
|
||||||
|
"zoom",
|
||||||
|
].forEach(function(type) {
|
||||||
|
[
|
||||||
|
"beforeunloadevent",
|
||||||
|
"compositionevent",
|
||||||
|
"customevent",
|
||||||
|
"devicemotionevent",
|
||||||
|
"deviceorientationevent",
|
||||||
|
"dragevent",
|
||||||
|
"event",
|
||||||
|
"events",
|
||||||
|
"focusevent",
|
||||||
|
"hashchangeevent",
|
||||||
|
"htmlevents",
|
||||||
|
"keyboardevent",
|
||||||
|
"messageevent",
|
||||||
|
"mouseevent",
|
||||||
|
"mouseevents",
|
||||||
|
"storageevent",
|
||||||
|
"svgevents",
|
||||||
|
"textevent",
|
||||||
|
"touchevent",
|
||||||
|
"uievent",
|
||||||
|
"uievents",
|
||||||
|
].forEach(function(interface) {
|
||||||
|
try {
|
||||||
|
var event = document.createEvent(interface);
|
||||||
|
event.initEvent(type, true, true);
|
||||||
|
scan(event);
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Object.getOwnPropertyNames(window).forEach(function(thing){
|
var obj;
|
||||||
addObject(window[thing]);
|
while (obj = to_scan.shift()) {
|
||||||
});
|
var proto = obj;
|
||||||
|
do {
|
||||||
try {
|
Object.getOwnPropertyNames(proto).forEach(function(name) {
|
||||||
addObject(new Event("click"));
|
var visited = ~names.indexOf(name);
|
||||||
addObject(new Event("contextmenu"));
|
if (!visited) names.push(name);
|
||||||
addObject(new Event("mouseup"));
|
try {
|
||||||
addObject(new Event("mousedown"));
|
scan(obj[name]);
|
||||||
addObject(new Event("keydown"));
|
if (visited) return;
|
||||||
addObject(new Event("keypress"));
|
if (/^create/.test(name)) {
|
||||||
addObject(new Event("keyup"));
|
scan(obj[name]());
|
||||||
} catch(ex) {}
|
}
|
||||||
|
if (/^[A-Z]/.test(name)) {
|
||||||
var ta = document.createElement("textarea");
|
scan(new obj[name]());
|
||||||
ta.style.width = "100%";
|
}
|
||||||
ta.style.height = "20em";
|
} catch (e) {}
|
||||||
ta.style.boxSizing = "border-box";
|
});
|
||||||
<!-- ta.value = Object.keys(props).sort(cmp).map(function(name){ -->
|
} while (proto = Object.getPrototypeOf(proto));
|
||||||
<!-- return JSON.stringify(name); -->
|
}
|
||||||
<!-- }).join(",\n"); -->
|
names.sort();
|
||||||
ta.value = JSON.stringify({
|
document.write('<pre>[\n "');
|
||||||
vars: [],
|
document.write(names.join('",\n "'));
|
||||||
props: Object.keys(props).sort(cmp)
|
document.write('"\n]</pre>');
|
||||||
}, null, 2);
|
}();
|
||||||
document.body.appendChild(ta);
|
</script>
|
||||||
|
</body>
|
||||||
function cmp(a, b) {
|
|
||||||
a = a.toLowerCase();
|
|
||||||
b = b.toLowerCase();
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
}
|
|
||||||
})();</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user