Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
448a8d3845 | ||
|
|
f5c09d0bbf | ||
|
|
014f655c5f | ||
|
|
bf30dc3038 | ||
|
|
ef2ef07cbd | ||
|
|
1a4440080d | ||
|
|
ac0086a745 | ||
|
|
2494daaf68 | ||
|
|
9b404f9de6 | ||
|
|
5344b7dab8 | ||
|
|
0007a53b9c | ||
|
|
1dd05f44eb | ||
|
|
bf7b122ab2 | ||
|
|
e29048b54a | ||
|
|
2eeb640eca | ||
|
|
ceb200fe81 | ||
|
|
f5f8239057 | ||
|
|
6f9d051784 | ||
|
|
931862e97f | ||
|
|
1d0127de21 | ||
|
|
2d8fc61677 | ||
|
|
1e31011874 | ||
|
|
75cdbf19aa | ||
|
|
4339bd5cfa | ||
|
|
1ab2fdaa10 | ||
|
|
eda540f6ec | ||
|
|
90a330da16 | ||
|
|
cad1f9cbd1 | ||
|
|
f6203bd5a8 | ||
|
|
03cf94ebe8 | ||
|
|
c3087dd179 | ||
|
|
2c305af478 | ||
|
|
72e6f64ca8 | ||
|
|
b9fac687ff | ||
|
|
2c88eb6fbe | ||
|
|
a67e3bfdd3 | ||
|
|
27142df4f5 | ||
|
|
5e4c7f4245 | ||
|
|
b521b4b926 | ||
|
|
aa9de76370 | ||
|
|
5a083a938d | ||
|
|
7a30d826b8 | ||
|
|
be55a09edf |
@@ -1,7 +1,6 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "0.4"
|
- "0.4"
|
||||||
- "0.6"
|
|
||||||
- "0.8"
|
- "0.8"
|
||||||
- "0.10"
|
- "0.10"
|
||||||
- "0.11"
|
- "0.11"
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ The available options are:
|
|||||||
--source-map-url The path to the source map to be added in //#
|
--source-map-url The path to the source map to be added in //#
|
||||||
sourceMappingURL. Defaults to the value passed with
|
sourceMappingURL. Defaults to the value passed with
|
||||||
--source-map. [string]
|
--source-map. [string]
|
||||||
|
--source-map-include-sources
|
||||||
|
Pass this flag if you want to include the content of
|
||||||
|
source files in the source map as sourcesContent
|
||||||
|
property. [boolean]
|
||||||
--in-source-map Input source map, useful if you're compressing JS that was
|
--in-source-map Input source map, useful if you're compressing JS that was
|
||||||
generated from some other original code.
|
generated from some other original code.
|
||||||
--screw-ie8 Pass this flag if you don't care about full compliance
|
--screw-ie8 Pass this flag if you don't care about full compliance
|
||||||
@@ -169,7 +173,7 @@ To enable the mangler you need to pass `--mangle` (`-m`). The following
|
|||||||
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
||||||
default).
|
default).
|
||||||
|
|
||||||
- `eval` — mangle names visible in scopes where `eval` or `when` are used
|
- `eval` — mangle names visible in scopes where `eval` or `with` are used
|
||||||
(disabled by default).
|
(disabled by default).
|
||||||
|
|
||||||
When mangling is enabled but you want to prevent certain names from being
|
When mangling is enabled but you want to prevent certain names from being
|
||||||
@@ -505,7 +509,7 @@ something like this:
|
|||||||
```javascript
|
```javascript
|
||||||
var toplevel = null;
|
var toplevel = null;
|
||||||
files.forEach(function(file){
|
files.forEach(function(file){
|
||||||
var code = fs.readFileSync(file);
|
var code = fs.readFileSync(file, "utf8");
|
||||||
toplevel = UglifyJS.parse(code, {
|
toplevel = UglifyJS.parse(code, {
|
||||||
filename: file,
|
filename: file,
|
||||||
toplevel: toplevel
|
toplevel: toplevel
|
||||||
|
|||||||
14
bin/uglifyjs
14
bin/uglifyjs
@@ -22,6 +22,7 @@ mangling you need to use `-c` and `-m`.\
|
|||||||
.describe("source-map", "Specify an output file where to generate source map.")
|
.describe("source-map", "Specify an output file where to generate source map.")
|
||||||
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
||||||
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
||||||
|
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||||
.describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default UglifyJS will try to be IE-proof).")
|
.describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default UglifyJS will try to be IE-proof).")
|
||||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||||
@@ -88,6 +89,7 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.string("p")
|
.string("p")
|
||||||
|
|
||||||
.boolean("expr")
|
.boolean("expr")
|
||||||
|
.boolean("source-map-include-sources")
|
||||||
.boolean("screw-ie8")
|
.boolean("screw-ie8")
|
||||||
.boolean("export-all")
|
.boolean("export-all")
|
||||||
.boolean("self")
|
.boolean("self")
|
||||||
@@ -218,6 +220,7 @@ var STATS = {};
|
|||||||
var OUTPUT_FILE = ARGS.o;
|
var OUTPUT_FILE = ARGS.o;
|
||||||
var TOPLEVEL = null;
|
var TOPLEVEL = null;
|
||||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
||||||
|
var SOURCES_CONTENT = {};
|
||||||
|
|
||||||
var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({
|
var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({
|
||||||
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
||||||
@@ -255,6 +258,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SOURCES_CONTENT[file] = code;
|
||||||
time_it("parse", function(){
|
time_it("parse", function(){
|
||||||
if (ARGS.spidermonkey) {
|
if (ARGS.spidermonkey) {
|
||||||
var program = JSON.parse(code);
|
var program = JSON.parse(code);
|
||||||
@@ -337,6 +341,15 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
if (MANGLE) time_it("mangle", function(){
|
if (MANGLE) time_it("mangle", function(){
|
||||||
TOPLEVEL.mangle_names(MANGLE);
|
TOPLEVEL.mangle_names(MANGLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (ARGS.source_map_include_sources) {
|
||||||
|
for (var file in SOURCES_CONTENT) {
|
||||||
|
if (SOURCES_CONTENT.hasOwnProperty(file)) {
|
||||||
|
SOURCE_MAP.get().setSourceContent(file, SOURCES_CONTENT[file]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
time_it("generate", function(){
|
time_it("generate", function(){
|
||||||
TOPLEVEL.print(output);
|
TOPLEVEL.print(output);
|
||||||
});
|
});
|
||||||
@@ -357,7 +370,6 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
||||||
} else {
|
} else {
|
||||||
sys.print(output);
|
sys.print(output);
|
||||||
sys.error("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARGS.stats) {
|
if (ARGS.stats) {
|
||||||
|
|||||||
127
lib/compress.js
127
lib/compress.js
@@ -61,6 +61,7 @@ function Compressor(options, false_by_default) {
|
|||||||
loops : !false_by_default,
|
loops : !false_by_default,
|
||||||
unused : !false_by_default,
|
unused : !false_by_default,
|
||||||
hoist_funs : !false_by_default,
|
hoist_funs : !false_by_default,
|
||||||
|
keep_fargs : false,
|
||||||
hoist_vars : false,
|
hoist_vars : false,
|
||||||
if_return : !false_by_default,
|
if_return : !false_by_default,
|
||||||
join_vars : !false_by_default,
|
join_vars : !false_by_default,
|
||||||
@@ -71,6 +72,7 @@ function Compressor(options, false_by_default) {
|
|||||||
negate_iife : !false_by_default,
|
negate_iife : !false_by_default,
|
||||||
screw_ie8 : false,
|
screw_ie8 : false,
|
||||||
drop_console : false,
|
drop_console : false,
|
||||||
|
angular : false,
|
||||||
|
|
||||||
warnings : true,
|
warnings : true,
|
||||||
global_defs : {}
|
global_defs : {}
|
||||||
@@ -198,6 +200,9 @@ merge(Compressor.prototype, {
|
|||||||
var CHANGED;
|
var CHANGED;
|
||||||
do {
|
do {
|
||||||
CHANGED = false;
|
CHANGED = false;
|
||||||
|
if (compressor.option("angular")) {
|
||||||
|
statements = process_for_angular(statements);
|
||||||
|
}
|
||||||
statements = eliminate_spurious_blocks(statements);
|
statements = eliminate_spurious_blocks(statements);
|
||||||
if (compressor.option("dead_code")) {
|
if (compressor.option("dead_code")) {
|
||||||
statements = eliminate_dead_code(statements, compressor);
|
statements = eliminate_dead_code(statements, compressor);
|
||||||
@@ -219,6 +224,50 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
return statements;
|
return statements;
|
||||||
|
|
||||||
|
function process_for_angular(statements) {
|
||||||
|
function make_injector(func, name) {
|
||||||
|
return make_node(AST_SimpleStatement, func, {
|
||||||
|
body: make_node(AST_Assign, func, {
|
||||||
|
operator: "=",
|
||||||
|
left: make_node(AST_Dot, name, {
|
||||||
|
expression: make_node(AST_SymbolRef, name, name),
|
||||||
|
property: "$inject"
|
||||||
|
}),
|
||||||
|
right: make_node(AST_Array, func, {
|
||||||
|
elements: func.argnames.map(function(sym){
|
||||||
|
return make_node(AST_String, sym, { value: sym.name });
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return statements.reduce(function(a, stat){
|
||||||
|
a.push(stat);
|
||||||
|
var token = stat.start;
|
||||||
|
var comments = token.comments_before;
|
||||||
|
if (comments && comments.length > 0) {
|
||||||
|
var last = comments.pop();
|
||||||
|
if (/@ngInject/.test(last.value)) {
|
||||||
|
// case 1: defun
|
||||||
|
if (stat instanceof AST_Defun) {
|
||||||
|
a.push(make_injector(stat, stat.name));
|
||||||
|
}
|
||||||
|
else if (stat instanceof AST_Definitions) {
|
||||||
|
stat.definitions.forEach(function(def){
|
||||||
|
if (def.value && def.value instanceof AST_Lambda) {
|
||||||
|
a.push(make_injector(def.value, def.name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compressor.warn("Unknown statement marked with @ngInject [{file}:{line},{col}]", token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
function eliminate_spurious_blocks(statements) {
|
function eliminate_spurious_blocks(statements) {
|
||||||
var seen_dirs = [];
|
var seen_dirs = [];
|
||||||
return statements.reduce(function(a, stat){
|
return statements.reduce(function(a, stat){
|
||||||
@@ -328,7 +377,7 @@ merge(Compressor.prototype, {
|
|||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.condition = stat.condition.negate(compressor);
|
stat.condition = stat.condition.negate(compressor);
|
||||||
stat.body = make_node(AST_BlockStatement, stat, {
|
stat.body = make_node(AST_BlockStatement, stat, {
|
||||||
body: ret
|
body: as_statement_array(stat.alternative).concat(ret)
|
||||||
});
|
});
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat, {
|
stat.alternative = make_node(AST_BlockStatement, stat, {
|
||||||
body: body
|
body: body
|
||||||
@@ -996,18 +1045,20 @@ merge(Compressor.prototype, {
|
|||||||
var tt = new TreeTransformer(
|
var tt = new TreeTransformer(
|
||||||
function before(node, descend, in_list) {
|
function before(node, descend, in_list) {
|
||||||
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
||||||
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
if (!compressor.option("keep_fargs")) {
|
||||||
var sym = a[i];
|
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
||||||
if (sym.unreferenced()) {
|
var sym = a[i];
|
||||||
a.pop();
|
if (sym.unreferenced()) {
|
||||||
compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", {
|
a.pop();
|
||||||
name : sym.name,
|
compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", {
|
||||||
file : sym.start.file,
|
name : sym.name,
|
||||||
line : sym.start.line,
|
file : sym.start.file,
|
||||||
col : sym.start.col
|
line : sym.start.line,
|
||||||
});
|
col : sym.start.col
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else break;
|
||||||
}
|
}
|
||||||
else break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Defun && node !== self) {
|
if (node instanceof AST_Defun && node !== self) {
|
||||||
@@ -1836,6 +1887,18 @@ merge(Compressor.prototype, {
|
|||||||
return self.car;
|
return self.car;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (self.cdr instanceof AST_UnaryPrefix
|
||||||
|
&& self.cdr.operator == "void"
|
||||||
|
&& !self.cdr.expression.has_side_effects(compressor)) {
|
||||||
|
self.cdr.operator = self.car;
|
||||||
|
return self.cdr;
|
||||||
|
}
|
||||||
|
if (self.cdr instanceof AST_Undefined) {
|
||||||
|
return make_node(AST_UnaryPrefix, self, {
|
||||||
|
operator : "void",
|
||||||
|
expression : self.car
|
||||||
|
});
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2207,7 +2270,7 @@ merge(Compressor.prototype, {
|
|||||||
* ==>
|
* ==>
|
||||||
* exp = foo ? something : something_else;
|
* exp = foo ? something : something_else;
|
||||||
*/
|
*/
|
||||||
self = make_node(AST_Assign, self, {
|
return make_node(AST_Assign, self, {
|
||||||
operator: consequent.operator,
|
operator: consequent.operator,
|
||||||
left: consequent.left,
|
left: consequent.left,
|
||||||
right: make_node(AST_Conditional, self, {
|
right: make_node(AST_Conditional, self, {
|
||||||
@@ -2217,6 +2280,38 @@ merge(Compressor.prototype, {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (consequent instanceof AST_Call
|
||||||
|
&& alternative.TYPE === consequent.TYPE
|
||||||
|
&& consequent.args.length == alternative.args.length
|
||||||
|
&& consequent.expression.equivalent_to(alternative.expression)) {
|
||||||
|
if (consequent.args.length == 0) {
|
||||||
|
return make_node(AST_Seq, self, {
|
||||||
|
car: self.condition,
|
||||||
|
cdr: consequent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (consequent.args.length == 1) {
|
||||||
|
consequent.args[0] = make_node(AST_Conditional, self, {
|
||||||
|
condition: self.condition,
|
||||||
|
consequent: consequent.args[0],
|
||||||
|
alternative: alternative.args[0]
|
||||||
|
});
|
||||||
|
return consequent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// x?y?z:a:a --> x&&y?z:a
|
||||||
|
if (consequent instanceof AST_Conditional
|
||||||
|
&& consequent.alternative.equivalent_to(alternative)) {
|
||||||
|
return make_node(AST_Conditional, self, {
|
||||||
|
condition: make_node(AST_Binary, self, {
|
||||||
|
left: self.condition,
|
||||||
|
operator: "&&",
|
||||||
|
right: consequent.condition
|
||||||
|
}),
|
||||||
|
consequent: consequent.consequent,
|
||||||
|
alternative: alternative
|
||||||
|
});
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2256,6 +2351,12 @@ merge(Compressor.prototype, {
|
|||||||
property : prop
|
property : prop
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
var v = parseFloat(prop);
|
||||||
|
if (!isNaN(v) && v.toString() == prop) {
|
||||||
|
self.property = make_node(AST_Number, self.property, {
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,22 +46,23 @@
|
|||||||
function OutputStream(options) {
|
function OutputStream(options) {
|
||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
indent_start : 0,
|
indent_start : 0,
|
||||||
indent_level : 4,
|
indent_level : 4,
|
||||||
quote_keys : false,
|
quote_keys : false,
|
||||||
space_colon : true,
|
space_colon : true,
|
||||||
ascii_only : false,
|
ascii_only : false,
|
||||||
inline_script : false,
|
unescape_regexps : false,
|
||||||
width : 80,
|
inline_script : false,
|
||||||
max_line_len : 32000,
|
width : 80,
|
||||||
beautify : false,
|
max_line_len : 32000,
|
||||||
source_map : null,
|
beautify : false,
|
||||||
bracketize : false,
|
source_map : null,
|
||||||
semicolons : true,
|
bracketize : false,
|
||||||
comments : false,
|
semicolons : true,
|
||||||
preserve_line : false,
|
comments : false,
|
||||||
screw_ie8 : false,
|
preserve_line : false,
|
||||||
preamble : null,
|
screw_ie8 : false,
|
||||||
|
preamble : null,
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
var indentation = 0;
|
var indentation = 0;
|
||||||
@@ -386,13 +387,20 @@ function OutputStream(options) {
|
|||||||
var comments = start.comments_before || [];
|
var comments = start.comments_before || [];
|
||||||
|
|
||||||
// XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112
|
// XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112
|
||||||
// if this node is `return` or `throw`, we cannot allow comments before
|
// and https://github.com/mishoo/UglifyJS2/issues/372
|
||||||
// the returned or thrown value.
|
if (self instanceof AST_Exit && self.value) {
|
||||||
if (self instanceof AST_Exit && self.value
|
self.value.walk(new TreeWalker(function(node){
|
||||||
&& self.value.start.comments_before
|
if (node.start && node.start.comments_before) {
|
||||||
&& self.value.start.comments_before.length > 0) {
|
comments = comments.concat(node.start.comments_before);
|
||||||
comments = comments.concat(self.value.start.comments_before);
|
node.start.comments_before = [];
|
||||||
self.value.start.comments_before = [];
|
}
|
||||||
|
if (node instanceof AST_Function ||
|
||||||
|
node instanceof AST_Array ||
|
||||||
|
node instanceof AST_Object)
|
||||||
|
{
|
||||||
|
return true; // don't go inside.
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.test) {
|
if (c.test) {
|
||||||
@@ -456,7 +464,7 @@ function OutputStream(options) {
|
|||||||
|| p instanceof AST_Unary // !(foo, bar, baz)
|
|| p instanceof AST_Unary // !(foo, bar, baz)
|
||||||
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
||||||
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|
||||||
|| p instanceof AST_Dot // (1, {foo:2}).foo ==> 2
|
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
||||||
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
||||||
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
||||||
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
||||||
@@ -1111,10 +1119,47 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Number, function(self, output){
|
DEFPRINT(AST_Number, function(self, output){
|
||||||
output.print(make_num(self.getValue()));
|
output.print(make_num(self.getValue()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function regexp_safe_literal(code) {
|
||||||
|
return [
|
||||||
|
0x5c , // \
|
||||||
|
0x2f , // /
|
||||||
|
0x2e , // .
|
||||||
|
0x2b , // +
|
||||||
|
0x2a , // *
|
||||||
|
0x3f , // ?
|
||||||
|
0x28 , // (
|
||||||
|
0x29 , // )
|
||||||
|
0x5b , // [
|
||||||
|
0x5d , // ]
|
||||||
|
0x7b , // {
|
||||||
|
0x7d , // }
|
||||||
|
0x24 , // $
|
||||||
|
0x5e , // ^
|
||||||
|
0x3a , // :
|
||||||
|
0x7c , // |
|
||||||
|
0x21 , // !
|
||||||
|
0x0a , // \n
|
||||||
|
0x0d , // \r
|
||||||
|
0x00 , // \0
|
||||||
|
0xfeff , // Unicode BOM
|
||||||
|
0x2028 , // unicode "line separator"
|
||||||
|
0x2029 , // unicode "paragraph separator"
|
||||||
|
].indexOf(code) < 0;
|
||||||
|
};
|
||||||
|
|
||||||
DEFPRINT(AST_RegExp, function(self, output){
|
DEFPRINT(AST_RegExp, function(self, output){
|
||||||
var str = self.getValue().toString();
|
var str = self.getValue().toString();
|
||||||
if (output.option("ascii_only"))
|
if (output.option("ascii_only")) {
|
||||||
str = output.to_ascii(str);
|
str = output.to_ascii(str);
|
||||||
|
} else if (output.option("unescape_regexps")) {
|
||||||
|
str = str.split("\\\\").map(function(str){
|
||||||
|
return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s){
|
||||||
|
var code = parseInt(s.substr(2), 16);
|
||||||
|
return regexp_safe_literal(code) ? String.fromCharCode(code) : s;
|
||||||
|
});
|
||||||
|
}).join("\\\\");
|
||||||
|
}
|
||||||
output.print(str);
|
output.print(str);
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
|
var KEYWORDS = 'break case catch const continue debugger default delete do else finally for function if in instanceof new return switch throw try typeof var void while with';
|
||||||
var KEYWORDS_ATOM = 'false null true';
|
var KEYWORDS_ATOM = 'false null true';
|
||||||
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile'
|
var RESERVED_WORDS = 'abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield'
|
||||||
+ " " + KEYWORDS_ATOM + " " + KEYWORDS;
|
+ " " + KEYWORDS_ATOM + " " + KEYWORDS;
|
||||||
var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
|
var KEYWORDS_BEFORE_EXPRESSION = 'return new delete throw else case';
|
||||||
|
|
||||||
@@ -1381,7 +1381,7 @@ function parse($TEXT, options) {
|
|||||||
condition : expr,
|
condition : expr,
|
||||||
consequent : yes,
|
consequent : yes,
|
||||||
alternative : expression(false, no_in),
|
alternative : expression(false, no_in),
|
||||||
end : peek()
|
end : prev()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
|
|||||||
@@ -365,6 +365,10 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
||||||
|
to_mangle.push(node.definition());
|
||||||
|
return;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ function SourceMap(options) {
|
|||||||
line: orig_line,
|
line: orig_line,
|
||||||
column: orig_col
|
column: orig_col
|
||||||
});
|
});
|
||||||
|
if (info.source === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
source = info.source;
|
source = info.source;
|
||||||
orig_line = info.line;
|
orig_line = info.line;
|
||||||
orig_col = info.column;
|
orig_col = info.column;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"main": "tools/node.js",
|
"main": "tools/node.js",
|
||||||
"version": "2.4.8",
|
"version": "2.4.13",
|
||||||
"engines": { "node" : ">=0.4.0" },
|
"engines": { "node" : ">=0.4.0" },
|
||||||
"maintainers": [{
|
"maintainers": [{
|
||||||
"name": "Mihai Bazon",
|
"name": "Mihai Bazon",
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async" : "~0.2.6",
|
"async" : "~0.2.6",
|
||||||
"source-map" : "~0.1.7",
|
"source-map" : "~0.1.33",
|
||||||
"optimist" : "~0.3.5",
|
"optimist" : "~0.3.5",
|
||||||
"uglify-to-browserify": "~1.0.0"
|
"uglify-to-browserify": "~1.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -141,3 +141,94 @@ ifs_6: {
|
|||||||
x = foo || bar || baz || boo ? 20 : 10;
|
x = foo || bar || baz || boo ? 20 : 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (some_condition()) {
|
||||||
|
do_something(x);
|
||||||
|
} else {
|
||||||
|
do_something(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
do_something(some_condition() ? x : y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (some_condition()) {
|
||||||
|
x = new FooBar(1);
|
||||||
|
} else {
|
||||||
|
x = new FooBar(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x = new FooBar(some_condition() ? 1 : 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (some_condition()) {
|
||||||
|
new FooBar(1);
|
||||||
|
} else {
|
||||||
|
FooBar(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
some_condition() ? new FooBar(1) : FooBar(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_4: {
|
||||||
|
options = {
|
||||||
|
conditionals: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (some_condition()) {
|
||||||
|
do_something();
|
||||||
|
} else {
|
||||||
|
do_something();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
some_condition(), do_something();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_5: {
|
||||||
|
options = {
|
||||||
|
conditionals: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (some_condition()) {
|
||||||
|
if (some_other_condition()) {
|
||||||
|
do_something();
|
||||||
|
} else {
|
||||||
|
alternate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alternate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (some_condition()) {
|
||||||
|
if (some_other_condition()) {
|
||||||
|
do_something();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
some_condition() && some_other_condition() ? do_something() : alternate();
|
||||||
|
some_condition() && some_other_condition() && do_something();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,16 +60,16 @@ negate_iife_4: {
|
|||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
if ((function(){ return true })()) {
|
if ((function(){ return true })()) {
|
||||||
console.log(true);
|
foo(true);
|
||||||
} else {
|
} else {
|
||||||
console.log(false);
|
bar(false);
|
||||||
}
|
}
|
||||||
(function(){
|
(function(){
|
||||||
console.log("something");
|
console.log("something");
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function(){ return true }() ? console.log(false) : console.log(true), function(){
|
!function(){ return true }() ? bar(false) : foo(true), function(){
|
||||||
console.log("something");
|
console.log("something");
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ for (var i in UglifyJS) {
|
|||||||
|
|
||||||
exports.minify = function(files, options) {
|
exports.minify = function(files, options) {
|
||||||
options = UglifyJS.defaults(options, {
|
options = UglifyJS.defaults(options, {
|
||||||
|
spidermonkey : false,
|
||||||
outSourceMap : null,
|
outSourceMap : null,
|
||||||
sourceRoot : null,
|
sourceRoot : null,
|
||||||
inSourceMap : null,
|
inSourceMap : null,
|
||||||
@@ -60,22 +61,28 @@ exports.minify = function(files, options) {
|
|||||||
output : null,
|
output : null,
|
||||||
compress : {}
|
compress : {}
|
||||||
});
|
});
|
||||||
if (typeof files == "string")
|
|
||||||
files = [ files ];
|
|
||||||
|
|
||||||
UglifyJS.base54.reset();
|
UglifyJS.base54.reset();
|
||||||
|
|
||||||
// 1. parse
|
// 1. parse
|
||||||
var toplevel = null;
|
var toplevel = null,
|
||||||
files.forEach(function(file){
|
sourcesContent = {};
|
||||||
var code = options.fromString
|
|
||||||
? file
|
if (options.spidermonkey) {
|
||||||
: fs.readFileSync(file, "utf8");
|
toplevel = UglifyJS.AST_Node.from_mozilla_ast(files);
|
||||||
toplevel = UglifyJS.parse(code, {
|
} else {
|
||||||
filename: options.fromString ? "?" : file,
|
if (typeof files == "string")
|
||||||
toplevel: toplevel
|
files = [ files ];
|
||||||
|
files.forEach(function(file){
|
||||||
|
var code = options.fromString
|
||||||
|
? file
|
||||||
|
: fs.readFileSync(file, "utf8");
|
||||||
|
sourcesContent[file] = code;
|
||||||
|
toplevel = UglifyJS.parse(code, {
|
||||||
|
filename: options.fromString ? "?" : file,
|
||||||
|
toplevel: toplevel
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
// 2. compress
|
// 2. compress
|
||||||
if (options.compress) {
|
if (options.compress) {
|
||||||
@@ -105,6 +112,14 @@ exports.minify = function(files, options) {
|
|||||||
orig: inMap,
|
orig: inMap,
|
||||||
root: options.sourceRoot
|
root: options.sourceRoot
|
||||||
});
|
});
|
||||||
|
if (options.sourceMapIncludeSources) {
|
||||||
|
for (var file in sourcesContent) {
|
||||||
|
if (sourcesContent.hasOwnProperty(file)) {
|
||||||
|
options.source_map.get().setSourceContent(file, sourcesContent[file]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (options.output) {
|
if (options.output) {
|
||||||
UglifyJS.merge(output, options.output);
|
UglifyJS.merge(output, options.output);
|
||||||
|
|||||||
Reference in New Issue
Block a user