uglifier 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of uglifier might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +27 -0
- data/.travis.yml +3 -3
- data/CHANGELOG.md +4 -0
- data/CONTRIBUTING.md +36 -11
- data/Gemfile +9 -0
- data/README.md +5 -3
- data/Rakefile +10 -2
- data/gemfiles/rubyracer +1 -0
- data/gemfiles/rubyrhino +1 -0
- data/lib/uglifier.rb +112 -98
- data/lib/uglifier/version.rb +1 -1
- data/lib/uglify.js +5 -5
- data/spec/source_map_spec.rb +29 -29
- data/spec/spec_helper.rb +7 -2
- data/spec/uglifier_spec.rb +77 -72
- data/uglifier.gemspec +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da19be0a44b400c082d673a8e9a0163ab02c1d9e
|
4
|
+
data.tar.gz: 53003f0c4bdfd9a404362fbf6950f03ebe25cc82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 796edba31e0fd57cab4f987b638470ba009f5468608dea8c98c529f12abcef289622a66d58b9067f33f94169fa506949813baa1c52b90451bb6082d4230c6c02
|
7
|
+
data.tar.gz: 9cfb9e5dd1ed8b3eb8223f79256c5a6c69da05de769a88e91c3d6db83f341a00af1106b29b1ed4701790bcf0ca193d43fed756207ecdef3ac1149bd67035d84e
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- uglifier.gemspec
|
4
|
+
- lib/uglifier/version.rb
|
5
|
+
|
6
|
+
ClassLength:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
# Offense count: 4
|
10
|
+
# Cop supports --auto-correct.
|
11
|
+
DeprecatedHashMethods:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
HashSyntax:
|
15
|
+
EnforcedStyle: hash_rockets
|
16
|
+
|
17
|
+
LineLength:
|
18
|
+
Max: 100
|
19
|
+
|
20
|
+
MethodLength:
|
21
|
+
Max: 20
|
22
|
+
|
23
|
+
SignalException:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
StringLiterals:
|
27
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -1,17 +1,42 @@
|
|
1
1
|
# Contributing to Uglifier
|
2
2
|
|
3
|
-
Any contributions to Uglifier are welcome, whether they are feedback, bug reports, or - even better - pull requests.
|
3
|
+
Any contributions to Uglifier are welcome, whether they are feedback, bug reports, or - even better - pull requests.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Development
|
6
|
+
|
7
|
+
To start working on Uglifier, fork the repo to your own account. [Ruby](https://www.ruby-lang.org), [bundler](http://bundler.io) and [Node.js](http://nodejs.org) are required as dependencies.
|
8
|
+
|
9
|
+
Ensure that your local copy is up-to-date before you start working on a feature or a bug fix. You should write any new code in a topic branch.
|
10
|
+
|
11
|
+
### Tests
|
12
|
+
|
13
|
+
Try to write a test case that reproduces the problem you're trying to fix or describes a feature that you want to build. Tests are located in `spec/` directory.
|
14
|
+
|
15
|
+
Tests as a pull request are appreciated even without a fix to highlight or reproduce a problem.
|
16
|
+
|
17
|
+
To run tests, first install all project dependencies:
|
18
|
+
|
19
|
+
bundle install
|
20
|
+
|
21
|
+
Then run tests using rake:
|
6
22
|
|
7
|
-
|
23
|
+
bundle exec rake
|
8
24
|
|
9
|
-
|
25
|
+
### Updating UglifyJS and source-map
|
26
|
+
|
27
|
+
[UglifyJS](https://github.com/mishoo/UglifyJS2) and [source-map](https://github.com/mozilla/source-map/) are included in the project as Git submodules. To install submodules, run in your terminal
|
28
|
+
|
29
|
+
git submodule update --init
|
30
|
+
|
31
|
+
After that, UglifyJS and source-map are checked out under `vendor/uglifyjs` and `vendor/source-map`.
|
32
|
+
|
33
|
+
Use Git commands (e.g. git checkout master) to change the included version. You can even write custom code to yourself. After changing the dependencies, compile new version of the bundled JS file using
|
34
|
+
|
35
|
+
rake js
|
36
|
+
|
37
|
+
After this, the new JS is used in your development version.
|
38
|
+
|
39
|
+
|
40
|
+
## Reporting issues
|
10
41
|
|
11
|
-
|
12
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
13
|
-
* Fork the project
|
14
|
-
* Start a feature/bugfix branch
|
15
|
-
* Commit and push until you are happy with your contribution
|
16
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
17
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
42
|
+
Uglifier uses the [GitHub issue tracker](https://github.com/lautis/uglifier/issues) to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. When submitting a bug report, please include a Gist that includes a stack trace and any details that may be necessary to reproduce the bug, including your gem version, Ruby version, and **ExecJS runtime**. Ideally, a bug report should include a pull request with failing specs.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Uglifier
|
1
|
+
# Uglifier [![Build Status](https://travis-ci.org/lautis/uglifier.svg?branch=master)](https://travis-ci.org/lautis/uglifier) [![Dependency Status](https://gemnasium.com/lautis/uglifier.svg)](https://gemnasium.com/lautis/uglifier)
|
2
2
|
|
3
3
|
Ruby wrapper for [UglifyJS](https://github.com/mishoo/UglifyJS2) JavaScript compressor.
|
4
4
|
|
@@ -101,9 +101,11 @@ Available options and their defaults are
|
|
101
101
|
|
102
102
|
## Development
|
103
103
|
|
104
|
-
|
104
|
+
Tests are run using
|
105
105
|
|
106
|
-
|
106
|
+
bundle exec rake
|
107
|
+
|
108
|
+
See [CONTRIBUTING](https://github.com/lautis/uglifier/blob/master/CONTRIBUTING.md) for details about working on and contributing to Uglifier.
|
107
109
|
|
108
110
|
## Copyright
|
109
111
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'bundler'
|
3
5
|
require 'bundler/gem_tasks'
|
@@ -18,8 +20,6 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
|
|
18
20
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
19
21
|
end
|
20
22
|
|
21
|
-
task :default => :spec
|
22
|
-
|
23
23
|
require 'rdoc/task'
|
24
24
|
Rake::RDocTask.new do |rdoc|
|
25
25
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
@@ -51,3 +51,11 @@ task :js do
|
|
51
51
|
|
52
52
|
File.write("lib/uglify.js", source)
|
53
53
|
end
|
54
|
+
|
55
|
+
if RUBY_VERSION < '1.9.3'
|
56
|
+
task :default => [:spec]
|
57
|
+
else
|
58
|
+
require 'rubocop/rake_task'
|
59
|
+
RuboCop::RakeTask.new(:rubocop)
|
60
|
+
task :default => [:rubocop, :spec]
|
61
|
+
end
|
data/gemfiles/rubyracer
CHANGED
data/gemfiles/rubyrhino
CHANGED
data/lib/uglifier.rb
CHANGED
@@ -4,11 +4,74 @@ require "execjs"
|
|
4
4
|
require "json"
|
5
5
|
require "uglifier/version"
|
6
6
|
|
7
|
+
# A wrapper around the UglifyJS interface
|
7
8
|
class Uglifier
|
8
9
|
Error = ExecJS::Error
|
10
|
+
JS = <<-JS
|
11
|
+
function comments(option) {
|
12
|
+
if (Object.prototype.toString.call(option) === '[object Array]') {
|
13
|
+
return new RegExp(option[0], option[1]);
|
14
|
+
} else if (option == "jsdoc") {
|
15
|
+
return function(node, comment) {
|
16
|
+
if (comment.type == "comment2") {
|
17
|
+
return /@preserve|@license|@cc_on/i.test(comment.value);
|
18
|
+
} else {
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
} else {
|
23
|
+
return option;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
var options = %s;
|
28
|
+
var source = options.source;
|
29
|
+
var ast = UglifyJS.parse(source, options.parse_options);
|
30
|
+
ast.figure_out_scope();
|
31
|
+
|
32
|
+
if (options.compress) {
|
33
|
+
var compressor = UglifyJS.Compressor(options.compress);
|
34
|
+
ast = ast.transform(compressor);
|
35
|
+
ast.figure_out_scope();
|
36
|
+
}
|
37
|
+
|
38
|
+
if (options.mangle) {
|
39
|
+
ast.compute_char_frequency();
|
40
|
+
ast.mangle_names(options.mangle);
|
41
|
+
}
|
42
|
+
|
43
|
+
if (options.enclose) {
|
44
|
+
ast = ast.wrap_enclose(options.enclose);
|
45
|
+
}
|
46
|
+
|
47
|
+
var gen_code_options = options.output;
|
48
|
+
gen_code_options.comments = comments(options.output.comments);
|
49
|
+
|
50
|
+
if (options.generate_map) {
|
51
|
+
var source_map = UglifyJS.SourceMap(options.source_map_options);
|
52
|
+
gen_code_options.source_map = source_map;
|
53
|
+
}
|
54
|
+
|
55
|
+
var stream = UglifyJS.OutputStream(gen_code_options);
|
56
|
+
|
57
|
+
ast.print(stream);
|
58
|
+
if (options.generate_map) {
|
59
|
+
return [stream.toString(), source_map.toString()];
|
60
|
+
} else {
|
61
|
+
return stream.toString();
|
62
|
+
}
|
63
|
+
JS
|
64
|
+
|
65
|
+
# UglifyJS source patch
|
66
|
+
SourcePath = File.expand_path("../uglify.js", __FILE__)
|
67
|
+
# ES5 shims source path
|
68
|
+
ES5FallbackPath = File.expand_path("../es5.js", __FILE__)
|
69
|
+
# String.split shim source path
|
70
|
+
SplitFallbackPath = File.expand_path("../split.js", __FILE__)
|
9
71
|
|
10
72
|
# Default options for compilation
|
11
73
|
DEFAULTS = {
|
74
|
+
# rubocop:disable LineLength
|
12
75
|
:output => {
|
13
76
|
:ascii_only => true, # Escape non-ASCII characterss
|
14
77
|
:comments => :copyright, # Preserve comments (:all, :jsdoc, :copyright, :none)
|
@@ -63,10 +126,7 @@ class Uglifier
|
|
63
126
|
:input_source_map => nil, # The contents of the source map describing the input
|
64
127
|
:screw_ie8 => false # Don't bother to generate safe code for IE8
|
65
128
|
}
|
66
|
-
|
67
|
-
SourcePath = File.expand_path("../uglify.js", __FILE__)
|
68
|
-
ES5FallbackPath = File.expand_path("../es5.js", __FILE__)
|
69
|
-
SplitFallbackPath = File.expand_path("../split.js", __FILE__)
|
129
|
+
# rubocop:enable LineLength
|
70
130
|
|
71
131
|
# Minifies JavaScript code using implicit context.
|
72
132
|
#
|
@@ -75,7 +135,7 @@ class Uglifier
|
|
75
135
|
#
|
76
136
|
# Returns minified code as String
|
77
137
|
def self.compile(source, options = {})
|
78
|
-
|
138
|
+
new(options).compile(source)
|
79
139
|
end
|
80
140
|
|
81
141
|
# Minifies JavaScript code and generates a source map using implicit context.
|
@@ -85,7 +145,7 @@ class Uglifier
|
|
85
145
|
#
|
86
146
|
# Returns a pair of [minified code as String, source map as a String]
|
87
147
|
def self.compile_with_map(source, options = {})
|
88
|
-
|
148
|
+
new(options).compile_with_map(source)
|
89
149
|
end
|
90
150
|
|
91
151
|
# Initialize new context for Uglifier with given options
|
@@ -93,7 +153,7 @@ class Uglifier
|
|
93
153
|
# options - Hash of options to override Uglifier::DEFAULTS
|
94
154
|
def initialize(options = {})
|
95
155
|
(options.keys - DEFAULTS.keys - [:comments, :squeeze, :copyright])[0..1].each do |missing|
|
96
|
-
raise ArgumentError
|
156
|
+
raise ArgumentError, "Invalid option: #{missing}"
|
97
157
|
end
|
98
158
|
@options = options
|
99
159
|
@context = ExecJS.compile(File.open(ES5FallbackPath, "r:UTF-8").read +
|
@@ -107,7 +167,7 @@ class Uglifier
|
|
107
167
|
#
|
108
168
|
# Returns minified code as String
|
109
169
|
def compile(source)
|
110
|
-
|
170
|
+
run_uglifyjs(source, false)
|
111
171
|
end
|
112
172
|
alias_method :compress, :compile
|
113
173
|
|
@@ -117,90 +177,40 @@ class Uglifier
|
|
117
177
|
#
|
118
178
|
# Returns a pair of [minified code as String, source map as a String]
|
119
179
|
def compile_with_map(source)
|
120
|
-
|
180
|
+
run_uglifyjs(source, true)
|
121
181
|
end
|
122
182
|
|
123
183
|
private
|
124
184
|
|
125
|
-
#
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
source = source.respond_to?(:read) ? source.read : source.to_s
|
130
|
-
|
131
|
-
js = <<-JS
|
132
|
-
function comments(option) {
|
133
|
-
if (Object.prototype.toString.call(option) === '[object Array]') {
|
134
|
-
return new RegExp(option[0], option[1]);
|
135
|
-
} else if (option == "jsdoc") {
|
136
|
-
return function(node, comment) {
|
137
|
-
if (comment.type == "comment2") {
|
138
|
-
return /@preserve|@license|@cc_on/i.test(comment.value);
|
139
|
-
} else {
|
140
|
-
return false;
|
141
|
-
}
|
142
|
-
}
|
143
|
-
} else {
|
144
|
-
return option;
|
145
|
-
}
|
146
|
-
}
|
147
|
-
|
148
|
-
var options = %s;
|
149
|
-
var source = options.source;
|
150
|
-
var ast = UglifyJS.parse(source, options.parse_options);
|
151
|
-
ast.figure_out_scope();
|
152
|
-
|
153
|
-
if (options.compress) {
|
154
|
-
var compressor = UglifyJS.Compressor(options.compress);
|
155
|
-
ast = ast.transform(compressor);
|
156
|
-
ast.figure_out_scope();
|
157
|
-
}
|
158
|
-
|
159
|
-
if (options.mangle) {
|
160
|
-
ast.compute_char_frequency();
|
161
|
-
ast.mangle_names(options.mangle);
|
162
|
-
}
|
163
|
-
|
164
|
-
if (options.enclose) {
|
165
|
-
ast = ast.wrap_enclose(options.enclose);
|
166
|
-
}
|
167
|
-
|
168
|
-
var gen_code_options = options.output;
|
169
|
-
gen_code_options.comments = comments(options.output.comments);
|
170
|
-
|
171
|
-
if (options.generate_map) {
|
172
|
-
var source_map = UglifyJS.SourceMap(options.source_map_options);
|
173
|
-
gen_code_options.source_map = source_map;
|
174
|
-
}
|
175
|
-
|
176
|
-
var stream = UglifyJS.OutputStream(gen_code_options);
|
177
|
-
|
178
|
-
ast.print(stream);
|
179
|
-
if (options.generate_map) {
|
180
|
-
return [stream.toString(), source_map.toString()];
|
181
|
-
} else {
|
182
|
-
return stream.toString();
|
183
|
-
}
|
184
|
-
JS
|
185
|
-
|
186
|
-
@context.exec(js % json_encode(
|
187
|
-
:source => source,
|
185
|
+
# Run UglifyJS for given source code
|
186
|
+
def run_uglifyjs(source, generate_map)
|
187
|
+
@context.exec(Uglifier::JS % json_encode(
|
188
|
+
:source => read_source(source),
|
188
189
|
:output => output_options,
|
189
190
|
:compress => compressor_options,
|
190
191
|
:mangle => mangle_options,
|
191
192
|
:parse_options => parse_options,
|
192
193
|
:source_map_options => source_map_options,
|
193
|
-
:generate_map =>
|
194
|
+
:generate_map => generate_map,
|
194
195
|
:enclose => enclose_options
|
195
196
|
))
|
196
197
|
end
|
197
198
|
|
199
|
+
def read_source(source)
|
200
|
+
if source.respond_to?(:read)
|
201
|
+
source.read
|
202
|
+
else
|
203
|
+
source.to_s
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
198
207
|
def mangle_options
|
199
208
|
conditional_option(@options[:mangle], DEFAULTS[:mangle])
|
200
209
|
end
|
201
210
|
|
202
211
|
def compressor_options
|
203
|
-
defaults = conditional_option(
|
212
|
+
defaults = conditional_option(
|
213
|
+
DEFAULTS[:compress],
|
204
214
|
:global_defs => @options[:define] || {},
|
205
215
|
:screw_ie8 => @options[:screw_ie8] || DEFAULTS[:screw_ie8]
|
206
216
|
)
|
@@ -208,17 +218,7 @@ class Uglifier
|
|
208
218
|
end
|
209
219
|
|
210
220
|
def comment_options
|
211
|
-
|
212
|
-
@options[:output][:comments]
|
213
|
-
elsif @options.has_key?(:comments)
|
214
|
-
@options[:comments]
|
215
|
-
elsif @options[:copyright] == false
|
216
|
-
:none
|
217
|
-
else
|
218
|
-
DEFAULTS[:output][:comments]
|
219
|
-
end
|
220
|
-
|
221
|
-
case val
|
221
|
+
case comment_setting
|
222
222
|
when :all, true
|
223
223
|
true
|
224
224
|
when :jsdoc
|
@@ -226,23 +226,37 @@ class Uglifier
|
|
226
226
|
when :copyright
|
227
227
|
encode_regexp(/Copyright/i)
|
228
228
|
when Regexp
|
229
|
-
encode_regexp(
|
229
|
+
encode_regexp(comment_setting)
|
230
230
|
else
|
231
231
|
false
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
|
-
def
|
236
|
-
|
237
|
-
|
235
|
+
def comment_setting
|
236
|
+
if @options.has_key?(:output) && @options[:output].has_key?(:comments)
|
237
|
+
@options[:output][:comments]
|
238
|
+
elsif @options.has_key?(:comments)
|
239
|
+
@options[:comments]
|
240
|
+
elsif @options[:copyright] == false
|
241
|
+
:none
|
238
242
|
else
|
239
|
-
|
243
|
+
DEFAULTS[:output][:comments]
|
240
244
|
end
|
245
|
+
end
|
241
246
|
|
247
|
+
def output_options
|
242
248
|
DEFAULTS[:output].merge(@options[:output] || {}).merge(
|
243
249
|
:comments => comment_options,
|
244
|
-
:screw_ie8 => screw_ie8
|
245
|
-
).reject { |key,
|
250
|
+
:screw_ie8 => screw_ie8?
|
251
|
+
).reject { |key, _| key == :ie_proof }
|
252
|
+
end
|
253
|
+
|
254
|
+
def screw_ie8?
|
255
|
+
if (@options[:output] || {}).has_key?(:ie_proof)
|
256
|
+
false
|
257
|
+
else
|
258
|
+
@options[:screw_ie8] || DEFAULTS[:screw_ie8]
|
259
|
+
end
|
246
260
|
end
|
247
261
|
|
248
262
|
def source_map_options
|
@@ -254,7 +268,7 @@ class Uglifier
|
|
254
268
|
end
|
255
269
|
|
256
270
|
def parse_options
|
257
|
-
{:filename => @options[:source_filename]}
|
271
|
+
{ :filename => @options[:source_filename] }
|
258
272
|
end
|
259
273
|
|
260
274
|
def enclose_options
|
@@ -273,16 +287,16 @@ class Uglifier
|
|
273
287
|
|
274
288
|
def encode_regexp(regexp)
|
275
289
|
modifiers = if regexp.casefold?
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
290
|
+
"i"
|
291
|
+
else
|
292
|
+
""
|
293
|
+
end
|
280
294
|
|
281
295
|
[regexp.source, modifiers]
|
282
296
|
end
|
283
297
|
|
284
298
|
def conditional_option(value, defaults)
|
285
|
-
if value == true || value
|
299
|
+
if value == true || value.nil?
|
286
300
|
defaults
|
287
301
|
elsif value
|
288
302
|
defaults.merge(value)
|