psyho_juicer 1.0.0 → 1.0.7
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.
- data/Gemfile +11 -0
- data/History.txt +33 -0
- data/Readme.rdoc +16 -4
- data/VERSION +1 -1
- data/lib/juicer/asset/path.rb +6 -10
- data/lib/juicer/cache_buster.rb +53 -13
- data/lib/juicer/command/merge.rb +14 -6
- data/lib/juicer/css_cache_buster.rb +6 -4
- data/lib/juicer/dependency_resolver/css_dependency_resolver.rb +1 -1
- data/lib/juicer/image_embed.rb +18 -20
- data/lib/juicer/install/yui_compressor_installer.rb +2 -1
- data/lib/juicer/merger/stylesheet_merger.rb +5 -5
- data/lib/juicer/minifyer/closure_compiler.rb +1 -1
- data/lib/juicer.rb +1 -1
- data/lib/psyho_juicer.rb +1 -0
- data/test/data/Changelog.txt +10 -0
- data/test/data/a.css +3 -0
- data/test/data/a.js +5 -0
- data/test/data/a1.css +5 -0
- data/test/data/b.css +1 -0
- data/test/data/b.js +5 -0
- data/test/data/b1.css +5 -0
- data/test/data/b2.css +5 -0
- data/test/data/c1.css +3 -0
- data/test/data/css/2.gif +1 -0
- data/test/data/css/test.css +15 -0
- data/test/data/css/test2.css +1 -0
- data/test/data/css/test3.css +12 -0
- data/test/data/d1.css +3 -0
- data/test/data/images/1.png +1 -0
- data/test/data/my_app.js +2 -0
- data/test/data/not-ok.js +2 -0
- data/test/data/ok.js +3 -0
- data/test/data/path_test.css +5 -0
- data/test/data/path_test2.css +14 -0
- data/test/data/pkg/module/moda.js +2 -0
- data/test/data/pkg/module/modb.js +3 -0
- data/test/data/pkg/pkg.js +1 -0
- data/test/fixtures/git-tracked-file.txt +1 -0
- data/test/fixtures/yui-download.html +103 -243
- data/test/test_helper.rb +27 -1
- data/test/unit/juicer/asset/path_test.rb +7 -1
- data/test/unit/juicer/cache_buster_test.rb +95 -5
- data/test/unit/juicer/command/util_test.rb +1 -1
- data/test/unit/juicer/css_cache_buster_test.rb +127 -32
- data/test/unit/juicer/image_embed_test.rb +35 -0
- data/test/unit/juicer/merger/stylesheet_merger_test.rb +175 -109
- data/test/unit/juicer/minifyer/closure_compressor_test.rb +3 -3
- metadata +68 -21
data/Gemfile
ADDED
data/History.txt
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
== 1.0.6 / 2010-06-29
|
2
|
+
* Fix bug where image embedding could not see the document root,
|
3
|
+
resulting in missing images (Jakub Pawlowicz)
|
4
|
+
|
5
|
+
== 1.0.5 / 2010-06-06
|
6
|
+
* No more Regexp warnings on Ruby 1.9.1
|
7
|
+
* Cycle hosts for relative paths
|
8
|
+
* Allow hostnames with no protocol (i.e. //myassets)
|
9
|
+
|
10
|
+
== 1.0.4 / 2010-05-26
|
11
|
+
* Fix issue (GH-22) where Closure Compiler would not work due to wrong
|
12
|
+
command line arguments passed by Juicer
|
13
|
+
* Brought to you by Elliott Wood, two-fish.com:
|
14
|
+
* Added "rails" cache-buster type for cache-buster stamps that are identical
|
15
|
+
to those generated by Rails'
|
16
|
+
* --all-hosts-local is no longer dependent upon command-line positioning.
|
17
|
+
* Ensured that URLs don't receive two cache busters, even when asset
|
18
|
+
host cycling is used.
|
19
|
+
|
20
|
+
== 1.0.3 / 2010-04-15
|
21
|
+
* Update YUI Compressor installer to find the download link in YUI's updated markup
|
22
|
+
Pacthed by Olle Jonsson (http://ollehost.dk/blog/)
|
23
|
+
* Make stylesheet merger properly handle quoted URLs, fixes GH issue 20
|
24
|
+
|
25
|
+
== 1.0.2 / 2010-03-19
|
26
|
+
* Don't add multiple cache busters
|
27
|
+
|
28
|
+
== 1.0.1 / 2010-03-03
|
29
|
+
* Don't crash when trying to cache bust non-existent files, simply
|
30
|
+
skip them
|
31
|
+
* Don't attempt to cache bust data urls (contributed by
|
32
|
+
http://github.com/psyho/juicer)
|
33
|
+
|
1
34
|
== 1.0.0 / 2010-02-24
|
2
35
|
* Make sure @import rules with url is removed when files are merged
|
3
36
|
* Dependency resolver supports depending on directories
|
data/Readme.rdoc
CHANGED
@@ -4,9 +4,12 @@ Official URL: http://github.com/cjohansen/juicer/tree/master
|
|
4
4
|
Christian Johansen (http://www.cjohansen.no) and contributors:
|
5
5
|
|
6
6
|
* Morgan Roderick (http://roderick.dk)
|
7
|
+
* Elliott Wood (http://two-fish.com)
|
7
8
|
* Pavel Valodzka (http://github.com/valodzka)
|
8
9
|
* Daniel Stockman (http://evocateur.org/)
|
9
10
|
* Aaron Suggs (http://ktheory.com)
|
11
|
+
* Olle Jonsson (http://ollehost.dk/blog/)
|
12
|
+
* Jakub Pawlowicz (http://blog.jakubpawlowicz.com)
|
10
13
|
|
11
14
|
== DESCRIPTION:
|
12
15
|
|
@@ -68,15 +71,19 @@ Juicer supports so-called cache busters. A cache buster is a pattern in a path
|
|
68
71
|
whose only purpose is to "trick" browsers to redownload a file when it has
|
69
72
|
changed in cases where a far future expires header is used.
|
70
73
|
|
71
|
-
There are
|
72
|
-
so: http://assets/images/1.png?
|
73
|
-
|
74
|
+
There are three types of cache busters. Soft cache busters (the default) add a
|
75
|
+
parameter to the URL, like so: http://assets/images/1.png?jcb=1234567890, ie the
|
76
|
+
letters "jcb" (as in Juicer Cache Buster) and then the timestamp of the files mtime.
|
77
|
+
|
78
|
+
Rails cache busters are similar, except they leave out the parameter name. This
|
79
|
+
mimics the behavior of the image_tag helper in the Ruby on Rails framework, so that
|
80
|
+
images called from both CSS and from Rails views will have identical URLs.
|
74
81
|
|
75
82
|
Unfortunately, the popular web proxy Squid shipped for some time with a default
|
76
83
|
configuration which would not treat a URL as a "new" URL if the only thing changed
|
77
84
|
was the GET parameters. For this reason Juicer provides hard cache busters.
|
78
85
|
|
79
|
-
Hard cache busters result in URLs such as: http://assets/images/1-
|
86
|
+
Hard cache busters result in URLs such as: http://assets/images/1-jcb1234567890.png,
|
80
87
|
ie URLs that require either renaming of files, or (more conveniently) a web
|
81
88
|
server configuration that will forward URLs to the right files anyway.
|
82
89
|
|
@@ -286,6 +293,11 @@ Will tell you about other dependencies that might be missing on your system.
|
|
286
293
|
* Aaron Suggs (http://ktheory.com)
|
287
294
|
Added support for depending on directories
|
288
295
|
Fixed installers on 1.0 branch
|
296
|
+
* Elliott Wood (http://two-fish.com)
|
297
|
+
Added "rails" cache buster type
|
298
|
+
Fixed issues with asset host cycling
|
299
|
+
* Jakub Pawlowicz (http://blog.jakubpawlowicz.com)
|
300
|
+
Fixed issue with embedding images that weren't found
|
289
301
|
|
290
302
|
== LICENSE:
|
291
303
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.7
|
data/lib/juicer/asset/path.rb
CHANGED
@@ -63,7 +63,7 @@ module Juicer
|
|
63
63
|
# Directory served as root through a web server, see Juicer::Asset::Path#initialize
|
64
64
|
attr_reader :document_root
|
65
65
|
|
66
|
-
@@scheme_pattern = %r{^[a-zA-Z]{3,5}
|
66
|
+
@@scheme_pattern = %r{^([a-zA-Z]{3,5}:)?//}
|
67
67
|
|
68
68
|
#
|
69
69
|
# Initialize asset at <tt>path</tt>. Accepts an optional hash of options:
|
@@ -244,16 +244,12 @@ module Juicer
|
|
244
244
|
def path_with_cache_buster(path, options = {})
|
245
245
|
return path if !options.key?(:cache_buster) && options[:cache_buster_type].nil?
|
246
246
|
|
247
|
-
buster_path = nil
|
248
247
|
type = options[:cache_buster_type] || :soft
|
249
248
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
# If :cache_buster wasn't specified, rely on default value
|
255
|
-
buster_path = Juicer::CacheBuster.send(type, filename)
|
256
|
-
end
|
249
|
+
buster_options = {:revision_type => options[:cache_buster_format]}
|
250
|
+
buster_options[:parameter] = options[:cache_buster] if options.key?(:cache_buster)
|
251
|
+
|
252
|
+
buster_path = Juicer::CacheBuster.send(type, filename, buster_options)
|
257
253
|
|
258
254
|
path.sub(File.basename(path), File.basename(buster_path))
|
259
255
|
end
|
@@ -265,7 +261,7 @@ module Juicer
|
|
265
261
|
hosts.each do |host|
|
266
262
|
return path if path !~ @@scheme_pattern
|
267
263
|
|
268
|
-
path.sub
|
264
|
+
path = path.sub(%r{^#{host}}, '')
|
269
265
|
end
|
270
266
|
|
271
267
|
return path
|
data/lib/juicer/cache_buster.rb
CHANGED
@@ -78,20 +78,34 @@ module Juicer
|
|
78
78
|
# See <tt>#hard</tt> and <tt>#soft</tt> for explanation of the parameter
|
79
79
|
# argument.
|
80
80
|
#
|
81
|
-
def self.path(file,
|
81
|
+
def self.path(file, opts = {})
|
82
82
|
return file if file =~ /data:.*;base64/
|
83
|
+
|
84
|
+
type = opts[:type]
|
85
|
+
type = [:soft, :hard, :rails].include?(type) ? type : :soft
|
86
|
+
|
87
|
+
parameter = opts.key?(:parameter) ? opts[:parameter] : DEFAULT_PARAMETER
|
88
|
+
parameter = nil if type == :rails
|
89
|
+
|
83
90
|
file = self.clean(file, parameter)
|
84
91
|
filename = file.split("?").first
|
92
|
+
|
93
|
+
revision_type = opts[:revision_type]
|
94
|
+
revision_type = :mtime if type == :rails
|
95
|
+
revision_type = [:git, :mtime].include?(revision_type) ? revision_type : :mtime
|
96
|
+
|
85
97
|
raise ArgumentError.new("#{file} could not be found") unless File.exists?(filename)
|
86
|
-
|
87
|
-
|
98
|
+
|
99
|
+
revision = Revision.send(revision_type, filename)
|
88
100
|
|
89
101
|
if type == :soft
|
90
102
|
parameter = "#{parameter}=".sub(/^=$/, '')
|
91
|
-
return "#{file}#{file.index('?') ? '&' : '?'}#{parameter}#{
|
103
|
+
return "#{file}#{file.index('?') ? '&' : '?'}#{parameter}#{revision}"
|
104
|
+
elsif type == :rails
|
105
|
+
return "#{file}#{file.index('?') ? '' : "?#{revision}"}"
|
92
106
|
end
|
93
107
|
|
94
|
-
file.sub(/(\.[^\.]+$)/, "-#{parameter}#{
|
108
|
+
file.sub(/(\.[^\.]+$)/, "-#{parameter}#{revision}" + '\1')
|
95
109
|
end
|
96
110
|
|
97
111
|
#
|
@@ -101,8 +115,8 @@ module Juicer
|
|
101
115
|
# <tt>images/logo-cb1234567890.png</tt> which is the case for the default
|
102
116
|
# parameter name "cb" (as in *c*ache *b*uster).
|
103
117
|
#
|
104
|
-
def self.hard(file,
|
105
|
-
self.path(file, :hard
|
118
|
+
def self.hard(file, opts = {})
|
119
|
+
self.path(file, opts.merge(:type => :hard))
|
106
120
|
end
|
107
121
|
|
108
122
|
#
|
@@ -112,20 +126,46 @@ module Juicer
|
|
112
126
|
# <tt>images/logo.png?cb=1234567890</tt> which is the case for the default
|
113
127
|
# parameter name "cb" (as in *c*ache *b*uster).
|
114
128
|
#
|
115
|
-
def self.soft(file,
|
116
|
-
self.path(file, :soft
|
129
|
+
def self.soft(file, opts = {})
|
130
|
+
self.path(file, opts.merge(:type => :soft))
|
117
131
|
end
|
118
132
|
|
133
|
+
#
|
134
|
+
# Add a Rails-style cache buster to a filename. Results in filenames of the
|
135
|
+
# form: <tt>file.suffix?[timestamp]</tt>, ie <tt>images/logo.png?1234567890</tt>
|
136
|
+
# which is the format used by Rails' image_tag helper.
|
137
|
+
#
|
138
|
+
def self.rails(file, opts = {})
|
139
|
+
self.path(file, opts.merge(:type => :rails))
|
140
|
+
end
|
141
|
+
|
119
142
|
#
|
120
143
|
# Remove cache buster from a URL for a given parameter name. Parameter name is
|
121
144
|
# "cb" by default.
|
122
145
|
#
|
123
146
|
def self.clean(file, parameter = DEFAULT_PARAMETER)
|
124
|
-
|
125
|
-
|
126
|
-
|
147
|
+
if "#{parameter}".length == 0
|
148
|
+
return file.sub(/\?\d+$/, '')
|
149
|
+
else
|
150
|
+
query_param = "#{parameter}="
|
151
|
+
new_file = file.sub(/#{query_param}\d+&?/, "").sub(/(\?|&)$/, "")
|
152
|
+
return new_file unless new_file == file
|
127
153
|
|
128
|
-
|
154
|
+
file.sub(/-#{parameter}\d+(\.\w+)($|\?)/, '\1\2')
|
155
|
+
end
|
129
156
|
end
|
157
|
+
|
158
|
+
module Revision
|
159
|
+
def self.git(filename)
|
160
|
+
version = %x{git log --pretty=format:%H -1 -- #{filename} 2> /dev/null}
|
161
|
+
version = %x{git log --pretty=format:%H -1 2> /dev/null} if version == '' || version == nil
|
162
|
+
version = 'unknown' if version == '' || version == nil
|
163
|
+
return version
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.mtime(filename)
|
167
|
+
File.mtime(filename).to_i
|
168
|
+
end
|
169
|
+
end
|
130
170
|
end
|
131
171
|
end
|
data/lib/juicer/command/merge.rb
CHANGED
@@ -68,15 +68,20 @@ the compressor the path should be the path to where the jar file is found.
|
|
68
68
|
opt.on("-l", "--local-hosts hosts", "Host names that are served from --document-root (can be given cache busters). Comma separated") do |hosts|
|
69
69
|
@local_hosts = hosts.split(",")
|
70
70
|
end
|
71
|
-
opt.on("", "--all-hosts-local", "Treat all hosts as local (ie served from --document-root") {
|
71
|
+
opt.on("", "--all-hosts-local", "Treat all hosts as local (ie served from --document-root)") { @all_hosts_local = true }
|
72
72
|
opt.on("-r", "--relative-urls", "Convert all referenced URLs to relative URLs. Requires --document-root if\n" +
|
73
73
|
(" " * 37) + "absolute URLs are used. Only valid for CSS files") { |t| @relative_urls = true }
|
74
74
|
opt.on("-b", "--absolute-urls", "Convert all referenced URLs to absolute URLs. Requires --document-root.\n" +
|
75
75
|
(" " * 37) + "Works with cycled asset hosts. Only valid for CSS files") { |t| @absolute_urls = true }
|
76
76
|
opt.on("-d", "--document-root dir", "Path to resolve absolute URLs relative to") { |path| @document_root = path }
|
77
|
-
opt.on("-c", "--cache-buster type", "none, soft or hard. Default is soft, which adds timestamps to
|
78
|
-
(" " * 37) + "URLs as query parameters. None leaves URLs untouched
|
79
|
-
|
77
|
+
opt.on("-c", "--cache-buster type", "none, soft, rails, or hard. Default is soft, which adds timestamps to\n" +
|
78
|
+
(" " * 37) + "reference URLs as query parameters. None leaves URLs untouched, rails adds\n" +
|
79
|
+
(" " * 37) + "timestamps in the same format as Rails' image_tag helper, and hard alters\n" +
|
80
|
+
(" " * 37) + "file names") do |type|
|
81
|
+
@cache_buster = [:soft, :hard, :rails].include?(type.to_sym) ? type.to_sym : nil
|
82
|
+
end
|
83
|
+
opt.on("-C", "--cache-buster-format format", "Format of the cache buster. Allowed mtime (timestamp) and git (git commit hash). Default is mtime") do |format|
|
84
|
+
@cache_buster_format = (format.to_sym == :git) ? :git : :mtime
|
80
85
|
end
|
81
86
|
opt.on("-e", "--embed-images type", "none or data_uri. Default is none. Data_uri embeds images using Base64 encoding\n" +
|
82
87
|
(" " * 37) + "None leaves URLs untouched. Candiate images must be flagged with '?embed=true to be considered") do |embed|
|
@@ -93,6 +98,9 @@ the compressor the path should be the path to where the jar file is found.
|
|
93
98
|
raise SystemExit.new("Please provide atleast one input file")
|
94
99
|
end
|
95
100
|
|
101
|
+
# Copy hosts to local_hosts if --all-hosts-local was specified
|
102
|
+
@local_hosts = @hosts if @all_hosts_local
|
103
|
+
|
96
104
|
# Figure out which file to output to
|
97
105
|
output = output(files.first)
|
98
106
|
|
@@ -180,7 +188,7 @@ the compressor the path should be the path to where the jar file is found.
|
|
180
188
|
#
|
181
189
|
def cache_buster(file)
|
182
190
|
return nil if !file || file !~ /\.css$/ || @cache_buster.nil?
|
183
|
-
Juicer::CssCacheBuster.new(:document_root => @document_root, :type => @cache_buster, :hosts => @local_hosts)
|
191
|
+
Juicer::CssCacheBuster.new(:document_root => @document_root, :type => @cache_buster, :hosts => @local_hosts, :format => @cache_buster_format)
|
184
192
|
end
|
185
193
|
|
186
194
|
#
|
@@ -188,7 +196,7 @@ the compressor the path should be the path to where the jar file is found.
|
|
188
196
|
#
|
189
197
|
def image_embed(file)
|
190
198
|
return nil if !file || file !~ /\.css$/ || @image_embed_type.nil?
|
191
|
-
Juicer::ImageEmbed.new( :type => @image_embed_type )
|
199
|
+
Juicer::ImageEmbed.new(:document_root => @document_root, :type => @image_embed_type )
|
192
200
|
end
|
193
201
|
|
194
202
|
#
|
@@ -29,6 +29,7 @@ module Juicer
|
|
29
29
|
@document_root.sub!(%r{/?$}, "") if @document_root
|
30
30
|
@type = options[:type] || :soft
|
31
31
|
@hosts = (options[:hosts] || []).collect { |h| h.sub!(%r{/?$}, "") }
|
32
|
+
@format = options[:format] || :mtime
|
32
33
|
@contents = @base = nil
|
33
34
|
end
|
34
35
|
|
@@ -42,15 +43,16 @@ module Juicer
|
|
42
43
|
|
43
44
|
urls(file).each do |asset|
|
44
45
|
begin
|
45
|
-
next if used.include?(asset.path)
|
46
|
-
@contents.gsub!(asset.path, asset.path(:cache_buster_type => @type))
|
46
|
+
next if used.include?(asset.path)
|
47
|
+
@contents.gsub!(asset.path, asset.path(:cache_buster_type => @type, :cache_buster_format => @format))
|
48
|
+
used.push(asset.path)
|
47
49
|
rescue Errno::ENOENT
|
48
50
|
puts "Unable to locate file #{asset.path}, skipping cache buster"
|
49
51
|
rescue ArgumentError => e
|
50
52
|
if e.message =~ /No document root/
|
51
|
-
|
53
|
+
puts "Unable to resolve path #{asset.path} without :document_root option"
|
52
54
|
else
|
53
|
-
|
55
|
+
puts "Unable to locate #{asset.path}, skipping cache buster"
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -8,7 +8,7 @@ module Juicer
|
|
8
8
|
class CssDependencyResolver < DependencyResolver
|
9
9
|
# Regexp borrowed from similar project:
|
10
10
|
# http://github.com/cgriego/front-end-blender/tree/master/lib/front_end_architect/blender.rb
|
11
|
-
@@import_pattern = /^\s*@import(?:\surl\(|\s)(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]
|
11
|
+
@@import_pattern = /^\s*@import(?:\surl\(|\s)(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]*))?\1\)?(?:[^?;]*);?/im
|
12
12
|
|
13
13
|
private
|
14
14
|
def parse(line, imported_file = nil)
|
data/lib/juicer/image_embed.rb
CHANGED
@@ -62,13 +62,13 @@ module Juicer
|
|
62
62
|
begin
|
63
63
|
next if used.include?(asset) || duplicates.include?(asset.path)
|
64
64
|
used << asset
|
65
|
-
|
65
|
+
|
66
66
|
# make sure we do not exceed SIZE_LIMIT
|
67
67
|
new_path = embed_data_uri(asset.filename)
|
68
68
|
|
69
69
|
if new_path.length < SIZE_LIMIT
|
70
70
|
# replace the url in the css file with the data uri
|
71
|
-
@contents.gsub!(asset.path, embed_data_uri(asset.
|
71
|
+
@contents.gsub!(asset.path, embed_data_uri(asset.filename)) if asset.filename.match( /\?embed=true$/ )
|
72
72
|
else
|
73
73
|
Juicer::LOGGER.warn("The final data uri for the image located at #{asset.path.gsub('?embed=true', '')} exceeds #{SIZE_LIMIT} and will not be embedded to maintain compatability.")
|
74
74
|
end
|
@@ -86,25 +86,23 @@ module Juicer
|
|
86
86
|
def embed_data_uri( path )
|
87
87
|
new_path = path
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
supported_file_matches = path.match( /(?:\.)(png|gif|jpg|jpeg)(?:\?embed=true)$/i )
|
90
|
+
filetype = supported_file_matches[1] if supported_file_matches
|
91
|
+
|
92
|
+
if ( filetype )
|
93
|
+
filename = path.gsub('?embed=true','')
|
92
94
|
|
93
|
-
if
|
94
|
-
|
95
|
-
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
new_path = Datafy::make_data_uri( content, content_type )
|
105
|
-
else
|
106
|
-
puts "Unable to locate file #{filename} on local file system, skipping image embedding"
|
107
|
-
end
|
95
|
+
# check if file exists, throw an error if it doesn't exist
|
96
|
+
if File.exist?( filename )
|
97
|
+
|
98
|
+
# read contents of file into memory
|
99
|
+
content = File.read( filename )
|
100
|
+
content_type = "image/#{filetype}"
|
101
|
+
|
102
|
+
# encode the url
|
103
|
+
new_path = Datafy::make_data_uri( content, content_type )
|
104
|
+
else
|
105
|
+
puts "Unable to locate file #{filename} on local file system, skipping image embedding"
|
108
106
|
end
|
109
107
|
end
|
110
108
|
return new_path
|
@@ -60,8 +60,9 @@ module Juicer
|
|
60
60
|
def latest
|
61
61
|
return @latest if @latest
|
62
62
|
webpage = Nokogiri::HTML(open(@website))
|
63
|
-
@latest = (webpage / "
|
63
|
+
@latest = (webpage / "h3#yuicompressor + ul li a:last").text.match(/(\d\.\d\.\d)/)[1]
|
64
64
|
end
|
65
|
+
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
@@ -53,13 +53,13 @@ module Juicer
|
|
53
53
|
# for all absolute URLs regardless of absolute/relative URL strategy.
|
54
54
|
#
|
55
55
|
def merge(file)
|
56
|
-
content = super.gsub(/^\s*@import(?:\surl\(|\s)(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]
|
56
|
+
content = super.gsub(/^\s*@import(?:\surl\(|\s)(['"]?)([^\?'"\)\s]+)(\?(?:[^'"\)]*))?\1\)?(?:[^?;]*);?/i, "")
|
57
57
|
dir = File.expand_path(File.dirname(file))
|
58
58
|
|
59
59
|
content.scan(/url\([\s"']*([^\)"'\s]*)[\s"']*\)/m).uniq.collect do |url|
|
60
60
|
url = url.first
|
61
61
|
path = resolve_path(url, dir)
|
62
|
-
content.gsub!(/\(
|
62
|
+
content.gsub!(/\([\s"']*#{url}[\s"']*\)/m, "(#{path})") unless path == url
|
63
63
|
end
|
64
64
|
|
65
65
|
content
|
@@ -79,7 +79,7 @@ module Juicer
|
|
79
79
|
|
80
80
|
# All URLs that don't start with a protocol
|
81
81
|
if url !~ %r{^/} && url !~ %r{^[a-z]+://}
|
82
|
-
if @use_absolute
|
82
|
+
if @use_absolute || @hosts.length > 0
|
83
83
|
raise ArgumentError.new("Unable to handle absolute URLs without :document_root option") if !@document_root
|
84
84
|
path = File.expand_path(File.join(dir, url)).sub(@document_root, "") # Make absolute
|
85
85
|
else
|
@@ -88,8 +88,8 @@ module Juicer
|
|
88
88
|
end
|
89
89
|
|
90
90
|
# Cycle hosts, if any
|
91
|
-
if
|
92
|
-
path = File.join(@hosts[@host_num % @hosts.length],
|
91
|
+
if path =~ %r{^/} && @hosts.length > 0
|
92
|
+
path = File.join(@hosts[@host_num % @hosts.length], path)
|
93
93
|
@host_num += 1
|
94
94
|
end
|
95
95
|
|
@@ -62,7 +62,7 @@ module Juicer
|
|
62
62
|
|
63
63
|
out_dir = File.dirname(output)
|
64
64
|
FileUtils.mkdir_p(out_dir) unless File.exists?(out_dir)
|
65
|
-
|
65
|
+
execute(%Q{-jar "#{locate_jar}"#{jar_args} --js_output_file "#{output}" --js "#{file}"})
|
66
66
|
|
67
67
|
File.delete(file) if use_tmp
|
68
68
|
end
|
data/lib/juicer.rb
CHANGED
data/lib/psyho_juicer.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path('juicer', File.dirname(__FILE__)) unless defined?(Juicer)
|
data/test/data/a.css
ADDED
data/test/data/a.js
ADDED
data/test/data/a1.css
ADDED
data/test/data/b.css
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/* Dette er b.css */
|
data/test/data/b.js
ADDED
data/test/data/b1.css
ADDED
data/test/data/b2.css
ADDED
data/test/data/c1.css
ADDED
data/test/data/css/2.gif
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
body { background: url(/images/1.png); }
|
data/test/data/d1.css
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/test/data/my_app.js
ADDED
data/test/data/not-ok.js
ADDED
data/test/data/ok.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
var pkg = {};
|
@@ -0,0 +1 @@
|
|
1
|
+
DO NOT MODIFY
|