sprockets 2.2.3 → 2.12.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sprockets might be problematic. Click here for more details.
- checksums.yaml +4 -4
- 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 +14 -7
- data/lib/sprockets/asset_attributes.rb +15 -4
- data/lib/sprockets/base.rb +154 -14
- 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/static_asset.rb +1 -0
- data/lib/sprockets/uglifier_compressor.rb +29 -0
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +27 -0
- metadata +72 -5
data/lib/sprockets/mime.rb
CHANGED
@@ -15,6 +15,11 @@ module Sprockets
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
# Returns a `Hash` of explicitly registered mime types.
|
19
|
+
def registered_mime_types
|
20
|
+
@mime_types.dup
|
21
|
+
end
|
22
|
+
|
18
23
|
if {}.respond_to?(:key)
|
19
24
|
def extension_for_mime_type(type)
|
20
25
|
mime_types.key(type)
|
@@ -41,8 +46,4 @@ module Sprockets
|
|
41
46
|
end
|
42
47
|
end
|
43
48
|
end
|
44
|
-
|
45
|
-
# Extend Sprockets module to provide global registry
|
46
|
-
extend Mime
|
47
|
-
@mime_types = {}
|
48
49
|
end
|
@@ -1,16 +1,11 @@
|
|
1
|
-
require 'sprockets/errors'
|
2
|
-
require 'pathname'
|
3
|
-
|
4
1
|
module Sprockets
|
5
|
-
|
6
|
-
# the `Environment` and `Index` classes.
|
7
|
-
module Trail
|
2
|
+
module Paths
|
8
3
|
# Returns `Environment` root.
|
9
4
|
#
|
10
5
|
# All relative paths are expanded with root as its base. To be
|
11
6
|
# useful set this to your applications root directory. (`Rails.root`)
|
12
7
|
def root
|
13
|
-
trail.root.dup
|
8
|
+
@trail.root.dup
|
14
9
|
end
|
15
10
|
|
16
11
|
# Returns an `Array` of path `String`s.
|
@@ -21,14 +16,13 @@ module Sprockets
|
|
21
16
|
# have no affect on the environment. See `append_path`,
|
22
17
|
# `prepend_path`, and `clear_paths`.
|
23
18
|
def paths
|
24
|
-
trail.paths.dup
|
19
|
+
@trail.paths.dup
|
25
20
|
end
|
26
21
|
|
27
22
|
# Prepend a `path` to the `paths` list.
|
28
23
|
#
|
29
24
|
# Paths at the end of the `Array` have the least priority.
|
30
25
|
def prepend_path(path)
|
31
|
-
expire_index!
|
32
26
|
@trail.prepend_path(path)
|
33
27
|
end
|
34
28
|
|
@@ -36,7 +30,6 @@ module Sprockets
|
|
36
30
|
#
|
37
31
|
# Paths at the beginning of the `Array` have a higher priority.
|
38
32
|
def append_path(path)
|
39
|
-
expire_index!
|
40
33
|
@trail.append_path(path)
|
41
34
|
end
|
42
35
|
|
@@ -46,7 +39,6 @@ module Sprockets
|
|
46
39
|
# completely wipe the paths list and reappend them in the order
|
47
40
|
# you want.
|
48
41
|
def clear_paths
|
49
|
-
expire_index!
|
50
42
|
@trail.paths.dup.each { |path| @trail.remove_path(path) }
|
51
43
|
end
|
52
44
|
|
@@ -57,34 +49,10 @@ module Sprockets
|
|
57
49
|
# # => [".js", ".css", ".coffee", ".sass", ...]
|
58
50
|
#
|
59
51
|
def extensions
|
60
|
-
trail.extensions.dup
|
61
|
-
end
|
62
|
-
|
63
|
-
# Finds the expanded real path for a given logical path by
|
64
|
-
# searching the environment's paths.
|
65
|
-
#
|
66
|
-
# resolve("application.js")
|
67
|
-
# # => "/path/to/app/javascripts/application.js.coffee"
|
68
|
-
#
|
69
|
-
# A `FileNotFound` exception is raised if the file does not exist.
|
70
|
-
def resolve(logical_path, options = {})
|
71
|
-
# If a block is given, preform an iterable search
|
72
|
-
if block_given?
|
73
|
-
args = attributes_for(logical_path).search_paths + [options]
|
74
|
-
trail.find(*args) do |path|
|
75
|
-
yield Pathname.new(path)
|
76
|
-
end
|
77
|
-
else
|
78
|
-
resolve(logical_path, options) do |pathname|
|
79
|
-
return pathname
|
80
|
-
end
|
81
|
-
raise FileNotFound, "couldn't find file '#{logical_path}'"
|
82
|
-
end
|
52
|
+
@trail.extensions.dup
|
83
53
|
end
|
84
54
|
|
85
55
|
protected
|
86
|
-
|
87
|
-
@trail
|
88
|
-
end
|
56
|
+
attr_reader :trail
|
89
57
|
end
|
90
58
|
end
|
@@ -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
|