sprockets 2.2.3 → 2.12.5
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 +5 -5
- data/README.md +135 -4
- data/bin/sprockets +8 -0
- data/lib/rake/sprocketstask.rb +24 -13
- data/lib/sprockets.rb +52 -8
- data/lib/sprockets/asset.rb +17 -8
- data/lib/sprockets/asset_attributes.rb +15 -4
- data/lib/sprockets/base.rb +155 -15
- data/lib/sprockets/bundled_asset.rb +5 -6
- data/lib/sprockets/caching.rb +39 -39
- data/lib/sprockets/closure_compressor.rb +22 -0
- data/lib/sprockets/compressing.rb +73 -0
- data/lib/sprockets/context.rb +57 -3
- data/lib/sprockets/directive_processor.rb +3 -1
- data/lib/sprockets/engines.rb +4 -4
- data/lib/sprockets/environment.rb +12 -15
- data/lib/sprockets/errors.rb +1 -0
- data/lib/sprockets/index.rb +1 -0
- data/lib/sprockets/jst_processor.rb +2 -6
- data/lib/sprockets/manifest.rb +77 -19
- data/lib/sprockets/mime.rb +5 -4
- data/lib/sprockets/{trail.rb → paths.rb} +5 -37
- data/lib/sprockets/processed_asset.rb +1 -1
- data/lib/sprockets/processing.rb +3 -77
- data/lib/sprockets/processor.rb +1 -1
- data/lib/sprockets/sass_cache_store.rb +29 -0
- data/lib/sprockets/sass_compressor.rb +27 -0
- data/lib/sprockets/sass_functions.rb +70 -0
- data/lib/sprockets/sass_importer.rb +30 -0
- data/lib/sprockets/sass_template.rb +66 -0
- data/lib/sprockets/scss_template.rb +13 -0
- data/lib/sprockets/server.rb +1 -1
- data/lib/sprockets/static_asset.rb +4 -1
- data/lib/sprockets/uglifier_compressor.rb +29 -0
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +27 -0
- metadata +88 -7
@@ -19,7 +19,7 @@ module Sprockets
|
|
19
19
|
@dependency_digest = compute_dependency_digest(environment)
|
20
20
|
|
21
21
|
elapsed_time = ((Time.now.to_f - start_time) * 1000).to_i
|
22
|
-
environment.logger.
|
22
|
+
environment.logger.debug "Compiled #{logical_path} (#{elapsed_time}ms) (pid #{Process.pid})"
|
23
23
|
end
|
24
24
|
|
25
25
|
# Interal: Used to check equality
|
data/lib/sprockets/processing.rb
CHANGED
@@ -7,16 +7,6 @@ module Sprockets
|
|
7
7
|
# `Processing` is an internal mixin whose public methods are exposed on
|
8
8
|
# the `Environment` and `Index` classes.
|
9
9
|
module Processing
|
10
|
-
include Engines, Mime
|
11
|
-
|
12
|
-
# Register a new mime type.
|
13
|
-
def register_mime_type(mime_type, ext)
|
14
|
-
# Overrides the global behavior to expire the index
|
15
|
-
expire_index!
|
16
|
-
@trail.append_extension(ext)
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
10
|
# Returns an `Array` of format extension `String`s.
|
21
11
|
#
|
22
12
|
# format_extensions
|
@@ -26,14 +16,6 @@ module Sprockets
|
|
26
16
|
@trail.extensions - @engines.keys
|
27
17
|
end
|
28
18
|
|
29
|
-
# Registers a new Engine `klass` for `ext`.
|
30
|
-
def register_engine(ext, klass)
|
31
|
-
# Overrides the global behavior to expire the index
|
32
|
-
expire_index!
|
33
|
-
add_engine_to_trail(ext, klass)
|
34
|
-
super
|
35
|
-
end
|
36
|
-
|
37
19
|
# Deprecated alias for `preprocessors`.
|
38
20
|
def processors(*args)
|
39
21
|
preprocessors(*args)
|
@@ -83,13 +65,11 @@ module Sprockets
|
|
83
65
|
#
|
84
66
|
# A block can be passed for to create a shorthand processor.
|
85
67
|
#
|
86
|
-
# register_preprocessor :my_processor do |context, data|
|
68
|
+
# register_preprocessor 'text/css', :my_processor do |context, data|
|
87
69
|
# data.gsub(...)
|
88
70
|
# end
|
89
71
|
#
|
90
72
|
def register_preprocessor(mime_type, klass, &block)
|
91
|
-
expire_index!
|
92
|
-
|
93
73
|
if block_given?
|
94
74
|
name = klass.to_s
|
95
75
|
klass = Class.new(Processor) do
|
@@ -107,13 +87,11 @@ module Sprockets
|
|
107
87
|
#
|
108
88
|
# A block can be passed for to create a shorthand processor.
|
109
89
|
#
|
110
|
-
# register_postprocessor :my_processor do |context, data|
|
90
|
+
# register_postprocessor 'text/css', :my_processor do |context, data|
|
111
91
|
# data.gsub(...)
|
112
92
|
# end
|
113
93
|
#
|
114
94
|
def register_postprocessor(mime_type, klass, &block)
|
115
|
-
expire_index!
|
116
|
-
|
117
95
|
if block_given?
|
118
96
|
name = klass.to_s
|
119
97
|
klass = Class.new(Processor) do
|
@@ -135,8 +113,6 @@ module Sprockets
|
|
135
113
|
# unregister_preprocessor 'text/css', Sprockets::DirectiveProcessor
|
136
114
|
#
|
137
115
|
def unregister_preprocessor(mime_type, klass)
|
138
|
-
expire_index!
|
139
|
-
|
140
116
|
if klass.is_a?(String) || klass.is_a?(Symbol)
|
141
117
|
klass = @preprocessors[mime_type].detect { |cls|
|
142
118
|
cls.respond_to?(:name) &&
|
@@ -152,8 +128,6 @@ module Sprockets
|
|
152
128
|
# unregister_postprocessor 'text/css', Sprockets::DirectiveProcessor
|
153
129
|
#
|
154
130
|
def unregister_postprocessor(mime_type, klass)
|
155
|
-
expire_index!
|
156
|
-
|
157
131
|
if klass.is_a?(String) || klass.is_a?(Symbol)
|
158
132
|
klass = @postprocessors[mime_type].detect { |cls|
|
159
133
|
cls.respond_to?(:name) &&
|
@@ -187,13 +161,11 @@ module Sprockets
|
|
187
161
|
#
|
188
162
|
# A block can be passed for to create a shorthand processor.
|
189
163
|
#
|
190
|
-
# register_bundle_processor :my_processor do |context, data|
|
164
|
+
# register_bundle_processor 'text/css', :my_processor do |context, data|
|
191
165
|
# data.gsub(...)
|
192
166
|
# end
|
193
167
|
#
|
194
168
|
def register_bundle_processor(mime_type, klass, &block)
|
195
|
-
expire_index!
|
196
|
-
|
197
169
|
if block_given?
|
198
170
|
name = klass.to_s
|
199
171
|
klass = Class.new(Processor) do
|
@@ -210,8 +182,6 @@ module Sprockets
|
|
210
182
|
# unregister_bundle_processor 'text/css', Sprockets::CharsetNormalizer
|
211
183
|
#
|
212
184
|
def unregister_bundle_processor(mime_type, klass)
|
213
|
-
expire_index!
|
214
|
-
|
215
185
|
if klass.is_a?(String) || klass.is_a?(Symbol)
|
216
186
|
klass = @bundle_processors[mime_type].detect { |cls|
|
217
187
|
cls.respond_to?(:name) &&
|
@@ -222,50 +192,6 @@ module Sprockets
|
|
222
192
|
@bundle_processors[mime_type].delete(klass)
|
223
193
|
end
|
224
194
|
|
225
|
-
# Return CSS compressor or nil if none is set
|
226
|
-
def css_compressor
|
227
|
-
bundle_processors('text/css').detect { |klass|
|
228
|
-
klass.respond_to?(:name) &&
|
229
|
-
klass.name == 'Sprockets::Processor (css_compressor)'
|
230
|
-
}
|
231
|
-
end
|
232
|
-
|
233
|
-
# Assign a compressor to run on `text/css` assets.
|
234
|
-
#
|
235
|
-
# The compressor object must respond to `compress` or `compile`.
|
236
|
-
def css_compressor=(compressor)
|
237
|
-
expire_index!
|
238
|
-
|
239
|
-
unregister_bundle_processor 'text/css', :css_compressor
|
240
|
-
return unless compressor
|
241
|
-
|
242
|
-
register_bundle_processor 'text/css', :css_compressor do |context, data|
|
243
|
-
compressor.compress(data)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
# Return JS compressor or nil if none is set
|
248
|
-
def js_compressor
|
249
|
-
bundle_processors('application/javascript').detect { |klass|
|
250
|
-
klass.respond_to?(:name) &&
|
251
|
-
klass.name == 'Sprockets::Processor (js_compressor)'
|
252
|
-
}
|
253
|
-
end
|
254
|
-
|
255
|
-
# Assign a compressor to run on `application/javascript` assets.
|
256
|
-
#
|
257
|
-
# The compressor object must respond to `compress` or `compile`.
|
258
|
-
def js_compressor=(compressor)
|
259
|
-
expire_index!
|
260
|
-
|
261
|
-
unregister_bundle_processor 'application/javascript', :js_compressor
|
262
|
-
return unless compressor
|
263
|
-
|
264
|
-
register_bundle_processor 'application/javascript', :js_compressor do |context, data|
|
265
|
-
compressor.compress(data)
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
195
|
private
|
270
196
|
def add_engine_to_trail(ext, klass)
|
271
197
|
@trail.append_extension(ext.to_s)
|
data/lib/sprockets/processor.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sass'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
class SassCacheStore < ::Sass::CacheStores::Base
|
5
|
+
attr_reader :environment
|
6
|
+
|
7
|
+
def initialize(environment)
|
8
|
+
@environment = environment
|
9
|
+
end
|
10
|
+
|
11
|
+
def _store(key, version, sha, contents)
|
12
|
+
environment.cache_set("sass/#{key}", {:version => version, :sha => sha, :contents => contents})
|
13
|
+
end
|
14
|
+
|
15
|
+
def _retrieve(key, version, sha)
|
16
|
+
if obj = environment.cache_get("sass/#{key}")
|
17
|
+
return unless obj[:version] == version
|
18
|
+
return unless obj[:sha] == sha
|
19
|
+
obj[:contents]
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def path_to(key)
|
26
|
+
key
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
class SassCompressor < Tilt::Template
|
5
|
+
self.default_mime_type = 'text/css'
|
6
|
+
|
7
|
+
def self.engine_initialized?
|
8
|
+
defined?(::Sass::Engine)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_engine
|
12
|
+
require_template_library 'sass'
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
end
|
17
|
+
|
18
|
+
def evaluate(context, locals, &block)
|
19
|
+
::Sass::Engine.new(data, {
|
20
|
+
:syntax => :scss,
|
21
|
+
:cache => false,
|
22
|
+
:read_cache => false,
|
23
|
+
:style => :compressed
|
24
|
+
}).render
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'sass'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
module SassFunctions
|
5
|
+
def asset_path(path)
|
6
|
+
::Sass::Script::String.new(sprockets_context.asset_path(path.value), :string)
|
7
|
+
end
|
8
|
+
|
9
|
+
def asset_url(path)
|
10
|
+
::Sass::Script::String.new("url(" + sprockets_context.asset_path(path.value) + ")")
|
11
|
+
end
|
12
|
+
|
13
|
+
def image_path(path)
|
14
|
+
::Sass::Script::String.new(sprockets_context.image_path(path.value), :string)
|
15
|
+
end
|
16
|
+
|
17
|
+
def image_url(path)
|
18
|
+
::Sass::Script::String.new("url(" + sprockets_context.image_path(path.value) + ")")
|
19
|
+
end
|
20
|
+
|
21
|
+
def video_path(path)
|
22
|
+
::Sass::Script::String.new(sprockets_context.video_path(path.value), :string)
|
23
|
+
end
|
24
|
+
|
25
|
+
def video_url(path)
|
26
|
+
::Sass::Script::String.new("url(" + sprockets_context.video_path(path.value) + ")")
|
27
|
+
end
|
28
|
+
|
29
|
+
def audio_path(path)
|
30
|
+
::Sass::Script::String.new(sprockets_context.audio_path(path.value), :string)
|
31
|
+
end
|
32
|
+
|
33
|
+
def audio_url(path)
|
34
|
+
::Sass::Script::String.new("url(" + sprockets_context.audio_path(path.value) + ")")
|
35
|
+
end
|
36
|
+
|
37
|
+
def font_path(path)
|
38
|
+
::Sass::Script::String.new(sprockets_context.font_path(path.value), :string)
|
39
|
+
end
|
40
|
+
|
41
|
+
def font_url(path)
|
42
|
+
::Sass::Script::String.new("url(" + sprockets_context.font_path(path.value) + ")")
|
43
|
+
end
|
44
|
+
|
45
|
+
def javascript_path(path)
|
46
|
+
::Sass::Script::String.new(sprockets_context.javascript_path(path.value), :string)
|
47
|
+
end
|
48
|
+
|
49
|
+
def javascript_url(path)
|
50
|
+
::Sass::Script::String.new("url(" + sprockets_context.javascript_path(path.value) + ")")
|
51
|
+
end
|
52
|
+
|
53
|
+
def stylesheet_path(path)
|
54
|
+
::Sass::Script::String.new(sprockets_context.stylesheet_path(path.value), :string)
|
55
|
+
end
|
56
|
+
|
57
|
+
def stylesheet_url(path)
|
58
|
+
::Sass::Script::String.new("url(" + sprockets_context.stylesheet_path(path.value) + ")")
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
def sprockets_context
|
63
|
+
options[:sprockets][:context]
|
64
|
+
end
|
65
|
+
|
66
|
+
def sprockets_environment
|
67
|
+
options[:sprockets][:environment]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sass'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
# This custom importer that tracks all imported filenames during
|
5
|
+
# compile.
|
6
|
+
class SassImporter < ::Sass::Importers::Filesystem
|
7
|
+
attr_reader :imported_filenames
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
@imported_filenames = []
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_relative(*args)
|
15
|
+
engine = super
|
16
|
+
if engine && (filename = engine.options[:filename])
|
17
|
+
@imported_filenames << filename
|
18
|
+
end
|
19
|
+
engine
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(*args)
|
23
|
+
engine = super
|
24
|
+
if engine && (filename = engine.options[:filename])
|
25
|
+
@imported_filenames << filename
|
26
|
+
end
|
27
|
+
engine
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
# This custom Tilt handler replaces the one built into Tilt. The
|
5
|
+
# main difference is that it uses a custom importer that plays nice
|
6
|
+
# with sprocket's caching system.
|
7
|
+
#
|
8
|
+
# See `SassImporter` for more infomation.
|
9
|
+
class SassTemplate < Tilt::Template
|
10
|
+
self.default_mime_type = 'text/css'
|
11
|
+
|
12
|
+
def self.engine_initialized?
|
13
|
+
defined?(::Sass::Engine) && defined?(::Sass::Script::Functions) &&
|
14
|
+
::Sass::Script::Functions < Sprockets::SassFunctions
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize_engine
|
18
|
+
# Double check constant to avoid tilt warning
|
19
|
+
unless defined? ::Sass
|
20
|
+
require_template_library 'sass'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Install custom functions. It'd be great if this didn't need to
|
24
|
+
# be installed globally, but could be passed into Engine as an
|
25
|
+
# option.
|
26
|
+
::Sass::Script::Functions.send :include, Sprockets::SassFunctions
|
27
|
+
end
|
28
|
+
|
29
|
+
def prepare
|
30
|
+
end
|
31
|
+
|
32
|
+
def syntax
|
33
|
+
:sass
|
34
|
+
end
|
35
|
+
|
36
|
+
def evaluate(context, locals, &block)
|
37
|
+
# Use custom importer that knows about Sprockets Caching
|
38
|
+
cache_store = SassCacheStore.new(context.environment)
|
39
|
+
|
40
|
+
options = {
|
41
|
+
:filename => eval_file,
|
42
|
+
:line => line,
|
43
|
+
:syntax => syntax,
|
44
|
+
:cache_store => cache_store,
|
45
|
+
:importer => SassImporter.new(context.pathname.to_s),
|
46
|
+
:load_paths => context.environment.paths.map { |path| SassImporter.new(path.to_s) },
|
47
|
+
:sprockets => {
|
48
|
+
:context => context,
|
49
|
+
:environment => context.environment
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
result = ::Sass::Engine.new(data, options).render
|
54
|
+
|
55
|
+
# Track all imported files
|
56
|
+
filenames = ([options[:importer].imported_filenames] + options[:load_paths].map(&:imported_filenames)).flatten.uniq
|
57
|
+
filenames.each { |filename| context.depend_on(filename) }
|
58
|
+
|
59
|
+
result
|
60
|
+
rescue ::Sass::SyntaxError => e
|
61
|
+
# Annotates exception message with parse line number
|
62
|
+
context.__LINE__ = e.sass_backtrace.first[:line]
|
63
|
+
raise e
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'sprockets/sass_template'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
# Scss handler to replace Tilt's builtin one. See `SassTemplate` and
|
5
|
+
# `SassImporter` for more infomation.
|
6
|
+
class ScssTemplate < SassTemplate
|
7
|
+
self.default_mime_type = 'text/css'
|
8
|
+
|
9
|
+
def syntax
|
10
|
+
:scss
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/sprockets/server.rb
CHANGED
@@ -90,7 +90,7 @@ module Sprockets
|
|
90
90
|
#
|
91
91
|
# http://example.org/assets/../../../etc/passwd
|
92
92
|
#
|
93
|
-
path.include?("..") || Pathname.new(path).absolute?
|
93
|
+
path.include?("..") || Pathname.new(path).absolute? || path.include?("://")
|
94
94
|
end
|
95
95
|
|
96
96
|
# Returns a 403 Forbidden response tuple
|
@@ -21,7 +21,9 @@ module Sprockets
|
|
21
21
|
# Save asset to disk.
|
22
22
|
def write_to(filename, options = {})
|
23
23
|
# Gzip contents if filename has '.gz'
|
24
|
-
options
|
24
|
+
unless options.key?(:compress)
|
25
|
+
options[:compress] = File.extname(filename) == '.gz' && File.extname(logical_path) != '.gz'
|
26
|
+
end
|
25
27
|
|
26
28
|
FileUtils.mkdir_p File.dirname(filename)
|
27
29
|
|
@@ -30,6 +32,7 @@ module Sprockets
|
|
30
32
|
pathname.open('rb') do |rd|
|
31
33
|
File.open("#{filename}+", 'wb') do |wr|
|
32
34
|
gz = Zlib::GzipWriter.new(wr, Zlib::BEST_COMPRESSION)
|
35
|
+
gz.mtime = mtime.to_i
|
33
36
|
buf = ""
|
34
37
|
while rd.read(16384, buf)
|
35
38
|
gz.write(buf)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Sprockets
|
4
|
+
class UglifierCompressor < Tilt::Template
|
5
|
+
self.default_mime_type = 'application/javascript'
|
6
|
+
|
7
|
+
def self.engine_initialized?
|
8
|
+
defined?(::Uglifier)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_engine
|
12
|
+
require_template_library 'uglifier'
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
end
|
17
|
+
|
18
|
+
def evaluate(context, locals, &block)
|
19
|
+
# Feature detect Uglifier 2.0 option support
|
20
|
+
if Uglifier::DEFAULTS[:copyright]
|
21
|
+
# Uglifier < 2.x
|
22
|
+
Uglifier.new(:copyright => false).compile(data)
|
23
|
+
else
|
24
|
+
# Uglifier >= 2.x
|
25
|
+
Uglifier.new(:comments => :none).compile(data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|