sprockets 2.2.3 → 2.12.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.info "Compiled #{logical_path} (#{elapsed_time}ms) (pid #{Process.pid})"
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
@@ -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)
@@ -3,7 +3,7 @@ require 'tilt'
3
3
  module Sprockets
4
4
  # `Processor` creates an anonymous processor class from a block.
5
5
  #
6
- # register_preprocessor :my_processor do |context, data|
6
+ # register_preprocessor 'text/css', :my_processor do |context, data|
7
7
  # # ...
8
8
  # end
9
9
  #
@@ -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
@@ -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[:compress] ||= File.extname(filename) == '.gz'
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