sinatra-assetpack-flexible-compression 0.0.1
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/.gitignore +4 -0
- data/Gemfile +2 -0
- data/HISTORY.md +131 -0
- data/README.md +664 -0
- data/Rakefile +31 -0
- data/docsrc/style.css +32 -0
- data/examples/basic/.gitignore +1 -0
- data/examples/basic/Rakefile +7 -0
- data/examples/basic/app.rb +39 -0
- data/examples/basic/app/css/test.sass +11 -0
- data/examples/basic/app/images/icon.png +0 -0
- data/examples/basic/app/js/app.js +4 -0
- data/examples/basic/app/js/vendor/jquery.js +2 -0
- data/examples/basic/app/js/vendor/jquery.plugin.js +2 -0
- data/examples/basic/app/js/vendor/underscore.js +2 -0
- data/examples/basic/views/index.erb +26 -0
- data/examples/classic/app.rb +24 -0
- data/examples/classic/css/screen.scss +1 -0
- data/examples/compass/.gitignore +1 -0
- data/examples/compass/Rakefile +7 -0
- data/examples/compass/app.rb +45 -0
- data/examples/compass/app/css/main.scss +64 -0
- data/examples/compass/app/images/icon-scfd8d7d404.png +0 -0
- data/examples/compass/app/images/icon/mail.png +0 -0
- data/examples/compass/app/images/icon/refresh.png +0 -0
- data/examples/compass/app/images/junk/mail.png +0 -0
- data/examples/compass/app/images/junk/refresh.png +0 -0
- data/examples/compass/app/js/app.js +3 -0
- data/examples/compass/app/js/vendor/jquery.js +2 -0
- data/examples/compass/app/js/vendor/jquery.plugin.js +2 -0
- data/examples/compass/app/js/vendor/underscore.js +2 -0
- data/examples/compass/config.ru +3 -0
- data/examples/compass/views/index.erb +15 -0
- data/lib/sinatra/assetpack.rb +61 -0
- data/lib/sinatra/assetpack/buster_helpers.rb +36 -0
- data/lib/sinatra/assetpack/class_methods.rb +82 -0
- data/lib/sinatra/assetpack/compressor.rb +54 -0
- data/lib/sinatra/assetpack/configurator.rb +21 -0
- data/lib/sinatra/assetpack/css.rb +36 -0
- data/lib/sinatra/assetpack/engine.rb +20 -0
- data/lib/sinatra/assetpack/engines/closure.rb +19 -0
- data/lib/sinatra/assetpack/engines/jsmin.rb +10 -0
- data/lib/sinatra/assetpack/engines/sass.rb +11 -0
- data/lib/sinatra/assetpack/engines/simple.rb +11 -0
- data/lib/sinatra/assetpack/engines/sqwish.rb +21 -0
- data/lib/sinatra/assetpack/engines/uglify.rb +12 -0
- data/lib/sinatra/assetpack/engines/yui.rb +22 -0
- data/lib/sinatra/assetpack/hasharray.rb +66 -0
- data/lib/sinatra/assetpack/helpers.rb +61 -0
- data/lib/sinatra/assetpack/html_helpers.rb +17 -0
- data/lib/sinatra/assetpack/image.rb +59 -0
- data/lib/sinatra/assetpack/options.rb +326 -0
- data/lib/sinatra/assetpack/package.rb +116 -0
- data/lib/sinatra/assetpack/rake.rb +29 -0
- data/lib/sinatra/assetpack/version.rb +7 -0
- data/test/app/.gitignore +1 -0
- data/test/app/Rakefile +7 -0
- data/test/app/app.rb +62 -0
- data/test/app/app/css/behavior.htc +1 -0
- data/test/app/app/css/js2c.css +494 -0
- data/test/app/app/css/screen.sass +9 -0
- data/test/app/app/css/sqwishable.css +7 -0
- data/test/app/app/css/style.css +3 -0
- data/test/app/app/css/stylus.styl +3 -0
- data/test/app/app/css_stylus/stylus.styl +3 -0
- data/test/app/app/images/background.jpg +1 -0
- data/test/app/app/images/email.png +0 -0
- data/test/app/app/js/_ignoreme.js +1 -0
- data/test/app/app/js/hello.js +1 -0
- data/test/app/app/js/hi.coffee +2 -0
- data/test/app/app/js/ugly.js +7 -0
- data/test/app/app/js_glob/a/b/c1/hello.js +1 -0
- data/test/app/app/js_glob/a/b/c2/hi.js +1 -0
- data/test/app/app/js_glob/a/b/c2/hola.js +1 -0
- data/test/app/app/views/index.haml +1 -0
- data/test/arity_test.rb +26 -0
- data/test/build_test.rb +31 -0
- data/test/cache_test.rb +9 -0
- data/test/compressed_test.rb +30 -0
- data/test/glob_test.rb +42 -0
- data/test/helpers_test.rb +30 -0
- data/test/ignore_test.rb +30 -0
- data/test/img_test.rb +31 -0
- data/test/local_file_test.rb +21 -0
- data/test/mime_type_test.rb +33 -0
- data/test/non_existent_test.rb +45 -0
- data/test/options_test.rb +21 -0
- data/test/order_test.rb +20 -0
- data/test/preproc_test.rb +28 -0
- data/test/redundant_test.rb +11 -0
- data/test/simplecss_test.rb +16 -0
- data/test/sqwish_test.rb +31 -0
- data/test/stylus_test.rb +23 -0
- data/test/template_cache_test.rb +29 -0
- data/test/test_helper.rb +46 -0
- data/test/tilt_test.rb +11 -0
- data/test/uglifier_test.rb +23 -0
- data/test/unit_test.rb +109 -0
- data/test/yui_test.rb +22 -0
- metadata +276 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module AssetPack
|
3
|
+
module HtmlHelpers
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def e(str)
|
7
|
+
re = Rack::Utils.escape_html str
|
8
|
+
re = re.gsub("/", '/') # Rack sometimes insists on munging slashes in Ruby 1.8.
|
9
|
+
re
|
10
|
+
end
|
11
|
+
|
12
|
+
def kv(hash)
|
13
|
+
hash.map { |k, v| " #{e k}='#{e v}'" }.join('')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module AssetPack
|
3
|
+
# An image.
|
4
|
+
#
|
5
|
+
# == Common usage
|
6
|
+
#
|
7
|
+
# i = Image['/app/images/background.png'] # Local file path
|
8
|
+
#
|
9
|
+
# i.dimensions # Tuple for [ width, height ]
|
10
|
+
# i.width
|
11
|
+
# i.height
|
12
|
+
#
|
13
|
+
# i.dimensions? # True if dimensions are available
|
14
|
+
# # (e.g., if ImageMagick is installed and working)
|
15
|
+
#
|
16
|
+
class Image
|
17
|
+
# Looks up an image.
|
18
|
+
# This makes each image only have one associated instance forever.
|
19
|
+
def self.[](fname)
|
20
|
+
fname = File.expand_path(fname) || fname
|
21
|
+
|
22
|
+
@cache ||= Hash.new
|
23
|
+
@cache[fname] ||= new fname
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(file)
|
27
|
+
@file = file
|
28
|
+
end
|
29
|
+
|
30
|
+
def dimensions
|
31
|
+
return @dimensions unless @dimensions.nil?
|
32
|
+
|
33
|
+
_, _, dim = `identify "#{@file}"`.split(' ')
|
34
|
+
w, h = dim.split('x')
|
35
|
+
|
36
|
+
if w.to_i != 0 && h.to_i != 0
|
37
|
+
@dimensions = [w.to_i, h.to_i]
|
38
|
+
else
|
39
|
+
@dimensions = false
|
40
|
+
end
|
41
|
+
|
42
|
+
rescue => e
|
43
|
+
@dimensions = false
|
44
|
+
end
|
45
|
+
|
46
|
+
def dimensions?
|
47
|
+
!! dimensions
|
48
|
+
end
|
49
|
+
|
50
|
+
def width
|
51
|
+
dimensions? && dimensions[0]
|
52
|
+
end
|
53
|
+
|
54
|
+
def height
|
55
|
+
dimensions? && dimensions[1]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,326 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module AssetPack
|
3
|
+
# Assets.
|
4
|
+
#
|
5
|
+
# == Common usage
|
6
|
+
#
|
7
|
+
# SinatraApp.assets {
|
8
|
+
# # dsl stuff here
|
9
|
+
# }
|
10
|
+
#
|
11
|
+
# a = SinatraApp.assets
|
12
|
+
#
|
13
|
+
# Getting options:
|
14
|
+
#
|
15
|
+
# a.js_compression
|
16
|
+
# a.output_path
|
17
|
+
#
|
18
|
+
# Served:
|
19
|
+
#
|
20
|
+
# a.served # { '/js' => '/var/www/project/app/js', ... }
|
21
|
+
# # (URL path => local path)
|
22
|
+
#
|
23
|
+
# Packages:
|
24
|
+
#
|
25
|
+
# a.packages # { 'app.css' => #<Package>, ... }
|
26
|
+
# # (name.type => package instance)
|
27
|
+
#
|
28
|
+
# Build:
|
29
|
+
#
|
30
|
+
# a.build! { |path| puts "Building #{path}" }
|
31
|
+
#
|
32
|
+
# Lookup:
|
33
|
+
#
|
34
|
+
# a.local_path_for('/images/bg.gif')
|
35
|
+
# a.served?('/images/bg.gif')
|
36
|
+
#
|
37
|
+
# a.glob(['/js/*.js', '/js/vendor/**/*.js'])
|
38
|
+
# # Returns a HashArray of (local => remote)
|
39
|
+
#
|
40
|
+
class Options
|
41
|
+
include Configurator
|
42
|
+
|
43
|
+
def initialize(app, &blk)
|
44
|
+
unless app.root?
|
45
|
+
raise Error, "Please set :root in your Sinatra app."
|
46
|
+
end
|
47
|
+
|
48
|
+
@app = app
|
49
|
+
@js_compression = :jsmin
|
50
|
+
@css_compression = :simple
|
51
|
+
|
52
|
+
begin
|
53
|
+
@output_path = app.public
|
54
|
+
rescue NoMethodError
|
55
|
+
@output_path = app.public_folder
|
56
|
+
end
|
57
|
+
|
58
|
+
@js_compression_options = Hash.new
|
59
|
+
@css_compression_options = Hash.new
|
60
|
+
|
61
|
+
@ignored = Array.new
|
62
|
+
|
63
|
+
reset!
|
64
|
+
|
65
|
+
# Defaults!
|
66
|
+
serve '/css', :from => 'app/css'
|
67
|
+
serve '/js', :from => 'app/js'
|
68
|
+
serve '/images', :from => 'app/images'
|
69
|
+
|
70
|
+
ignore '.*'
|
71
|
+
ignore '_*'
|
72
|
+
|
73
|
+
blk.arity <= 0 ? instance_eval(&blk) : yield(self) if block_given?
|
74
|
+
end
|
75
|
+
|
76
|
+
# =====================================================================
|
77
|
+
# DSL methods
|
78
|
+
|
79
|
+
def serve(path, options={})
|
80
|
+
raise Error unless options[:from]
|
81
|
+
return unless File.directory?(File.join(app.root, options[:from]))
|
82
|
+
|
83
|
+
@served[path] = options[:from]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Undo defaults.
|
87
|
+
def reset!
|
88
|
+
@served = Hash.new
|
89
|
+
@packages = Hash.new
|
90
|
+
end
|
91
|
+
|
92
|
+
# Ignores a given path spec.
|
93
|
+
def ignore(spec)
|
94
|
+
if spec[0] == '/'
|
95
|
+
@ignored << "#{spec}"
|
96
|
+
@ignored << "#{spec}/**"
|
97
|
+
else
|
98
|
+
@ignored << "**/#{spec}"
|
99
|
+
@ignored << "**/#{spec}/**"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Makes nothing ignored. Use this if you don't want to ignore dotfiles and underscore files.
|
104
|
+
def clear_ignores!
|
105
|
+
@ignored = Array.new
|
106
|
+
end
|
107
|
+
|
108
|
+
# Checks if a given path is ignored.
|
109
|
+
def ignored?(fn)
|
110
|
+
@ignored.any? { |spec| File.fnmatch spec, fn }
|
111
|
+
end
|
112
|
+
|
113
|
+
# Adds some JS packages.
|
114
|
+
#
|
115
|
+
# js :foo, [ '/js/vendor/jquery.*.js', ... ]
|
116
|
+
# js :foo, '/js/foo.js', [ '/js/vendor/jquery.*.js', ... ]
|
117
|
+
#
|
118
|
+
def js(name, *args)
|
119
|
+
js_or_css :js, name, *args
|
120
|
+
end
|
121
|
+
|
122
|
+
# Adds some CSS packages.
|
123
|
+
#
|
124
|
+
# css :app, [ '/css/screen.css', ... ]
|
125
|
+
# css :app, '/css/app.css', [ '/css/screen.css', ... ]
|
126
|
+
#
|
127
|
+
def css(name, *args) #path, files=[])
|
128
|
+
js_or_css :css, name, *args
|
129
|
+
end
|
130
|
+
|
131
|
+
def js_or_css(type, name, *args)
|
132
|
+
# Account for "css :name, '/path/to/css', [ files ]"
|
133
|
+
if args[0].is_a?(String) && args[1].respond_to?(:each)
|
134
|
+
path, files = args
|
135
|
+
|
136
|
+
# Account for "css :name, [ files ]"
|
137
|
+
elsif args[0].respond_to?(:each)
|
138
|
+
path = "/assets/#{name}.#{type}" # /assets/foobar.css by default
|
139
|
+
files = args[0]
|
140
|
+
|
141
|
+
else
|
142
|
+
raise ArgumentError
|
143
|
+
end
|
144
|
+
|
145
|
+
@packages["#{name}.#{type}"] = Package.new(self, name, type, path, files)
|
146
|
+
end
|
147
|
+
|
148
|
+
attr_reader :app # Sinatra::Base instance
|
149
|
+
attr_reader :packages # Hash, keys are "foo.js", values are Packages
|
150
|
+
attr_reader :served # Hash, paths to be served.
|
151
|
+
# Key is URI path, value is local path
|
152
|
+
|
153
|
+
attrib :js_compression # Symbol, compression method for JS
|
154
|
+
attrib :css_compression # Symbol, compression method for CSS
|
155
|
+
attrib :output_path # '/public'
|
156
|
+
|
157
|
+
attrib :js_compression_options # Hash
|
158
|
+
attrib :css_compression_options # Hash
|
159
|
+
|
160
|
+
attrib :prebuild # Bool
|
161
|
+
|
162
|
+
def js_compression(name=nil, options=nil)
|
163
|
+
@js_compression = name unless name.nil?
|
164
|
+
@js_compression_options = options if options.is_a?(Hash)
|
165
|
+
@js_compression
|
166
|
+
end
|
167
|
+
|
168
|
+
def css_compression(name=nil, options=nil)
|
169
|
+
@css_compression = name unless name.nil?
|
170
|
+
@css_compression_options = options if options.is_a?(Hash)
|
171
|
+
@css_compression
|
172
|
+
end
|
173
|
+
|
174
|
+
# =====================================================================
|
175
|
+
# Stuff
|
176
|
+
|
177
|
+
attr_reader :served
|
178
|
+
|
179
|
+
def build!(&blk)
|
180
|
+
session = Rack::Test::Session.new app
|
181
|
+
|
182
|
+
get = lambda { |path|
|
183
|
+
response = session.get(path)
|
184
|
+
out = response.body
|
185
|
+
mtime = Time.parse(response.headers['Last-Modified']) if response.headers['Last-Modified']
|
186
|
+
|
187
|
+
[ out, mtime ]
|
188
|
+
}
|
189
|
+
|
190
|
+
packages.each { |_, pack|
|
191
|
+
out, mtime = get[pack.path]
|
192
|
+
|
193
|
+
write pack.path, out, mtime, &blk
|
194
|
+
write pack.production_path, out, mtime, &blk
|
195
|
+
}
|
196
|
+
|
197
|
+
files.each { |path, local|
|
198
|
+
out, mtime = get[path]
|
199
|
+
|
200
|
+
write path, out, mtime, &blk
|
201
|
+
write BusterHelpers.add_cache_buster(path, local), out, mtime, &blk
|
202
|
+
}
|
203
|
+
end
|
204
|
+
|
205
|
+
# Caches the packages.
|
206
|
+
def cache!(&blk)
|
207
|
+
return false if app.reload_templates
|
208
|
+
|
209
|
+
session = Rack::Test::Session.new app
|
210
|
+
packages.each { |_, pack|
|
211
|
+
yield pack.path if block_given?
|
212
|
+
session.get(pack.path)
|
213
|
+
}
|
214
|
+
|
215
|
+
true
|
216
|
+
end
|
217
|
+
|
218
|
+
def served?(path)
|
219
|
+
!! local_file_for(path)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Returns the local file for a given URI path.
|
223
|
+
# Returns nil if a file is not found.
|
224
|
+
def local_file_for(path)
|
225
|
+
path = path.squeeze('/')
|
226
|
+
|
227
|
+
uri, local = served.detect { |uri, local| path[0...uri.size] == uri }
|
228
|
+
|
229
|
+
if local
|
230
|
+
path = path[uri.size..-1]
|
231
|
+
path = File.join app.root, local, path
|
232
|
+
|
233
|
+
path if File.exists?(path)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Returns the local file for a given URI path. (for dynamic files)
|
238
|
+
# Returns nil if a file is not found.
|
239
|
+
# TODO: consolidate with local_file_for
|
240
|
+
def dyn_local_file_for(file, from)
|
241
|
+
# Remove extension
|
242
|
+
file = $1 if file =~ /^(.*)(\.[^\.]+)$/
|
243
|
+
|
244
|
+
# Remove cache-buster (/js/app.28389.js => /js/app)
|
245
|
+
file = $1 if file =~ /^(.*)\.[0-9]+$/
|
246
|
+
|
247
|
+
Dir[File.join(app.root, from, "#{file}.*")].first
|
248
|
+
end
|
249
|
+
|
250
|
+
# Writes `public/#{path}` based on contents of `output`.
|
251
|
+
def write(path, output, mtime=nil)
|
252
|
+
require 'fileutils'
|
253
|
+
|
254
|
+
path = File.join(@output_path, path)
|
255
|
+
yield path if block_given?
|
256
|
+
|
257
|
+
FileUtils.mkdir_p File.dirname(path)
|
258
|
+
File.open(path, 'w') { |f| f.write output }
|
259
|
+
|
260
|
+
if mtime
|
261
|
+
File.utime mtime, mtime, path
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Returns the files as a hash.
|
266
|
+
def files(match=nil)
|
267
|
+
# All
|
268
|
+
# A buncha tuples
|
269
|
+
tuples = @served.map { |prefix, local_path|
|
270
|
+
path = File.expand_path(File.join(@app.root, local_path))
|
271
|
+
spec = File.join(path, '**', '*')
|
272
|
+
|
273
|
+
Dir[spec].map { |f|
|
274
|
+
[ to_uri(f, prefix, path), f ] unless File.directory?(f)
|
275
|
+
}
|
276
|
+
}.flatten.compact
|
277
|
+
|
278
|
+
Hash[*tuples]
|
279
|
+
end
|
280
|
+
|
281
|
+
# Returns an array of URI paths of those matching given globs.
|
282
|
+
#
|
283
|
+
# glob('spec')
|
284
|
+
# glob(['spec1', 'spec2' ...])
|
285
|
+
# glob('spec', preserve: true)
|
286
|
+
#
|
287
|
+
# If `preserve` is set to true, it will preserve any specs that are not
|
288
|
+
# wildcards that don't match anything.
|
289
|
+
#
|
290
|
+
def glob(match, options={})
|
291
|
+
|
292
|
+
match = [*match] # Force array-ness
|
293
|
+
|
294
|
+
paths = match.map { |spec|
|
295
|
+
if options[:preserve] && !spec.include?('*')
|
296
|
+
spec
|
297
|
+
else
|
298
|
+
files.keys.select { |f| File.fnmatch?(spec, f) }.sort
|
299
|
+
end
|
300
|
+
}.flatten
|
301
|
+
|
302
|
+
paths = paths.uniq
|
303
|
+
tuples = paths.map { |key| [key, files[key]] }
|
304
|
+
|
305
|
+
HashArray[*tuples.flatten]
|
306
|
+
end
|
307
|
+
|
308
|
+
private
|
309
|
+
# Returns a URI for a given file
|
310
|
+
# path = '/projects/x/app/css'
|
311
|
+
# to_uri('/projects/x/app/css/file.sass', '/styles', path) => '/styles/file.css'
|
312
|
+
#
|
313
|
+
def to_uri(f, prefix, path)
|
314
|
+
fn = (prefix + f.gsub(path, '')).squeeze('/')
|
315
|
+
|
316
|
+
# Switch the extension ('x.sass' => 'x.css')
|
317
|
+
file_ext = File.extname(fn).to_s[1..-1]
|
318
|
+
out_ext = AssetPack.tilt_formats[file_ext]
|
319
|
+
|
320
|
+
fn = fn.gsub(/\.#{file_ext}$/, ".#{out_ext}") if file_ext && out_ext
|
321
|
+
|
322
|
+
fn
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module AssetPack
|
3
|
+
# A package.
|
4
|
+
#
|
5
|
+
# == Common usage
|
6
|
+
#
|
7
|
+
# package = assets.packages['application.css']
|
8
|
+
#
|
9
|
+
# package.files # List of local files
|
10
|
+
# package.paths # List of URI paths
|
11
|
+
#
|
12
|
+
# package.type # :css or :js
|
13
|
+
# package.css?
|
14
|
+
# package.js?
|
15
|
+
#
|
16
|
+
# package.path # '/css/application.css' => where to serve the compressed file
|
17
|
+
#
|
18
|
+
# package.to_development_html
|
19
|
+
# package.to_production_html
|
20
|
+
#
|
21
|
+
class Package
|
22
|
+
include HtmlHelpers
|
23
|
+
include BusterHelpers
|
24
|
+
|
25
|
+
def initialize(assets, name, type, path, filespecs)
|
26
|
+
@assets = assets # Options instance
|
27
|
+
@name = name # "application"
|
28
|
+
@type = type # :js or :css
|
29
|
+
@path = path # '/js/app.js' -- where to served the compressed file
|
30
|
+
@filespecs = filespecs # [ '/js/*.js' ]
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :type
|
34
|
+
attr_reader :path
|
35
|
+
attr_reader :filespecs
|
36
|
+
attr_reader :name
|
37
|
+
|
38
|
+
# Returns a list of URIs
|
39
|
+
def paths_and_files
|
40
|
+
list = @assets.glob(@filespecs, :preserve => true)
|
41
|
+
list.reject! { |path, file| @assets.ignored?(path) }
|
42
|
+
list
|
43
|
+
end
|
44
|
+
|
45
|
+
def files
|
46
|
+
paths_and_files.values
|
47
|
+
end
|
48
|
+
|
49
|
+
def paths
|
50
|
+
paths_and_files.keys
|
51
|
+
end
|
52
|
+
|
53
|
+
def mtime
|
54
|
+
BusterHelpers.mtime_for(files)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the regex for the route, including cache buster crap.
|
58
|
+
def route_regex
|
59
|
+
re = @path.gsub(/(.[^.]+)$/) { |ext| "(?:\.[0-9]+)?#{ext}" }
|
60
|
+
/^#{re}$/
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_development_html(options={})
|
64
|
+
paths_and_files.map { |path, file|
|
65
|
+
path = add_cache_buster(path, file) # app.css => app.829378.css
|
66
|
+
link_tag(path, options)
|
67
|
+
}.join("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
# The URI path of the minified file (with cache buster)
|
71
|
+
def production_path
|
72
|
+
add_cache_buster @path, *files
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_production_html(options={})
|
76
|
+
link_tag production_path, options
|
77
|
+
end
|
78
|
+
|
79
|
+
def minify
|
80
|
+
engine = @assets.send(:"#{@type}_compression")
|
81
|
+
options = @assets.send(:"#{@type}_compression_options")
|
82
|
+
|
83
|
+
Compressor.compress combined, @type, engine, options
|
84
|
+
end
|
85
|
+
|
86
|
+
# The cache hash.
|
87
|
+
def hash
|
88
|
+
if @assets.app.development?
|
89
|
+
"#{name}.#{type}/#{mtime}"
|
90
|
+
else
|
91
|
+
"#{name}.#{type}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def combined
|
96
|
+
session = Rack::Test::Session.new(@assets.app)
|
97
|
+
paths.map { |path|
|
98
|
+
result = session.get(path)
|
99
|
+
result.body if result.status == 200
|
100
|
+
}.join("\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
def js?() @type == :js; end
|
104
|
+
def css?() @type == :css; end
|
105
|
+
|
106
|
+
private
|
107
|
+
def link_tag(file, options={})
|
108
|
+
if js?
|
109
|
+
"<script src='#{e file}'#{kv options}></script>"
|
110
|
+
elsif css?
|
111
|
+
"<link rel='stylesheet' href='#{e file}'#{kv options} />"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|