Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7d3c07f5a |
@@ -1,2 +0,0 @@
|
|||||||
test
|
|
||||||
.travis.yml
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
before_install: "npm install -g npm"
|
before_install: "npm install -g npm"
|
||||||
node_js:
|
node_js:
|
||||||
|
- "0.8"
|
||||||
- "0.10"
|
- "0.10"
|
||||||
- "0.11"
|
- "0.11"
|
||||||
|
|||||||
223
README.md
223
README.md
@@ -52,87 +52,70 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
The available options are:
|
The available options are:
|
||||||
|
|
||||||
```
|
```
|
||||||
--source-map Specify an output file where to generate source
|
--source-map Specify an output file where to generate source map.
|
||||||
map.
|
[string]
|
||||||
--source-map-root The path to the original source to be included
|
--source-map-root The path to the original source to be included in the
|
||||||
in the source map.
|
source map. [string]
|
||||||
--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
|
sourceMappingURL. Defaults to the value passed with
|
||||||
with --source-map.
|
--source-map. [string]
|
||||||
--source-map-include-sources Pass this flag if you want to include the
|
--source-map-include-sources
|
||||||
content of source files in the source map as
|
Pass this flag if you want to include the content of
|
||||||
sourcesContent property.
|
source files in the source map as sourcesContent
|
||||||
--in-source-map Input source map, useful if you're compressing
|
property. [boolean]
|
||||||
JS that was generated from some other original
|
--in-source-map Input source map, useful if you're compressing JS that was
|
||||||
code.
|
generated from some other original code.
|
||||||
--screw-ie8 Pass this flag if you don't care about full
|
--screw-ie8 Pass this flag if you don't care about full compliance
|
||||||
compliance with Internet Explorer 6-8 quirks
|
with Internet Explorer 6-8 quirks (by default UglifyJS
|
||||||
(by default UglifyJS will try to be IE-proof).
|
will try to be IE-proof). [boolean]
|
||||||
--expr Parse a single expression, rather than a
|
--expr Parse a single expression, rather than a program (for
|
||||||
program (for parsing JSON)
|
parsing JSON) [boolean]
|
||||||
-p, --prefix Skip prefix for original filenames that appear
|
-p, --prefix Skip prefix for original filenames that appear in source
|
||||||
in source maps. For example -p 3 will drop 3
|
maps. For example -p 3 will drop 3 directories from file
|
||||||
directories from file names and ensure they are
|
names and ensure they are relative paths. You can also
|
||||||
relative paths. You can also specify -p
|
specify -p relative, which will make UglifyJS figure out
|
||||||
relative, which will make UglifyJS figure out
|
itself the relative paths between original sources, the
|
||||||
itself the relative paths between original
|
source map and the output file. [string]
|
||||||
sources, the source map and the output file.
|
-o, --output Output file (default STDOUT).
|
||||||
-o, --output Output file (default STDOUT).
|
-b, --beautify Beautify output/specify output options. [string]
|
||||||
-b, --beautify Beautify output/specify output options.
|
-m, --mangle Mangle names/pass mangler options. [string]
|
||||||
-m, --mangle Mangle names/pass mangler options.
|
-r, --reserved Reserved names to exclude from mangling.
|
||||||
-r, --reserved Reserved names to exclude from mangling.
|
-c, --compress Enable compressor/pass compressor options. Pass options
|
||||||
-c, --compress Enable compressor/pass compressor options. Pass
|
like -c hoist_vars=false,if_return=false. Use -c with no
|
||||||
options like -c
|
argument to use the default compression options. [string]
|
||||||
hoist_vars=false,if_return=false. Use -c with
|
-d, --define Global definitions [string]
|
||||||
no argument to use the default compression
|
-e, --enclose Embed everything in a big function, with a configurable
|
||||||
options.
|
parameter/argument list. [string]
|
||||||
-d, --define Global definitions
|
--comments Preserve copyright comments in the output. By default this
|
||||||
-e, --enclose Embed everything in a big function, with a
|
works like Google Closure, keeping JSDoc-style comments
|
||||||
configurable parameter/argument list.
|
that contain "@license" or "@preserve". You can optionally
|
||||||
--comments Preserve copyright comments in the output. By
|
pass one of the following arguments to this flag:
|
||||||
default this works like Google Closure, keeping
|
- "all" to keep all comments
|
||||||
JSDoc-style comments that contain "@license" or
|
- a valid JS regexp (needs to start with a slash) to keep
|
||||||
"@preserve". You can optionally pass one of the
|
only comments that match.
|
||||||
following arguments to this flag:
|
Note that currently not *all* comments can be kept when
|
||||||
- "all" to keep all comments
|
compression is on, because of dead code removal or
|
||||||
- a valid JS regexp (needs to start with a
|
cascading statements into sequences. [string]
|
||||||
slash) to keep only comments that match.
|
--preamble Preamble to prepend to the output. You can use this to
|
||||||
Note that currently not *all* comments can be
|
insert a comment, for example for licensing information.
|
||||||
kept when compression is on, because of dead
|
This will not be parsed, but the source map will adjust
|
||||||
code removal or cascading statements into
|
for its presence.
|
||||||
sequences.
|
--stats Display operations run time on STDERR. [boolean]
|
||||||
--preamble Preamble to prepend to the output. You can use
|
--acorn Use Acorn for parsing. [boolean]
|
||||||
this to insert a comment, for example for
|
--spidermonkey Assume input files are SpiderMonkey AST format (as JSON).
|
||||||
licensing information. This will not be
|
[boolean]
|
||||||
parsed, but the source map will adjust for its
|
--self Build itself (UglifyJS2) as a library (implies
|
||||||
presence.
|
--wrap=UglifyJS --export-all) [boolean]
|
||||||
--stats Display operations run time on STDERR.
|
--wrap Embed everything in a big function, making the “exports”
|
||||||
--acorn Use Acorn for parsing.
|
and “global” variables available. You need to pass an
|
||||||
--spidermonkey Assume input files are SpiderMonkey AST format
|
argument to this option to specify the name that your
|
||||||
(as JSON).
|
module will take when included in, say, a browser.
|
||||||
--self Build itself (UglifyJS2) as a library (implies
|
[string]
|
||||||
--wrap=UglifyJS --export-all)
|
--export-all Only used when --wrap, this tells UglifyJS to add code to
|
||||||
--wrap Embed everything in a big function, making the
|
automatically export all globals. [boolean]
|
||||||
“exports” and “global” variables available. You
|
--lint Display some scope warnings [boolean]
|
||||||
need to pass an argument to this option to
|
-v, --verbose Verbose [boolean]
|
||||||
specify the name that your module will take
|
-V, --version Print version number and exit. [boolean]
|
||||||
when included in, say, a browser.
|
|
||||||
--export-all Only used when --wrap, this tells UglifyJS to
|
|
||||||
add code to automatically export all globals.
|
|
||||||
--lint Display some scope warnings
|
|
||||||
-v, --verbose Verbose
|
|
||||||
-V, --version Print version number and exit.
|
|
||||||
--noerr Don't throw an error for unknown options in -c,
|
|
||||||
-b or -m.
|
|
||||||
--bare-returns Allow return outside of functions. Useful when
|
|
||||||
minifying CommonJS modules.
|
|
||||||
--keep-fnames Do not mangle/drop function names. Useful for
|
|
||||||
code relying on Function.prototype.name.
|
|
||||||
--reserved-file File containing reserved names
|
|
||||||
--reserve-domprops Make (most?) DOM properties reserved for
|
|
||||||
--mangle-props
|
|
||||||
--mangle-props Mangle property names
|
|
||||||
--name-cache File to hold mangled names mappings
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Specify `--output` (`-o`) to declare the output file. Otherwise the output
|
Specify `--output` (`-o`) to declare the output file. Otherwise the output
|
||||||
@@ -206,69 +189,6 @@ comma-separated list of names. For example:
|
|||||||
|
|
||||||
to prevent the `require`, `exports` and `$` names from being changed.
|
to prevent the `require`, `exports` and `$` names from being changed.
|
||||||
|
|
||||||
### Mangling property names (`--mangle-props`)
|
|
||||||
|
|
||||||
**Note:** this will probably break your code. Mangling property names is a
|
|
||||||
separate step, different from variable name mangling. Pass
|
|
||||||
`--mangle-props`. It will mangle all properties that are seen in some
|
|
||||||
object literal, or that are assigned to. For example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var x = {
|
|
||||||
foo: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
x.bar = 2;
|
|
||||||
x["baz"] = 3;
|
|
||||||
x[condition ? "moo" : "boo"] = 4;
|
|
||||||
console.log(x.something());
|
|
||||||
```
|
|
||||||
|
|
||||||
In the above code, `foo`, `bar`, `baz`, `moo` and `boo` will be replaced
|
|
||||||
with single characters, while `something()` will be left as is.
|
|
||||||
|
|
||||||
In order for this to be of any use, we should avoid mangling standard JS
|
|
||||||
names. For instance, if your code would contain `x.length = 10`, then
|
|
||||||
`length` becomes a candidate for mangling and it will be mangled throughout
|
|
||||||
the code, regardless if it's being used as part of your own objects or
|
|
||||||
accessing an array's length. To avoid that, you can use `--reserved-file`
|
|
||||||
to pass a filename that should contain the names to be excluded from
|
|
||||||
mangling. This file can be used both for excluding variable names and
|
|
||||||
property names. It could look like this, for example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"vars": [ "define", "require", ... ],
|
|
||||||
"props": [ "length", "prototype", ... ]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`--reserved-file` can be an array of file names (either a single
|
|
||||||
comma-separated argument, or you can pass multiple `--reserved-file`
|
|
||||||
arguments) — in this case it will exclude names from all those files.
|
|
||||||
|
|
||||||
A default exclusion file is provided in `tools/domprops.json` which should
|
|
||||||
cover most standard JS and DOM properties defined in various browsers. Pass
|
|
||||||
`--reserve-domprops` to read that in.
|
|
||||||
|
|
||||||
When you compress multiple files using this option, in order for them to
|
|
||||||
work together in the end we need to ensure somehow that one property gets
|
|
||||||
mangled to the same name in all of them. For this, pass `--name-cache
|
|
||||||
filename.json` and UglifyJS will maintain these mappings in a file which can
|
|
||||||
then be reused. It should be initially empty. Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
rm -f /tmp/cache.json # start fresh
|
|
||||||
uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js
|
|
||||||
uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, `part1.js` and `part2.js` will be consistent with each other in terms
|
|
||||||
of mangled property names.
|
|
||||||
|
|
||||||
Using the name cache is not necessary if you compress all your files in a
|
|
||||||
single call to UglifyJS.
|
|
||||||
|
|
||||||
## Compressor options
|
## Compressor options
|
||||||
|
|
||||||
You need to pass `--compress` (`-c`) to enable the compressor. Optionally
|
You need to pass `--compress` (`-c`) to enable the compressor. Optionally
|
||||||
@@ -352,15 +272,14 @@ contrived cases, but should be fine for most code. You might want to try it
|
|||||||
on your own code, it should reduce the minified size. Here's what happens
|
on your own code, it should reduce the minified size. Here's what happens
|
||||||
when this flag is on:
|
when this flag is on:
|
||||||
|
|
||||||
- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]`
|
- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[1, 2, 3 ]`
|
||||||
- `new Object()` → `{}`
|
- `new Object()` → `{}`
|
||||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||||
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||||
- `typeof foo == "undefined"` → `foo === void 0`
|
- `typeof foo == "undefined"` → `foo === void 0`
|
||||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
||||||
scope; we do it because the variable name will be mangled, typically
|
scope; we do it because the variable name will be mangled, typically
|
||||||
reduced to a single character)
|
reduced to a single character).
|
||||||
- discards unused function arguments (affects `function.length`)
|
|
||||||
|
|
||||||
### Conditional compilation
|
### Conditional compilation
|
||||||
|
|
||||||
@@ -591,16 +510,6 @@ var result = UglifyJS.minify("compiled.js", {
|
|||||||
// same as before, it returns `code` and `map`
|
// same as before, it returns `code` and `map`
|
||||||
```
|
```
|
||||||
|
|
||||||
If your input source map is not in a file, you can pass it in as an object
|
|
||||||
using the `inSourceMap` argument:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var result = UglifyJS.minify("compiled.js", {
|
|
||||||
inSourceMap: JSON.parse(my_source_map_string),
|
|
||||||
outSourceMap: "minified.js.map"
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
The `inSourceMap` is only used if you also request `outSourceMap` (it makes
|
The `inSourceMap` is only used if you also request `outSourceMap` (it makes
|
||||||
no sense otherwise).
|
no sense otherwise).
|
||||||
|
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
#! /usr/bin/env node
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var U2 = require("../tools/node");
|
|
||||||
var fs = require("fs");
|
|
||||||
var yargs = require("yargs");
|
|
||||||
var ARGS = yargs
|
|
||||||
.describe("o", "Output file")
|
|
||||||
.argv;
|
|
||||||
var files = ARGS._.slice();
|
|
||||||
var output = {
|
|
||||||
vars: {},
|
|
||||||
props: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ARGS.o) try {
|
|
||||||
output = JSON.parse(fs.readFileSync(ARGS.o, "utf8"));
|
|
||||||
} catch(ex) {}
|
|
||||||
|
|
||||||
files.forEach(getProps);
|
|
||||||
|
|
||||||
if (ARGS.o) {
|
|
||||||
fs.writeFileSync(ARGS.o, JSON.stringify(output, null, 2), "utf8");
|
|
||||||
} else {
|
|
||||||
console.log("%s", JSON.stringify(output, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getProps(filename) {
|
|
||||||
var code = fs.readFileSync(filename, "utf8");
|
|
||||||
var ast = U2.parse(code);
|
|
||||||
|
|
||||||
ast.walk(new U2.TreeWalker(function(node){
|
|
||||||
if (node instanceof U2.AST_ObjectKeyVal) {
|
|
||||||
add(node.key);
|
|
||||||
}
|
|
||||||
else if (node instanceof U2.AST_ObjectProperty) {
|
|
||||||
add(node.key.name);
|
|
||||||
}
|
|
||||||
else if (node instanceof U2.AST_Dot) {
|
|
||||||
add(node.property);
|
|
||||||
}
|
|
||||||
else if (node instanceof U2.AST_Sub) {
|
|
||||||
addStrings(node.property);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
function addStrings(node) {
|
|
||||||
var out = {};
|
|
||||||
try {
|
|
||||||
(function walk(node){
|
|
||||||
node.walk(new U2.TreeWalker(function(node){
|
|
||||||
if (node instanceof U2.AST_Seq) {
|
|
||||||
walk(node.cdr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof U2.AST_String) {
|
|
||||||
add(node.value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof U2.AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add(name) {
|
|
||||||
output.props[name] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
68
bin/uglifyjs
68
bin/uglifyjs
@@ -67,10 +67,6 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
|
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
|
||||||
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
|
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
|
||||||
.describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
|
.describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
|
||||||
.describe("reserved-file", "File containing reserved names")
|
|
||||||
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
|
|
||||||
.describe("mangle-props", "Mangle property names")
|
|
||||||
.describe("name-cache", "File to hold mangled names mappings")
|
|
||||||
|
|
||||||
.alias("p", "prefix")
|
.alias("p", "prefix")
|
||||||
.alias("o", "output")
|
.alias("o", "output")
|
||||||
@@ -88,21 +84,13 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.string("source-map-root")
|
.string("source-map-root")
|
||||||
.string("source-map-url")
|
.string("source-map-url")
|
||||||
.string("b")
|
.string("b")
|
||||||
.string("beautify")
|
|
||||||
.string("m")
|
.string("m")
|
||||||
.string("mangle")
|
|
||||||
.string("c")
|
.string("c")
|
||||||
.string("compress")
|
|
||||||
.string("d")
|
.string("d")
|
||||||
.string("define")
|
|
||||||
.string("e")
|
.string("e")
|
||||||
.string("enclose")
|
|
||||||
.string("comments")
|
.string("comments")
|
||||||
.string("wrap")
|
.string("wrap")
|
||||||
.string("p")
|
.string("p")
|
||||||
.string("prefix")
|
|
||||||
.string("name-cache")
|
|
||||||
.array("reserved-file")
|
|
||||||
|
|
||||||
.boolean("expr")
|
.boolean("expr")
|
||||||
.boolean("source-map-include-sources")
|
.boolean("source-map-include-sources")
|
||||||
@@ -110,18 +98,14 @@ You need to pass an argument to this option to specify the name that your module
|
|||||||
.boolean("export-all")
|
.boolean("export-all")
|
||||||
.boolean("self")
|
.boolean("self")
|
||||||
.boolean("v")
|
.boolean("v")
|
||||||
.boolean("verbose")
|
|
||||||
.boolean("stats")
|
.boolean("stats")
|
||||||
.boolean("acorn")
|
.boolean("acorn")
|
||||||
.boolean("spidermonkey")
|
.boolean("spidermonkey")
|
||||||
.boolean("lint")
|
.boolean("lint")
|
||||||
.boolean("V")
|
.boolean("V")
|
||||||
.boolean("version")
|
|
||||||
.boolean("noerr")
|
.boolean("noerr")
|
||||||
.boolean("bare-returns")
|
.boolean("bare-returns")
|
||||||
.boolean("keep-fnames")
|
.boolean("keep-fnames")
|
||||||
.boolean("mangle-props")
|
|
||||||
.boolean("reserve-domprops")
|
|
||||||
|
|
||||||
.wrap(80)
|
.wrap(80)
|
||||||
|
|
||||||
@@ -160,15 +144,6 @@ if (ARGS.acorn) {
|
|||||||
var COMPRESS = getOptions("c", true);
|
var COMPRESS = getOptions("c", true);
|
||||||
var MANGLE = getOptions("m", true);
|
var MANGLE = getOptions("m", true);
|
||||||
var BEAUTIFY = getOptions("b", true);
|
var BEAUTIFY = getOptions("b", true);
|
||||||
var RESERVED = null;
|
|
||||||
|
|
||||||
if (ARGS.reserved_file) ARGS.reserved_file.forEach(function(filename){
|
|
||||||
RESERVED = UglifyJS.readReservedFile(filename, RESERVED);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ARGS.reserve_domprops) {
|
|
||||||
RESERVED = UglifyJS.readDefaultReservedFile(RESERVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.d) {
|
if (ARGS.d) {
|
||||||
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
||||||
@@ -178,19 +153,6 @@ if (ARGS.r) {
|
|||||||
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RESERVED && MANGLE) {
|
|
||||||
if (!MANGLE.except) MANGLE.except = RESERVED.vars;
|
|
||||||
else MANGLE.except = MANGLE.except.concat(RESERVED.vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
function readNameCache(key) {
|
|
||||||
return UglifyJS.readNameCache(ARGS.name_cache, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeNameCache(key, cache) {
|
|
||||||
return UglifyJS.writeNameCache(ARGS.name_cache, key, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.quotes === true) {
|
if (ARGS.quotes === true) {
|
||||||
ARGS.quotes = 3;
|
ARGS.quotes = 3;
|
||||||
}
|
}
|
||||||
@@ -215,7 +177,7 @@ if (ARGS.keep_fnames) {
|
|||||||
if (BEAUTIFY)
|
if (BEAUTIFY)
|
||||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
||||||
|
|
||||||
if (ARGS.comments != null) {
|
if (ARGS.comments) {
|
||||||
if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) {
|
if (/^\/.*\/[a-zA-Z]*$/.test(ARGS.comments)) {
|
||||||
var regex_pos = ARGS.comments.lastIndexOf("/");
|
var regex_pos = ARGS.comments.lastIndexOf("/");
|
||||||
try {
|
try {
|
||||||
@@ -357,11 +319,11 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ARGS.wrap != null) {
|
if (ARGS.wrap) {
|
||||||
TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all);
|
TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARGS.enclose != null) {
|
if (ARGS.enclose) {
|
||||||
var arg_parameter_list = ARGS.enclose;
|
var arg_parameter_list = ARGS.enclose;
|
||||||
if (arg_parameter_list === true) {
|
if (arg_parameter_list === true) {
|
||||||
arg_parameter_list = [];
|
arg_parameter_list = [];
|
||||||
@@ -372,22 +334,11 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
|
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARGS.mangle_props) (function(){
|
|
||||||
var reserved = RESERVED ? RESERVED.props : null;
|
|
||||||
var cache = readNameCache("props");
|
|
||||||
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
|
||||||
reserved: reserved,
|
|
||||||
cache: cache
|
|
||||||
});
|
|
||||||
writeNameCache("props", cache);
|
|
||||||
})();
|
|
||||||
|
|
||||||
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint;
|
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint;
|
||||||
var TL_CACHE = readNameCache("vars");
|
|
||||||
|
|
||||||
if (SCOPE_IS_NEEDED) {
|
if (SCOPE_IS_NEEDED) {
|
||||||
time_it("scope", function(){
|
time_it("scope", function(){
|
||||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8 });
|
||||||
if (ARGS.lint) {
|
if (ARGS.lint) {
|
||||||
TOPLEVEL.scope_warnings();
|
TOPLEVEL.scope_warnings();
|
||||||
}
|
}
|
||||||
@@ -402,20 +353,17 @@ async.eachLimit(files, 1, function (file, cb) {
|
|||||||
|
|
||||||
if (SCOPE_IS_NEEDED) {
|
if (SCOPE_IS_NEEDED) {
|
||||||
time_it("scope", function(){
|
time_it("scope", function(){
|
||||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8 });
|
||||||
if (MANGLE && !TL_CACHE) {
|
if (MANGLE) {
|
||||||
TOPLEVEL.compute_char_frequency(MANGLE);
|
TOPLEVEL.compute_char_frequency(MANGLE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MANGLE) time_it("mangle", function(){
|
if (MANGLE) time_it("mangle", function(){
|
||||||
MANGLE.cache = TL_CACHE;
|
|
||||||
TOPLEVEL.mangle_names(MANGLE);
|
TOPLEVEL.mangle_names(MANGLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
writeNameCache("vars", TL_CACHE);
|
|
||||||
|
|
||||||
if (ARGS.source_map_include_sources) {
|
if (ARGS.source_map_include_sources) {
|
||||||
for (var file in SOURCES_CONTENT) {
|
for (var file in SOURCES_CONTENT) {
|
||||||
if (SOURCES_CONTENT.hasOwnProperty(file)) {
|
if (SOURCES_CONTENT.hasOwnProperty(file)) {
|
||||||
@@ -470,9 +418,9 @@ function normalize(o) {
|
|||||||
|
|
||||||
function getOptions(x, constants) {
|
function getOptions(x, constants) {
|
||||||
x = ARGS[x];
|
x = ARGS[x];
|
||||||
if (x == null) return null;
|
if (!x) return null;
|
||||||
var ret = {};
|
var ret = {};
|
||||||
if (x !== "") {
|
if (x !== true) {
|
||||||
var ast;
|
var ast;
|
||||||
try {
|
try {
|
||||||
ast = UglifyJS.parse(x, { expression: true });
|
ast = UglifyJS.parse(x, { expression: true });
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ merge(Compressor.prototype, {
|
|||||||
seq = [];
|
seq = [];
|
||||||
};
|
};
|
||||||
statements.forEach(function(stat){
|
statements.forEach(function(stat){
|
||||||
if (stat instanceof AST_SimpleStatement && seq.length < 2000) seq.push(stat.body);
|
if (stat instanceof AST_SimpleStatement) seq.push(stat.body);
|
||||||
else push_seq(), ret.push(stat);
|
else push_seq(), ret.push(stat);
|
||||||
});
|
});
|
||||||
push_seq();
|
push_seq();
|
||||||
@@ -1086,7 +1086,7 @@ 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)) {
|
||||||
if (compressor.option("unsafe") && !compressor.option("keep_fargs")) {
|
if (!compressor.option("keep_fargs")) {
|
||||||
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
for (var a = node.argnames, i = a.length; --i >= 0;) {
|
||||||
var sym = a[i];
|
var sym = a[i];
|
||||||
if (sym.unreferenced()) {
|
if (sym.unreferenced()) {
|
||||||
@@ -2267,16 +2267,16 @@ merge(Compressor.prototype, {
|
|||||||
OPT(AST_Infinity, function (self, compressor) {
|
OPT(AST_Infinity, function (self, compressor) {
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator : '/',
|
operator : '/',
|
||||||
left : make_node(AST_Number, self, {value: 1}),
|
left : make_node(AST_Number, null, {value: 1}),
|
||||||
right : make_node(AST_Number, self, {value: 0})
|
right : make_node(AST_Number, null, {value: 0})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_NaN, function (self, compressor) {
|
OPT(AST_NaN, function (self, compressor) {
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator : '/',
|
operator : '/',
|
||||||
left : make_node(AST_Number, self, {value: 0}),
|
left : make_node(AST_Number, null, {value: 0}),
|
||||||
right : make_node(AST_Number, self, {value: 0})
|
right : make_node(AST_Number, null, {value: 0})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2343,7 +2343,6 @@ merge(Compressor.prototype, {
|
|||||||
&& alternative instanceof AST_Assign
|
&& alternative instanceof AST_Assign
|
||||||
&& consequent.operator == alternative.operator
|
&& consequent.operator == alternative.operator
|
||||||
&& consequent.left.equivalent_to(alternative.left)
|
&& consequent.left.equivalent_to(alternative.left)
|
||||||
&& !consequent.left.has_side_effects(compressor)
|
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
* Stuff like this:
|
* Stuff like this:
|
||||||
@@ -2481,7 +2480,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function literals_in_boolean_context(self, compressor) {
|
function literals_in_boolean_context(self, compressor) {
|
||||||
if (compressor.option("booleans") && compressor.in_boolean_context() && !self.has_side_effects(compressor)) {
|
if (compressor.option("booleans") && compressor.in_boolean_context()) {
|
||||||
return make_node(AST_True, self);
|
return make_node(AST_True, self);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -187,9 +187,8 @@ function parse_js_number(num) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function JS_Parse_Error(message, filename, line, col, pos) {
|
function JS_Parse_Error(message, line, col, pos) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.filename = filename;
|
|
||||||
this.line = line;
|
this.line = line;
|
||||||
this.col = col;
|
this.col = col;
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
@@ -201,7 +200,7 @@ JS_Parse_Error.prototype.toString = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function js_error(message, filename, line, col, pos) {
|
function js_error(message, filename, line, col, pos) {
|
||||||
throw new JS_Parse_Error(message, filename, line, col, pos);
|
throw new JS_Parse_Error(message, line, col, pos);
|
||||||
};
|
};
|
||||||
|
|
||||||
function is_token(token, type, val) {
|
function is_token(token, type, val) {
|
||||||
@@ -298,8 +297,7 @@ function tokenizer($TEXT, filename, html5_comments) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function skip_whitespace() {
|
function skip_whitespace() {
|
||||||
var ch;
|
while (WHITESPACE_CHARS(peek()))
|
||||||
while (WHITESPACE_CHARS(ch = peek()) || ch == "\u2028" || ch == "\u2029")
|
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
/***********************************************************************
|
|
||||||
|
|
||||||
A JavaScript tokenizer / parser / beautifier / compressor.
|
|
||||||
https://github.com/mishoo/UglifyJS2
|
|
||||||
|
|
||||||
-------------------------------- (C) ---------------------------------
|
|
||||||
|
|
||||||
Author: Mihai Bazon
|
|
||||||
<mihai.bazon@gmail.com>
|
|
||||||
http://mihai.bazon.net/blog
|
|
||||||
|
|
||||||
Distributed under the BSD license:
|
|
||||||
|
|
||||||
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials
|
|
||||||
provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGE.
|
|
||||||
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function find_builtins() {
|
|
||||||
var a = [];
|
|
||||||
[ Object, Array, Function, Number,
|
|
||||||
String, Boolean, Error, Math,
|
|
||||||
Date, RegExp
|
|
||||||
].forEach(function(ctor){
|
|
||||||
Object.getOwnPropertyNames(ctor).map(add);
|
|
||||||
if (ctor.prototype) {
|
|
||||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function add(name) {
|
|
||||||
push_uniq(a, name);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
|
||||||
options = defaults(options, {
|
|
||||||
reserved : null,
|
|
||||||
cache : null
|
|
||||||
});
|
|
||||||
|
|
||||||
var reserved = options.reserved;
|
|
||||||
if (reserved == null)
|
|
||||||
reserved = find_builtins();
|
|
||||||
|
|
||||||
var cache = options.cache;
|
|
||||||
if (cache == null) {
|
|
||||||
cache = {
|
|
||||||
cname: -1,
|
|
||||||
props: new Dictionary()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var names_to_mangle = [];
|
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
|
||||||
ast.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
|
||||||
add(node.key);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
|
||||||
// setter or getter, since KeyVal is handled above
|
|
||||||
add(node.key.name);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Dot) {
|
|
||||||
if (this.parent() instanceof AST_Assign) {
|
|
||||||
add(node.property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Sub) {
|
|
||||||
if (this.parent() instanceof AST_Assign) {
|
|
||||||
addStrings(node.property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
// step 2: transform the tree, renaming properties
|
|
||||||
return ast.transform(new TreeTransformer(function(node){
|
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
|
||||||
if (should_mangle(node.key)) {
|
|
||||||
node.key = mangle(node.key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
|
||||||
// setter or getter
|
|
||||||
if (should_mangle(node.key.name)) {
|
|
||||||
node.key.name = mangle(node.key.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Dot) {
|
|
||||||
if (should_mangle(node.property)) {
|
|
||||||
node.property = mangle(node.property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Sub) {
|
|
||||||
node.property = mangleStrings(node.property);
|
|
||||||
}
|
|
||||||
// else if (node instanceof AST_String) {
|
|
||||||
// if (should_mangle(node.value)) {
|
|
||||||
// AST_Node.warn(
|
|
||||||
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
|
||||||
// file : node.start.file,
|
|
||||||
// line : node.start.line,
|
|
||||||
// col : node.start.col,
|
|
||||||
// prop : node.value
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}));
|
|
||||||
|
|
||||||
// only function declarations after this line
|
|
||||||
|
|
||||||
function can_mangle(name) {
|
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
|
||||||
if (/^[0-9.]+$/.test(name)) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function should_mangle(name) {
|
|
||||||
return cache.props.has(name)
|
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function add(name) {
|
|
||||||
if (can_mangle(name))
|
|
||||||
push_uniq(names_to_mangle, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangle(name) {
|
|
||||||
var mangled = cache.props.get(name);
|
|
||||||
if (!mangled) {
|
|
||||||
do {
|
|
||||||
mangled = base54(++cache.cname);
|
|
||||||
} while (!can_mangle(mangled));
|
|
||||||
cache.props.set(name, mangled);
|
|
||||||
}
|
|
||||||
return mangled;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addStrings(node) {
|
|
||||||
var out = {};
|
|
||||||
try {
|
|
||||||
(function walk(node){
|
|
||||||
node.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_Seq) {
|
|
||||||
walk(node.cdr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_String) {
|
|
||||||
add(node.value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangleStrings(node) {
|
|
||||||
return node.transform(new TreeTransformer(function(node){
|
|
||||||
if (node instanceof AST_Seq) {
|
|
||||||
node.cdr = mangleStrings(node.cdr);
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_String) {
|
|
||||||
if (should_mangle(node.value)) {
|
|
||||||
node.value = mangle(node.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Conditional) {
|
|
||||||
node.consequent = mangleStrings(node.consequent);
|
|
||||||
node.alternative = mangleStrings(node.alternative);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
29
lib/scope.js
29
lib/scope.js
@@ -67,26 +67,18 @@ SymbolDef.prototype = {
|
|||||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
|| this.orig[0] instanceof AST_SymbolDefun));
|
||||||
},
|
},
|
||||||
mangle: function(options) {
|
mangle: function(options) {
|
||||||
var cache = options.cache && options.cache.props;
|
if (!this.mangled_name && !this.unmangleable(options)) {
|
||||||
if (this.global && cache && cache.has(this.name)) {
|
|
||||||
this.mangled_name = cache.get(this.name);
|
|
||||||
}
|
|
||||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
|
||||||
var s = this.scope;
|
var s = this.scope;
|
||||||
if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda)
|
if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda)
|
||||||
s = s.parent_scope;
|
s = s.parent_scope;
|
||||||
this.mangled_name = s.next_mangled(options, this);
|
this.mangled_name = s.next_mangled(options, this);
|
||||||
if (this.global && cache) {
|
|
||||||
cache.set(this.name, this.mangled_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
screw_ie8: false,
|
screw_ie8: false
|
||||||
cache: null
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
@@ -191,10 +183,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
this.cname = options.cache.cname;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
||||||
@@ -356,15 +344,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
// the AST_SymbolDeclaration that it points to).
|
// the AST_SymbolDeclaration that it points to).
|
||||||
var lname = -1;
|
var lname = -1;
|
||||||
var to_mangle = [];
|
var to_mangle = [];
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
this.globals.each(function(symbol){
|
|
||||||
if (options.except.indexOf(symbol.name) < 0) {
|
|
||||||
to_mangle.push(symbol);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node instanceof AST_LabeledStatement) {
|
if (node instanceof AST_LabeledStatement) {
|
||||||
// lname is incremented when we get to the AST_Label
|
// lname is incremented when we get to the AST_Label
|
||||||
@@ -399,10 +378,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
});
|
});
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
options.cache.cname = this.cname;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||||
|
|||||||
12
lib/utils.js
12
lib/utils.js
@@ -106,12 +106,10 @@ function defaults(args, defs, croak) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function merge(obj, ext) {
|
function merge(obj, ext) {
|
||||||
var count = 0;
|
|
||||||
for (var i in ext) if (ext.hasOwnProperty(i)) {
|
for (var i in ext) if (ext.hasOwnProperty(i)) {
|
||||||
obj[i] = ext[i];
|
obj[i] = ext[i];
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
return count;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
function noop() {};
|
function noop() {};
|
||||||
@@ -300,11 +298,5 @@ Dictionary.prototype = {
|
|||||||
for (var i in this._values)
|
for (var i in this._values)
|
||||||
ret.push(f(this._values[i], i.substr(1)));
|
ret.push(f(this._values[i], i.substr(1)));
|
||||||
return ret;
|
return ret;
|
||||||
},
|
}
|
||||||
toObject: function() { return this._values }
|
|
||||||
};
|
|
||||||
Dictionary.fromObject = function(obj) {
|
|
||||||
var dict = new Dictionary();
|
|
||||||
dict._size = merge(dict._values, obj);
|
|
||||||
return dict;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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.20",
|
"version": "2.4.17",
|
||||||
"engines": { "node" : ">=0.4.0" },
|
"engines": { "node" : ">=0.4.0" },
|
||||||
"maintainers": [{
|
"maintainers": [{
|
||||||
"name": "Mihai Bazon",
|
"name": "Mihai Bazon",
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async" : "~0.2.6",
|
"async" : "~0.2.6",
|
||||||
"source-map" : "0.1.34",
|
"source-map" : "0.1.34",
|
||||||
"yargs": "~3.5.4",
|
"yargs": "~1.3.3",
|
||||||
"uglify-to-browserify": "~1.0.0"
|
"uglify-to-browserify": "~1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -86,9 +86,7 @@ ifs_4: {
|
|||||||
x(foo)[10].bar.baz = something_else();
|
x(foo)[10].bar.baz = something_else();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
foo && bar
|
x(foo)[10].bar.baz = (foo && bar) ? something() : something_else();
|
||||||
? x(foo)[10].bar.baz = something()
|
|
||||||
: x(foo)[10].bar.baz = something_else();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +133,6 @@ ifs_6: {
|
|||||||
comparisons: true
|
comparisons: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x;
|
|
||||||
if (!foo && !bar && !baz && !boo) {
|
if (!foo && !bar && !baz && !boo) {
|
||||||
x = 10;
|
x = 10;
|
||||||
} else {
|
} else {
|
||||||
@@ -143,7 +140,6 @@ ifs_6: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x;
|
|
||||||
x = foo || bar || baz || boo ? 20 : 10;
|
x = foo || bar || baz || boo ? 20 : 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +165,6 @@ cond_2: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x;
|
|
||||||
if (some_condition()) {
|
if (some_condition()) {
|
||||||
x = new FooBar(1);
|
x = new FooBar(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -177,7 +172,6 @@ cond_2: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x;
|
|
||||||
x = new FooBar(some_condition() ? 1 : 2);
|
x = new FooBar(some_condition() ? 1 : 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,7 +303,6 @@ cond_7_1: {
|
|||||||
evaluate : true
|
evaluate : true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x;
|
|
||||||
// access to global should be assumed to have side effects
|
// access to global should be assumed to have side effects
|
||||||
if (y) {
|
if (y) {
|
||||||
x = 1+1;
|
x = 1+1;
|
||||||
@@ -318,7 +311,6 @@ cond_7_1: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x;
|
|
||||||
x = (y, 2);
|
x = (y, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,7 +321,6 @@ cond_8: {
|
|||||||
evaluate : true
|
evaluate : true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var a;
|
|
||||||
// compress these
|
// compress these
|
||||||
a = condition ? true : false;
|
a = condition ? true : false;
|
||||||
|
|
||||||
@@ -364,7 +355,6 @@ cond_8: {
|
|||||||
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
|
||||||
a = !!condition;
|
a = !!condition;
|
||||||
a = !condition;
|
a = !condition;
|
||||||
a = !!condition();
|
a = !!condition();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
unused_funarg_1: {
|
unused_funarg_1: {
|
||||||
options = { unused: true, unsafe: true };
|
options = { unused: true };
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, c, d, e) {
|
function f(a, b, c, d, e) {
|
||||||
return a + b;
|
return a + b;
|
||||||
@@ -13,7 +13,7 @@ unused_funarg_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unused_funarg_2: {
|
unused_funarg_2: {
|
||||||
options = { unused: true, unsafe: true };
|
options = { unused: true };
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, c, d, e) {
|
function f(a, b, c, d, e) {
|
||||||
return a + c;
|
return a + c;
|
||||||
@@ -165,7 +165,7 @@ used_var_in_catch: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keep_fnames: {
|
keep_fnames: {
|
||||||
options = { unused: true, keep_fnames: true, unsafe: true };
|
options = { unused: true, keep_fnames: true };
|
||||||
input: {
|
input: {
|
||||||
function foo() {
|
function foo() {
|
||||||
return function bar(baz) {};
|
return function bar(baz) {};
|
||||||
|
|||||||
5603
tools/domprops.json
5603
tools/domprops.json
File diff suppressed because it is too large
Load Diff
@@ -33,8 +33,7 @@ var FILES = exports.FILES = [
|
|||||||
"../lib/output.js",
|
"../lib/output.js",
|
||||||
"../lib/compress.js",
|
"../lib/compress.js",
|
||||||
"../lib/sourcemap.js",
|
"../lib/sourcemap.js",
|
||||||
"../lib/mozilla-ast.js",
|
"../lib/mozilla-ast.js"
|
||||||
"../lib/propmangle.js"
|
|
||||||
].map(function(file){
|
].map(function(file){
|
||||||
return fs.realpathSync(path.join(path.dirname(__filename), file));
|
return fs.realpathSync(path.join(path.dirname(__filename), file));
|
||||||
});
|
});
|
||||||
@@ -193,63 +192,3 @@ exports.describe_ast = function() {
|
|||||||
doitem(UglifyJS.AST_Node);
|
doitem(UglifyJS.AST_Node);
|
||||||
return out + "";
|
return out + "";
|
||||||
};
|
};
|
||||||
|
|
||||||
function readReservedFile(filename, reserved) {
|
|
||||||
if (!reserved) {
|
|
||||||
reserved = { vars: [], props: [] };
|
|
||||||
}
|
|
||||||
var data = fs.readFileSync(filename, "utf8");
|
|
||||||
data = JSON.parse(data);
|
|
||||||
if (data.vars) {
|
|
||||||
data.vars.forEach(function(name){
|
|
||||||
UglifyJS.push_uniq(reserved.vars, name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (data.props) {
|
|
||||||
data.props.forEach(function(name){
|
|
||||||
UglifyJS.push_uniq(reserved.props, name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return reserved;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.readReservedFile = readReservedFile;
|
|
||||||
|
|
||||||
exports.readDefaultReservedFile = function(reserved) {
|
|
||||||
return readReservedFile(path.join(__dirname, "domprops.json"), reserved);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.readNameCache = function(filename, key) {
|
|
||||||
var cache = null;
|
|
||||||
if (filename) {
|
|
||||||
try {
|
|
||||||
var cache = fs.readFileSync(filename, "utf8");
|
|
||||||
cache = JSON.parse(cache)[key];
|
|
||||||
if (!cache) throw "init";
|
|
||||||
cache.props = UglifyJS.Dictionary.fromObject(cache.props);
|
|
||||||
} catch(ex) {
|
|
||||||
cache = {
|
|
||||||
cname: -1,
|
|
||||||
props: new UglifyJS.Dictionary()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cache;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.writeNameCache = function(filename, key, cache) {
|
|
||||||
if (filename) {
|
|
||||||
var data;
|
|
||||||
try {
|
|
||||||
data = fs.readFileSync(filename, "utf8");
|
|
||||||
data = JSON.parse(data);
|
|
||||||
} catch(ex) {
|
|
||||||
data = {};
|
|
||||||
}
|
|
||||||
data[key] = {
|
|
||||||
cname: cache.cname,
|
|
||||||
props: cache.props.toObject()
|
|
||||||
};
|
|
||||||
fs.writeFileSync(filename, JSON.stringify(data, null, 2), "utf8");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script>(function(){
|
|
||||||
var props = {};
|
|
||||||
|
|
||||||
function addObject(obj) {
|
|
||||||
if (obj == null) return;
|
|
||||||
try {
|
|
||||||
Object.getOwnPropertyNames(obj).forEach(add);
|
|
||||||
} 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) {
|
|
||||||
props[name] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.getOwnPropertyNames(window).forEach(function(thing){
|
|
||||||
addObject(window[thing]);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
addObject(new Event("click"));
|
|
||||||
addObject(new Event("contextmenu"));
|
|
||||||
addObject(new Event("mouseup"));
|
|
||||||
addObject(new Event("mousedown"));
|
|
||||||
addObject(new Event("keydown"));
|
|
||||||
addObject(new Event("keypress"));
|
|
||||||
addObject(new Event("keyup"));
|
|
||||||
} catch(ex) {}
|
|
||||||
|
|
||||||
var ta = document.createElement("textarea");
|
|
||||||
ta.style.width = "100%";
|
|
||||||
ta.style.height = "20em";
|
|
||||||
ta.style.boxSizing = "border-box";
|
|
||||||
<!-- ta.value = Object.keys(props).sort(cmp).map(function(name){ -->
|
|
||||||
<!-- return JSON.stringify(name); -->
|
|
||||||
<!-- }).join(",\n"); -->
|
|
||||||
ta.value = JSON.stringify({
|
|
||||||
vars: [],
|
|
||||||
props: Object.keys(props).sort(cmp)
|
|
||||||
}, null, 2);
|
|
||||||
document.body.appendChild(ta);
|
|
||||||
|
|
||||||
function cmp(a, b) {
|
|
||||||
a = a.toLowerCase();
|
|
||||||
b = b.toLowerCase();
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
}
|
|
||||||
})();</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user