uglifier 2.7.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/.travis.yml +9 -8
- data/.yardopts +4 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +1 -5
- data/README.md +19 -10
- data/Rakefile +1 -26
- data/lib/uglifier.js +111 -0
- data/lib/uglifier.rb +109 -93
- data/lib/uglifier/version.rb +1 -1
- data/lib/uglify.js +3015 -2102
- data/spec/source_map_spec.rb +152 -36
- data/spec/spec_helper.rb +11 -2
- data/spec/uglifier_spec.rb +95 -18
- data/uglifier.gemspec +3 -5
- metadata +16 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 965824e428764606cd1617e6e72b9ab0ad912b7b
|
4
|
+
data.tar.gz: 996b18eac0ad32e9c9ad8b31e7a8ab90c0208039
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d41ff9576c911132ce28f20b530d1c3b925e6caa5416884608e69cbbbe25b1fda4a4a27fb267b320633b6d9bb34c632c9e1c60c5be6b7663309aecb0a17b93df
|
7
|
+
data.tar.gz: 748763a30cd991eec4c52648c0af2a40ae199646cb92b0dc481ff504b1ef388dbfd385817011ca5489dd4ad5f37d0dff0c6d0e52a39fc41b61be6d859946677a
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -2,12 +2,13 @@ sudo: false
|
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
4
|
rvm:
|
5
|
-
- 1.8.7
|
6
5
|
- 1.9.3
|
7
6
|
- 2.0.0
|
8
|
-
- 2.1.
|
9
|
-
- 2.2.
|
10
|
-
-
|
7
|
+
- 2.1.7
|
8
|
+
- 2.2.3
|
9
|
+
- 2.3.0
|
10
|
+
- jruby-19mode
|
11
|
+
- jruby-9.0.4.0
|
11
12
|
- rbx-2
|
12
13
|
git:
|
13
14
|
submodules: false
|
@@ -15,16 +16,16 @@ gemfile:
|
|
15
16
|
- Gemfile
|
16
17
|
matrix:
|
17
18
|
include:
|
18
|
-
- rvm: 2.
|
19
|
+
- rvm: 2.3.0
|
19
20
|
gemfile: gemfiles/rubyracer
|
20
|
-
- rvm: 2.1.
|
21
|
+
- rvm: 2.1.7
|
21
22
|
gemfile: gemfiles/rubyracer
|
22
23
|
- rvm: jruby-19mode
|
23
24
|
gemfile: gemfiles/rubyrhino
|
24
|
-
- rvm: 2.
|
25
|
+
- rvm: 2.3.0
|
25
26
|
gemfile: gemfiles/alaska
|
26
27
|
env: ALASKA=1
|
27
28
|
allow_failures:
|
28
|
-
- rvm: 2.
|
29
|
+
- rvm: 2.3.0
|
29
30
|
gemfile: gemfiles/alaska
|
30
31
|
env: ALASKA=1
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## 3.0.0 (22 March 2016)
|
2
|
+
|
3
|
+
- drop support for Ruby 1.8
|
4
|
+
- remove json as dependency
|
5
|
+
- discard unused function arguments only in unsafe mode
|
6
|
+
- add `keep_fnames` option to preserve function names in compressed code
|
7
|
+
- add `collapse_vars` option to collapse single-use variables
|
8
|
+
- backwards incompatible changes to source map options
|
9
|
+
- support for inline base64 encoded source maps
|
10
|
+
- mangle property names option (disabled by default)
|
11
|
+
- update UglifyJS to 2.6.2
|
12
|
+
|
1
13
|
## 2.7.2 (26 August 2015)
|
2
14
|
|
3
15
|
- update UglifyJS to 2.4.24
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
# Uglifier
|
1
|
+
# Uglifier
|
2
2
|
|
3
3
|
Ruby wrapper for [UglifyJS](https://github.com/mishoo/UglifyJS2) JavaScript compressor.
|
4
4
|
|
5
|
+
[](https://travis-ci.org/lautis/uglifier)
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
Uglifier is available as a ruby gem.
|
@@ -65,6 +67,9 @@ Available options and their defaults are
|
|
65
67
|
:sort => false, # Assign shorter names to most frequently used variables. Often results in bigger output after gzip.
|
66
68
|
:toplevel => false # Mangle names declared in the toplevel scope
|
67
69
|
}, # Mangle variable and function names, set to false to skip mangling
|
70
|
+
:mangle_properties => {
|
71
|
+
:regex => nil # A regular expression to filter property names to be mangled
|
72
|
+
} # Mangle property names, disabled by default
|
68
73
|
:compress => {
|
69
74
|
:sequences => true, # Allow statements to be joined by commas
|
70
75
|
:properties => true, # Rewrite property access using the dot notation
|
@@ -82,22 +87,26 @@ Available options and their defaults are
|
|
82
87
|
:if_return => true, # Optimizations for if/return and if/continue
|
83
88
|
:join_vars => true, # Join consecutive var statements
|
84
89
|
:cascade => true, # Cascade sequences
|
90
|
+
:collapse_vars => false, # Collapse single-use var and const definitions when possible.
|
85
91
|
:negate_iife => true, # Negate immediately invoked function expressions to avoid extra parens
|
86
92
|
:pure_getters => false, # Assume that object property access does not have any side-effects
|
87
93
|
:pure_funcs => nil, # List of functions without side-effects. Can safely discard function calls when the result value is not used
|
88
94
|
:drop_console => false, # Drop calls to console.* functions
|
89
|
-
:angular => false
|
90
|
-
:keep_fargs => false
|
95
|
+
:angular => false, # Process @ngInject annotations
|
96
|
+
:keep_fargs => false, # Preserve unused function arguments
|
97
|
+
:keep_fnames => false # Preserve function names
|
91
98
|
}, # Apply transformations to code, set to false to skip
|
92
99
|
:define => {}, # Define values for symbol replacement
|
93
100
|
:enclose => false, # Enclose in output function wrapper, define replacements as key-value pairs
|
94
|
-
:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
+
:source_map => {
|
102
|
+
:map_url => false, # Url for source mapping to be appended in minified source
|
103
|
+
:url => false, # Url for original source to be appended in minified source
|
104
|
+
:sources_content => false, # Include original source content in map
|
105
|
+
:filename => nil, # The filename of the input file
|
106
|
+
:root => nil, # The URL of the directory which contains :filename
|
107
|
+
:output_filename => nil, # The filename or URL where the minified output can be found
|
108
|
+
:input_source_map => nil # The contents of the source map describing the input
|
109
|
+
}
|
101
110
|
}
|
102
111
|
```
|
103
112
|
|
data/Rakefile
CHANGED
@@ -1,40 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
|
-
require 'bundler'
|
5
3
|
require 'bundler/gem_tasks'
|
6
|
-
|
7
|
-
begin
|
8
|
-
Bundler.setup(:default, :development)
|
9
|
-
rescue Bundler::BundlerError => e
|
10
|
-
$stderr.puts e.message
|
11
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
12
|
-
exit e.status_code
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'rake'
|
16
|
-
|
17
|
-
require 'rspec/core'
|
18
4
|
require 'rspec/core/rake_task'
|
19
5
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
20
6
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
21
7
|
end
|
22
8
|
|
23
|
-
require 'rdoc/task'
|
24
|
-
Rake::RDocTask.new do |rdoc|
|
25
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
26
|
-
|
27
|
-
rdoc.rdoc_dir = 'rdoc'
|
28
|
-
rdoc.title = "uglifier #{version}"
|
29
|
-
rdoc.rdoc_files.include('README*')
|
30
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
31
|
-
end
|
32
|
-
|
33
9
|
desc "Rebuild lib/uglify.js"
|
34
10
|
task :js do
|
35
11
|
cd 'vendor/source-map/' do
|
36
12
|
`npm install`
|
37
|
-
`node Makefile.dryice.js`
|
38
13
|
end
|
39
14
|
|
40
15
|
cd 'vendor/uglifyjs/' do
|
@@ -54,7 +29,7 @@ end
|
|
54
29
|
begin
|
55
30
|
require 'rubocop/rake_task'
|
56
31
|
RuboCop::RakeTask.new(:rubocop)
|
57
|
-
task :default => [:spec]
|
32
|
+
task :default => [:rubocop, :spec]
|
58
33
|
rescue LoadError
|
59
34
|
task :default => [:spec]
|
60
35
|
end
|
data/lib/uglifier.js
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
function comments(option) {
|
2
|
+
if (Object.prototype.toString.call(option) === '[object Array]') {
|
3
|
+
return new RegExp(option[0], option[1]);
|
4
|
+
} else if (option == "jsdoc") {
|
5
|
+
return function(node, comment) {
|
6
|
+
if (comment.type == "comment2") {
|
7
|
+
return /@preserve|@license|@cc_on/i.test(comment.value);
|
8
|
+
} else {
|
9
|
+
return false;
|
10
|
+
}
|
11
|
+
};
|
12
|
+
} else {
|
13
|
+
return option;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
function readNameCache(key) {
|
18
|
+
return UglifyJS.readNameCache(null, key);
|
19
|
+
}
|
20
|
+
|
21
|
+
function writeNameCache(key, cache) {
|
22
|
+
return UglifyJS.writeNameCache(null, key, cache);
|
23
|
+
}
|
24
|
+
|
25
|
+
function regexOption(options) {
|
26
|
+
if (typeof options === 'object' && options.regex) {
|
27
|
+
return new RegExp(options.regex[0], options.regex[1]);
|
28
|
+
} else {
|
29
|
+
return null;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
function parse(source, options) {
|
34
|
+
var ast = UglifyJS.parse(source, options.parse_options);
|
35
|
+
ast.figure_out_scope();
|
36
|
+
|
37
|
+
if (options.compress) {
|
38
|
+
var compressor = UglifyJS.Compressor(options.compress);
|
39
|
+
ast = ast.transform(compressor);
|
40
|
+
ast.figure_out_scope();
|
41
|
+
}
|
42
|
+
|
43
|
+
if (options.mangle) {
|
44
|
+
ast.compute_char_frequency();
|
45
|
+
ast.mangle_names(options.mangle);
|
46
|
+
}
|
47
|
+
|
48
|
+
if (options.mangle_properties) {
|
49
|
+
var regex = regexOption(options.mangle_properties);
|
50
|
+
UglifyJS.mangle_properties(ast, {
|
51
|
+
reserved: [],
|
52
|
+
only_cache: false,
|
53
|
+
regex: regex
|
54
|
+
});
|
55
|
+
}
|
56
|
+
|
57
|
+
if (options.enclose) {
|
58
|
+
ast = ast.wrap_enclose(options.enclose);
|
59
|
+
}
|
60
|
+
return ast;
|
61
|
+
}
|
62
|
+
|
63
|
+
function copySourcesContent(sourceMap, options) {
|
64
|
+
sourceMap.get().setSourceContent(options.parse_options.filename, options.source);
|
65
|
+
|
66
|
+
var original = options.source_map_options.orig;
|
67
|
+
|
68
|
+
if (original && original.sources && original.sourcesContent) {
|
69
|
+
for(var i = 0; i < original.sources.length; i++) {
|
70
|
+
sourceMap.get().setSourceContent(original.sources[i], original.sourcesContent[i]);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
function uglifier(options) {
|
76
|
+
var source = options.source;
|
77
|
+
var ast = parse(source, options);
|
78
|
+
var source_map;
|
79
|
+
|
80
|
+
var gen_code_options = options.output;
|
81
|
+
gen_code_options.comments = comments(options.output.comments);
|
82
|
+
|
83
|
+
if (options.generate_map) {
|
84
|
+
source_map = UglifyJS.SourceMap(options.source_map_options);
|
85
|
+
gen_code_options.source_map = source_map;
|
86
|
+
|
87
|
+
if (options.source_map_options.sources_content) {
|
88
|
+
copySourcesContent(source_map, options);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
var stream = UglifyJS.OutputStream(gen_code_options);
|
93
|
+
ast.print(stream);
|
94
|
+
|
95
|
+
if (options.source_map_options.map_url) {
|
96
|
+
stream += "\n//# sourceMappingURL=" + options.source_map_options.map_url;
|
97
|
+
}
|
98
|
+
|
99
|
+
if (options.source_map_options.url) {
|
100
|
+
stream += "\n//# sourceURL=" + options.source_map_options.url;
|
101
|
+
}
|
102
|
+
|
103
|
+
if (options.generate_map) {
|
104
|
+
if (options.source_map_options.sources_content) {
|
105
|
+
source_map.get().setSourceContent(options.parse_options.filename, options.source);
|
106
|
+
}
|
107
|
+
return [stream.toString(), source_map.toString()];
|
108
|
+
} else {
|
109
|
+
return stream.toString();
|
110
|
+
}
|
111
|
+
}
|
data/lib/uglifier.rb
CHANGED
@@ -1,78 +1,14 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require "execjs"
|
4
3
|
require "json"
|
4
|
+
require "base64"
|
5
|
+
require "execjs"
|
5
6
|
require "uglifier/version"
|
6
7
|
|
7
8
|
# A wrapper around the UglifyJS interface
|
8
9
|
class Uglifier
|
9
10
|
# Error class for compilation errors.
|
10
11
|
Error = ExecJS::Error
|
11
|
-
# JavaScript code to call UglifyJS
|
12
|
-
JS = <<-JS
|
13
|
-
(function(options) {
|
14
|
-
function comments(option) {
|
15
|
-
if (Object.prototype.toString.call(option) === '[object Array]') {
|
16
|
-
return new RegExp(option[0], option[1]);
|
17
|
-
} else if (option == "jsdoc") {
|
18
|
-
return function(node, comment) {
|
19
|
-
if (comment.type == "comment2") {
|
20
|
-
return /@preserve|@license|@cc_on/i.test(comment.value);
|
21
|
-
} else {
|
22
|
-
return false;
|
23
|
-
}
|
24
|
-
}
|
25
|
-
} else {
|
26
|
-
return option;
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
var source = options.source;
|
31
|
-
var ast = UglifyJS.parse(source, options.parse_options);
|
32
|
-
ast.figure_out_scope();
|
33
|
-
|
34
|
-
if (options.compress) {
|
35
|
-
var compressor = UglifyJS.Compressor(options.compress);
|
36
|
-
ast = ast.transform(compressor);
|
37
|
-
ast.figure_out_scope();
|
38
|
-
}
|
39
|
-
|
40
|
-
if (options.mangle) {
|
41
|
-
ast.compute_char_frequency();
|
42
|
-
ast.mangle_names(options.mangle);
|
43
|
-
}
|
44
|
-
|
45
|
-
if (options.enclose) {
|
46
|
-
ast = ast.wrap_enclose(options.enclose);
|
47
|
-
}
|
48
|
-
|
49
|
-
var gen_code_options = options.output;
|
50
|
-
gen_code_options.comments = comments(options.output.comments);
|
51
|
-
|
52
|
-
if (options.generate_map) {
|
53
|
-
var source_map = UglifyJS.SourceMap(options.source_map_options);
|
54
|
-
gen_code_options.source_map = source_map;
|
55
|
-
}
|
56
|
-
|
57
|
-
var stream = UglifyJS.OutputStream(gen_code_options);
|
58
|
-
|
59
|
-
ast.print(stream);
|
60
|
-
|
61
|
-
if (options.source_map_options.map_url) {
|
62
|
-
stream += "\\n//# sourceMappingURL=" + options.source_map_options.map_url;
|
63
|
-
}
|
64
|
-
|
65
|
-
if (options.source_map_options.url) {
|
66
|
-
stream += "\\n//# sourceURL=" + options.source_map_options.url;
|
67
|
-
}
|
68
|
-
|
69
|
-
if (options.generate_map) {
|
70
|
-
return [stream.toString(), source_map.toString()];
|
71
|
-
} else {
|
72
|
-
return stream.toString();
|
73
|
-
}
|
74
|
-
})
|
75
|
-
JS
|
76
12
|
|
77
13
|
# UglifyJS source path
|
78
14
|
SourcePath = File.expand_path("../uglify.js", __FILE__)
|
@@ -80,6 +16,8 @@ class Uglifier
|
|
80
16
|
ES5FallbackPath = File.expand_path("../es5.js", __FILE__)
|
81
17
|
# String.split shim source path
|
82
18
|
SplitFallbackPath = File.expand_path("../split.js", __FILE__)
|
19
|
+
# UglifyJS wrapper path
|
20
|
+
UglifyJSWrapperPath = File.expand_path("../uglifier.js", __FILE__)
|
83
21
|
|
84
22
|
# Default options for compilation
|
85
23
|
DEFAULTS = {
|
@@ -104,8 +42,10 @@ class Uglifier
|
|
104
42
|
:eval => false, # Mangle names when eval of when is used in scope
|
105
43
|
:except => ["$super"], # Argument names to be excluded from mangling
|
106
44
|
:sort => false, # Assign shorter names to most frequently used variables. Often results in bigger output after gzip.
|
107
|
-
:toplevel => false # Mangle names declared in the toplevel scope
|
45
|
+
:toplevel => false, # Mangle names declared in the toplevel scope
|
46
|
+
:properties => false # Mangle property names
|
108
47
|
}, # Mangle variable and function names, set to false to skip mangling
|
48
|
+
:mangle_properties => false, # Mangle property names
|
109
49
|
:compress => {
|
110
50
|
:sequences => true, # Allow statements to be joined by commas
|
111
51
|
:properties => true, # Rewrite property access using the dot notation
|
@@ -123,23 +63,37 @@ class Uglifier
|
|
123
63
|
:if_return => true, # Optimizations for if/return and if/continue
|
124
64
|
:join_vars => true, # Join consecutive var statements
|
125
65
|
:cascade => true, # Cascade sequences
|
66
|
+
:collapse_vars => false, # Collapse single-use var and const definitions when possible.
|
126
67
|
:negate_iife => true, # Negate immediately invoked function expressions to avoid extra parens
|
127
68
|
:pure_getters => false, # Assume that object property access does not have any side-effects
|
128
69
|
:pure_funcs => nil, # List of functions without side-effects. Can safely discard function calls when the result value is not used
|
129
70
|
:drop_console => false, # Drop calls to console.* functions
|
130
71
|
:angular => false, # Process @ngInject annotations
|
131
|
-
:keep_fargs => false # Preserve unused function arguments
|
72
|
+
:keep_fargs => false, # Preserve unused function arguments
|
73
|
+
:keep_fnames => false # Preserve function names
|
132
74
|
}, # Apply transformations to code, set to false to skip
|
133
75
|
:define => {}, # Define values for symbol replacement
|
134
76
|
:enclose => false, # Enclose in output function wrapper, define replacements as key-value pairs
|
135
|
-
:source_filename => nil, # The filename of the input file
|
136
|
-
:source_root => nil, # The URL of the directory which contains :source_filename
|
137
|
-
:output_filename => nil, # The filename or URL where the minified output can be found
|
138
|
-
:input_source_map => nil, # The contents of the source map describing the input
|
139
77
|
:screw_ie8 => false, # Don't bother to generate safe code for IE8
|
140
|
-
:
|
141
|
-
|
78
|
+
:source_map => false # Generate source map
|
79
|
+
}
|
80
|
+
|
81
|
+
LEGACY_OPTIONS = [:comments, :squeeze, :copyright, :mangle]
|
82
|
+
|
83
|
+
MANGLE_PROPERTIES_DEFAULTS = {
|
84
|
+
:regex => nil # A regular expression to filter property names to be mangled
|
142
85
|
}
|
86
|
+
|
87
|
+
SOURCE_MAP_DEFAULTS = {
|
88
|
+
:map_url => false, # Url for source mapping to be appended in minified source
|
89
|
+
:url => false, # Url for original source to be appended in minified source
|
90
|
+
:sources_content => false, # Include original source content in map
|
91
|
+
:filename => nil, # The filename of the input file
|
92
|
+
:root => nil, # The URL of the directory which contains :filename
|
93
|
+
:output_filename => nil, # The filename or URL where the minified output can be found
|
94
|
+
:input_source_map => nil # The contents of the source map describing the input
|
95
|
+
}
|
96
|
+
|
143
97
|
# rubocop:enable LineLength
|
144
98
|
|
145
99
|
# Minifies JavaScript code using implicit context.
|
@@ -164,7 +118,7 @@ class Uglifier
|
|
164
118
|
#
|
165
119
|
# @param options [Hash] optional overrides to +Uglifier::DEFAULTS+
|
166
120
|
def initialize(options = {})
|
167
|
-
(options.keys - DEFAULTS.keys -
|
121
|
+
(options.keys - DEFAULTS.keys - LEGACY_OPTIONS)[0..1].each do |missing|
|
168
122
|
raise ArgumentError, "Invalid option: #{missing}"
|
169
123
|
end
|
170
124
|
@options = options
|
@@ -176,7 +130,14 @@ class Uglifier
|
|
176
130
|
# @param source [IO, String] valid JS source code.
|
177
131
|
# @return [String] minified code.
|
178
132
|
def compile(source)
|
179
|
-
|
133
|
+
if @options[:source_map]
|
134
|
+
compiled, source_map = run_uglifyjs(source, true)
|
135
|
+
source_map_uri = Base64.strict_encode64(source_map)
|
136
|
+
source_map_mime = "application/json;charset=utf-8;base64"
|
137
|
+
compiled + "\n//# sourceMappingURL=data:#{source_map_mime},#{source_map_uri}"
|
138
|
+
else
|
139
|
+
run_uglifyjs(source, false)
|
140
|
+
end
|
180
141
|
end
|
181
142
|
alias_method :compress, :compile
|
182
143
|
|
@@ -191,25 +152,28 @@ class Uglifier
|
|
191
152
|
private
|
192
153
|
|
193
154
|
def uglifyjs_source
|
194
|
-
[ES5FallbackPath, SplitFallbackPath, SourcePath].map do |file|
|
195
|
-
File.open(file, "r:UTF-8"
|
155
|
+
[ES5FallbackPath, SplitFallbackPath, SourcePath, UglifyJSWrapperPath].map do |file|
|
156
|
+
File.open(file, "r:UTF-8", &:read)
|
196
157
|
end.join("\n")
|
197
158
|
end
|
198
159
|
|
199
160
|
# Run UglifyJS for given source code
|
200
|
-
def run_uglifyjs(
|
161
|
+
def run_uglifyjs(input, generate_map)
|
162
|
+
source = read_source(input)
|
163
|
+
input_map = input_source_map(source, generate_map)
|
201
164
|
options = {
|
202
|
-
:source =>
|
165
|
+
:source => source,
|
203
166
|
:output => output_options,
|
204
167
|
:compress => compressor_options,
|
205
168
|
:mangle => mangle_options,
|
169
|
+
:mangle_properties => mangle_properties_options,
|
206
170
|
:parse_options => parse_options,
|
207
|
-
:source_map_options => source_map_options,
|
171
|
+
:source_map_options => source_map_options(input_map),
|
208
172
|
:generate_map => generate_map,
|
209
173
|
:enclose => enclose_options
|
210
174
|
}
|
211
175
|
|
212
|
-
@context.call(
|
176
|
+
@context.call("uglifier", options)
|
213
177
|
end
|
214
178
|
|
215
179
|
def read_source(source)
|
@@ -221,14 +185,25 @@ class Uglifier
|
|
221
185
|
end
|
222
186
|
|
223
187
|
def mangle_options
|
224
|
-
|
188
|
+
mangle_options = @options.fetch(:mangle, @options[:mangle])
|
189
|
+
conditional_option(mangle_options, DEFAULTS[:mangle])
|
190
|
+
end
|
191
|
+
|
192
|
+
def mangle_properties_options
|
193
|
+
mangle_options = @options.fetch(:mangle_properties, DEFAULTS[:mangle_properties])
|
194
|
+
options = conditional_option(mangle_options, MANGLE_PROPERTIES_DEFAULTS)
|
195
|
+
if options && options[:regex]
|
196
|
+
options.merge(:regex => encode_regexp(options[:regex]))
|
197
|
+
else
|
198
|
+
options
|
199
|
+
end
|
225
200
|
end
|
226
201
|
|
227
202
|
def compressor_options
|
228
203
|
defaults = conditional_option(
|
229
204
|
DEFAULTS[:compress],
|
230
205
|
:global_defs => @options[:define] || {},
|
231
|
-
:screw_ie8 =>
|
206
|
+
:screw_ie8 => screw_ie8?
|
232
207
|
)
|
233
208
|
conditional_option(@options[:compress] || @options[:squeeze], defaults)
|
234
209
|
end
|
@@ -269,24 +244,31 @@ class Uglifier
|
|
269
244
|
|
270
245
|
def screw_ie8?
|
271
246
|
if (@options[:output] || {}).has_key?(:ie_proof)
|
272
|
-
|
247
|
+
!@options[:output][:ie_proof]
|
273
248
|
else
|
274
|
-
@options
|
249
|
+
@options.fetch(:screw_ie8, DEFAULTS[:screw_ie8])
|
275
250
|
end
|
276
251
|
end
|
277
252
|
|
278
|
-
def source_map_options
|
253
|
+
def source_map_options(input_map)
|
254
|
+
options = conditional_option(@options[:source_map], SOURCE_MAP_DEFAULTS)
|
255
|
+
|
279
256
|
{
|
280
|
-
:file =>
|
281
|
-
:root =>
|
282
|
-
:orig =>
|
283
|
-
:map_url =>
|
284
|
-
:url =>
|
257
|
+
:file => options[:output_filename],
|
258
|
+
:root => options.fetch(:root) { input_map ? input_map["sourceRoot"] : nil },
|
259
|
+
:orig => input_map,
|
260
|
+
:map_url => options[:map_url],
|
261
|
+
:url => options[:url],
|
262
|
+
:sources_content => options[:sources_content]
|
285
263
|
}
|
286
264
|
end
|
287
265
|
|
288
266
|
def parse_options
|
289
|
-
|
267
|
+
if @options[:source_map].respond_to?(:[])
|
268
|
+
{ :filename => @options[:source_map][:filename] }
|
269
|
+
else
|
270
|
+
{}
|
271
|
+
end
|
290
272
|
end
|
291
273
|
|
292
274
|
def enclose_options
|
@@ -318,4 +300,38 @@ class Uglifier
|
|
318
300
|
false
|
319
301
|
end
|
320
302
|
end
|
303
|
+
|
304
|
+
def sanitize_map_root(map)
|
305
|
+
if map.nil?
|
306
|
+
nil
|
307
|
+
elsif map.is_a? String
|
308
|
+
sanitize_map_root(JSON.load(map))
|
309
|
+
elsif map["sourceRoot"] == ""
|
310
|
+
map.merge("sourceRoot" => nil)
|
311
|
+
else
|
312
|
+
map
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def extract_source_mapping_url(source)
|
317
|
+
comment_start = %r{(?://|/\*\s*)}
|
318
|
+
comment_end = %r{\s*(?:\r?\n?\*/|$)?}
|
319
|
+
source_mapping_regex = /#{comment_start}[@#]\ssourceMappingURL=\s*(\S*?)#{comment_end}/
|
320
|
+
rest = /\s#{comment_start}[@#]\s[a-zA-Z]+=\s*(?:\S*?)#{comment_end}/
|
321
|
+
regex = /#{source_mapping_regex}(?:#{rest})*\Z/m
|
322
|
+
match = regex.match(source)
|
323
|
+
match && match[1]
|
324
|
+
end
|
325
|
+
|
326
|
+
def input_source_map(source, generate_map)
|
327
|
+
return nil unless generate_map
|
328
|
+
sanitize_map_root(@options.fetch(:source_map, {}).fetch(:input_source_map) do
|
329
|
+
url = extract_source_mapping_url(source)
|
330
|
+
if url && url.start_with?("data:")
|
331
|
+
Base64.strict_decode64(url.split(",", 2)[-1])
|
332
|
+
end
|
333
|
+
end)
|
334
|
+
rescue ArgumentError, JSON::ParserError
|
335
|
+
nil
|
336
|
+
end
|
321
337
|
end
|