sprockets 3.0.0.beta.6 → 3.0.0.beta.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +171 -100
  3. data/lib/rake/sprocketstask.rb +2 -2
  4. data/lib/sprockets.rb +69 -63
  5. data/lib/sprockets/asset.rb +2 -61
  6. data/lib/sprockets/autoload_processor.rb +48 -0
  7. data/lib/sprockets/base.rb +4 -6
  8. data/lib/sprockets/bower.rb +8 -5
  9. data/lib/sprockets/bundle.rb +9 -13
  10. data/lib/sprockets/cache.rb +19 -14
  11. data/lib/sprockets/cache/file_store.rb +2 -1
  12. data/lib/sprockets/cached_environment.rb +15 -68
  13. data/lib/sprockets/closure_compressor.rb +17 -4
  14. data/lib/sprockets/coffee_script_processor.rb +26 -0
  15. data/lib/sprockets/coffee_script_template.rb +3 -20
  16. data/lib/sprockets/compressing.rb +10 -4
  17. data/lib/sprockets/configuration.rb +21 -37
  18. data/lib/sprockets/context.rb +37 -67
  19. data/lib/sprockets/dependencies.rb +73 -0
  20. data/lib/sprockets/digest_utils.rb +8 -2
  21. data/lib/sprockets/directive_processor.rb +122 -165
  22. data/lib/sprockets/eco_processor.rb +32 -0
  23. data/lib/sprockets/eco_template.rb +3 -26
  24. data/lib/sprockets/ejs_processor.rb +31 -0
  25. data/lib/sprockets/ejs_template.rb +3 -25
  26. data/lib/sprockets/encoding_utils.rb +9 -21
  27. data/lib/sprockets/engines.rb +25 -27
  28. data/lib/sprockets/environment.rb +9 -1
  29. data/lib/sprockets/erb_processor.rb +30 -0
  30. data/lib/sprockets/erb_template.rb +3 -20
  31. data/lib/sprockets/file_reader.rb +15 -0
  32. data/lib/sprockets/http_utils.rb +2 -0
  33. data/lib/sprockets/jst_processor.rb +9 -2
  34. data/lib/sprockets/legacy.rb +212 -3
  35. data/lib/sprockets/legacy_tilt_processor.rb +1 -1
  36. data/lib/sprockets/loader.rb +95 -89
  37. data/lib/sprockets/manifest.rb +23 -59
  38. data/lib/sprockets/mime.rb +28 -41
  39. data/lib/sprockets/path_dependency_utils.rb +76 -0
  40. data/lib/sprockets/path_utils.rb +21 -1
  41. data/lib/sprockets/paths.rb +23 -8
  42. data/lib/sprockets/processing.rb +102 -91
  43. data/lib/sprockets/processor_utils.rb +97 -0
  44. data/lib/sprockets/resolve.rb +110 -97
  45. data/lib/sprockets/sass_cache_store.rb +2 -2
  46. data/lib/sprockets/sass_compressor.rb +17 -4
  47. data/lib/sprockets/sass_functions.rb +2 -2
  48. data/lib/sprockets/sass_importer.rb +2 -2
  49. data/lib/sprockets/sass_processor.rb +305 -0
  50. data/lib/sprockets/sass_template.rb +4 -286
  51. data/lib/sprockets/server.rb +1 -13
  52. data/lib/sprockets/transformers.rb +62 -25
  53. data/lib/sprockets/uglifier_compressor.rb +17 -4
  54. data/lib/sprockets/uri_utils.rb +190 -0
  55. data/lib/sprockets/utils.rb +87 -6
  56. data/lib/sprockets/version.rb +1 -1
  57. data/lib/sprockets/yui_compressor.rb +17 -4
  58. metadata +14 -5
  59. data/lib/sprockets/asset_uri.rb +0 -80
  60. data/lib/sprockets/lazy_processor.rb +0 -15
@@ -1,289 +1,7 @@
1
- require 'rack/utils'
2
- require 'sass'
3
- require 'uri'
1
+ require 'sprockets/sass_processor'
4
2
 
5
3
  module Sprockets
6
- # Template engine class for the SASS/SCSS compiler. Depends on the `sass` gem.
7
- #
8
- # For more infomation see:
9
- #
10
- # https://github.com/sass/sass
11
- # https://github.com/rails/sass-rails
12
- #
13
- class SassTemplate
14
- # Internal: Defines default sass syntax to use. Exposed so the ScssTemplate
15
- # may override it.
16
- def self.syntax
17
- :sass
18
- end
19
-
20
- def self.call(*args)
21
- new.call(*args)
22
- end
23
-
24
- # Public: Initialize template with custom options.
25
- #
26
- # options - Hash
27
- # cache_version - String custom cache version. Used to force a cache
28
- # change after code changes are made to Sass Functions.
29
- #
30
- def initialize(options = {}, &block)
31
- @cache_version = options[:cache_version]
32
-
33
- @functions = Module.new do
34
- include Functions
35
- include options[:functions] if options[:functions]
36
- class_eval(&block) if block_given?
37
- end
38
- end
39
-
40
- def call(input)
41
- context = input[:environment].context_class.new(input)
42
-
43
- options = {
44
- filename: input[:filename],
45
- syntax: self.class.syntax,
46
- cache_store: CacheStore.new(input[:cache], @cache_version),
47
- load_paths: input[:environment].paths,
48
- sprockets: {
49
- context: context,
50
- environment: input[:environment],
51
- dependencies: context.metadata[:dependency_paths]
52
- }
53
- }
54
-
55
- engine = ::Sass::Engine.new(input[:data], options)
56
-
57
- css = Utils.module_include(::Sass::Script::Functions, @functions) do
58
- engine.render
59
- end
60
-
61
- # Track all imported files
62
- engine.dependencies.map do |dependency|
63
- context.metadata[:dependency_paths] << dependency.options[:filename]
64
- end
65
-
66
- context.metadata.merge(data: css)
67
- end
68
-
69
- # Public: Functions injected into Sass context during Sprockets evaluation.
70
- #
71
- # This module may be extended to add global functionality to all Sprockets
72
- # Sass environments. Though, scoping your functions to just your environment
73
- # is preferred.
74
- #
75
- # module Sprockets::SassTemplate::Functions
76
- # def asset_path(path, options = {})
77
- # end
78
- # end
79
- #
80
- module Functions
81
- # Public: Generate a url for asset path.
82
- #
83
- # Default implementation is deprecated. Currently defaults to
84
- # Context#asset_path.
85
- #
86
- # Will raise NotImplementedError in the future. Users should provide their
87
- # own base implementation.
88
- #
89
- # Returns a Sass::Script::String.
90
- def asset_path(path, options = {})
91
- path = path.value
92
-
93
- path, _, query, fragment = URI.split(path)[5..8]
94
- path = sprockets_context.asset_path(path, options)
95
- query = "?#{query}" if query
96
- fragment = "##{fragment}" if fragment
97
-
98
- ::Sass::Script::String.new("#{path}#{query}#{fragment}", :string)
99
- end
100
-
101
- # Public: Generate a asset url() link.
102
- #
103
- # path - Sass::Script::String URL path
104
- #
105
- # Returns a Sass::Script::String.
106
- def asset_url(path, options = {})
107
- ::Sass::Script::String.new("url(#{asset_path(path, options).value})")
108
- end
109
-
110
- # Public: Generate url for image path.
111
- #
112
- # path - Sass::Script::String URL path
113
- #
114
- # Returns a Sass::Script::String.
115
- def image_path(path)
116
- asset_path(path, type: :image)
117
- end
118
-
119
- # Public: Generate a image url() link.
120
- #
121
- # path - Sass::Script::String URL path
122
- #
123
- # Returns a Sass::Script::String.
124
- def image_url(path)
125
- asset_url(path, type: :image)
126
- end
127
-
128
- # Public: Generate url for video path.
129
- #
130
- # path - Sass::Script::String URL path
131
- #
132
- # Returns a Sass::Script::String.
133
- def video_path(path)
134
- asset_path(path, type: :video)
135
- end
136
-
137
- # Public: Generate a video url() link.
138
- #
139
- # path - Sass::Script::String URL path
140
- #
141
- # Returns a Sass::Script::String.
142
- def video_url(path)
143
- asset_url(path, type: :video)
144
- end
145
-
146
- # Public: Generate url for audio path.
147
- #
148
- # path - Sass::Script::String URL path
149
- #
150
- # Returns a Sass::Script::String.
151
- def audio_path(path)
152
- asset_path(path, type: :audio)
153
- end
154
-
155
- # Public: Generate a audio url() link.
156
- #
157
- # path - Sass::Script::String URL path
158
- #
159
- # Returns a Sass::Script::String.
160
- def audio_url(path)
161
- asset_url(path, type: :audio)
162
- end
163
-
164
- # Public: Generate url for font path.
165
- #
166
- # path - Sass::Script::String URL path
167
- #
168
- # Returns a Sass::Script::String.
169
- def font_path(path)
170
- asset_path(path, type: :font)
171
- end
172
-
173
- # Public: Generate a font url() link.
174
- #
175
- # path - Sass::Script::String URL path
176
- #
177
- # Returns a Sass::Script::String.
178
- def font_url(path)
179
- asset_url(path, type: :font)
180
- end
181
-
182
- # Public: Generate url for javascript path.
183
- #
184
- # path - Sass::Script::String URL path
185
- #
186
- # Returns a Sass::Script::String.
187
- def javascript_path(path)
188
- asset_path(path, type: :javascript)
189
- end
190
-
191
- # Public: Generate a javascript url() link.
192
- #
193
- # path - Sass::Script::String URL path
194
- #
195
- # Returns a Sass::Script::String.
196
- def javascript_url(path)
197
- asset_url(path, type: :javascript)
198
- end
199
-
200
- # Public: Generate url for stylesheet path.
201
- #
202
- # path - Sass::Script::String URL path
203
- #
204
- # Returns a Sass::Script::String.
205
- def stylesheet_path(path)
206
- asset_path(path, type: :stylesheet)
207
- end
208
-
209
- # Public: Generate a stylesheet url() link.
210
- #
211
- # path - Sass::Script::String URL path
212
- #
213
- # Returns a Sass::Script::String.
214
- def stylesheet_url(path)
215
- asset_url(path, type: :stylesheet)
216
- end
217
-
218
- # Public: Generate a data URI for asset path.
219
- #
220
- # path - Sass::Script::String logical asset path
221
- #
222
- # Returns a Sass::Script::String.
223
- def asset_data_url(path)
224
- if asset = sprockets_environment.find_asset(path.value, accept_encoding: 'base64')
225
- sprockets_dependencies << asset.filename
226
- url = "data:#{asset.content_type};base64,#{Rack::Utils.escape(asset.to_s)}"
227
- ::Sass::Script::String.new("url(" + url + ")")
228
- end
229
- end
230
-
231
- protected
232
- # Public: The Environment.
233
- #
234
- # Returns Sprockets::Environment.
235
- def sprockets_environment
236
- options[:sprockets][:environment]
237
- end
238
-
239
- # Public: Mutatable set dependency paths.
240
- #
241
- # Returns a Set.
242
- def sprockets_dependencies
243
- options[:sprockets][:dependencies]
244
- end
245
-
246
- # Deprecated: Get the Context instance. Use APIs on
247
- # sprockets_environment or sprockets_dependencies directly.
248
- #
249
- # Returns a Context instance.
250
- def sprockets_context
251
- options[:sprockets][:context]
252
- end
253
-
254
- end
255
-
256
- # Internal: Cache wrapper for Sprockets cache adapter.
257
- class CacheStore < ::Sass::CacheStores::Base
258
- VERSION = '1'
259
-
260
- def initialize(cache, version)
261
- @cache, @version = cache, "#{VERSION}/#{version}"
262
- end
263
-
264
- def _store(key, version, sha, contents)
265
- @cache._set("#{@version}/#{version}/#{key}/#{sha}", contents)
266
- end
267
-
268
- def _retrieve(key, version, sha)
269
- @cache._get("#{@version}/#{version}/#{key}/#{sha}")
270
- end
271
-
272
- def path_to(key)
273
- key
274
- end
275
- end
276
- end
277
-
278
- class ScssTemplate < SassTemplate
279
- def self.syntax
280
- :scss
281
- end
282
- end
283
-
284
- # Deprecated: Use Sprockets::SassTemplate::Functions instead.
285
- SassFunctions = SassTemplate::Functions
286
-
287
- # Deprecated: Use Sprockets::SassTemplate::CacheStore instead.
288
- SassCacheStore = SassTemplate::CacheStore
4
+ # Deprecated
5
+ SassTemplate = SassProcessor
6
+ ScssTemplate = ScssProcessor
289
7
  end
@@ -48,7 +48,7 @@ module Sprockets
48
48
 
49
49
  # 2.x/3.x compatibility hack. Just ignore fingerprints on ?body=1 requests.
50
50
  # 3.x/4.x prefers strong validation of fingerprint to body contents, but
51
- # 2.x just ignored it.
51
+ # 2.x just ignored it.
52
52
  if options[:bundle] == false
53
53
  fingerprint = nil
54
54
  end
@@ -63,13 +63,6 @@ module Sprockets
63
63
  if_none_match = env['HTTP_IF_NONE_MATCH'][/^"(\w+)"$/, 1]
64
64
  end
65
65
 
66
- if !if_match && !if_none_match && env['HTTP_ACCEPT_ENCODING']
67
- # Accept-Encoding negotiation is only enabled for non-fingerprinted
68
- # assets. Avoids the "Apache ETag gzip" bug. Just Google it.
69
- # https://issues.apache.org/bugzilla/show_bug.cgi?id=39727
70
- options[:accept_encoding] = env['HTTP_ACCEPT_ENCODING']
71
- end
72
-
73
66
  asset = find_asset(path, options)
74
67
 
75
68
  if asset.nil?
@@ -252,11 +245,6 @@ module Sprockets
252
245
  def headers(env, asset, length)
253
246
  headers = {}
254
247
 
255
- # Set content encoding
256
- if asset.encoding
257
- headers["Content-Encoding"] = asset.encoding
258
- end
259
-
260
248
  # Set content length header
261
249
  headers["Content-Length"] = length.to_s
262
250
 
@@ -1,5 +1,11 @@
1
+ require 'sprockets/http_utils'
2
+ require 'sprockets/processor_utils'
3
+ require 'sprockets/utils'
4
+
1
5
  module Sprockets
2
6
  module Transformers
7
+ include HTTPUtils, ProcessorUtils, Utils
8
+
3
9
  # Public: Two level mapping of a source mime type to a target mime type.
4
10
  #
5
11
  # environment.transformers
@@ -8,17 +14,9 @@ module Sprockets
8
14
  # }
9
15
  # }
10
16
  #
11
- attr_reader :transformers
12
-
13
- # Public: Two level mapping of target mime type to source mime type.
14
- #
15
- # environment.inverted_transformers
16
- # # => { 'application/javascript' => {
17
- # 'text/coffeescript' => ConvertCoffeeScriptToJavaScript
18
- # }
19
- # }
20
- #
21
- attr_reader :inverted_transformers
17
+ def transformers
18
+ config[:transformers]
19
+ end
22
20
 
23
21
  # Public: Register a transformer from and to a mime type.
24
22
  #
@@ -35,12 +33,10 @@ module Sprockets
35
33
  #
36
34
  # Returns nothing.
37
35
  def register_transformer(from, to, proc)
38
- mutate_hash_config(:transformers, from) do |transformers|
36
+ self.config = hash_reassoc(config, :registered_transformers, from) do |transformers|
39
37
  transformers.merge(to => proc)
40
38
  end
41
- mutate_hash_config(:inverted_transformers, to) do |transformers|
42
- transformers.merge(from => proc)
43
- end
39
+ compute_transformers!
44
40
  end
45
41
 
46
42
  # Internal: Resolve target mime type that the source type should be
@@ -79,25 +75,66 @@ module Sprockets
79
75
  accepts = []
80
76
  parsed_accepts.each do |(type, q)|
81
77
  accepts.push([type, q])
82
- inverted_transformers[type].keys.each do |subtype|
78
+ config[:inverted_transformers][type].each do |subtype|
83
79
  accepts.push([subtype, q * 0.8])
84
80
  end
85
81
  end
86
82
  accepts
87
83
  end
88
84
 
89
- # Internal: Find and load transformer by from and to mime type.
85
+ # Internal: Compose multiple transformer steps into a single processor
86
+ # function.
90
87
  #
91
- # from - String mime type
92
- # to - String mime type
88
+ # transformers - Two level Hash of a source mime type to a target mime type
89
+ # types - Array of mime type steps
93
90
  #
94
- # Returns Array of Procs.
95
- def unwrap_transformer(from, to)
96
- if processor = transformers[from][to]
97
- [unwrap_processor(processor)]
98
- else
99
- []
91
+ # Returns Processor.
92
+ def compose_transformers(transformers, types)
93
+ if types.length < 2
94
+ raise ArgumentError, "too few transform types: #{types.inspect}"
95
+ end
96
+
97
+ processors = []
98
+ enum = types.each
99
+
100
+ loop do
101
+ src, dst = enum.next, enum.peek
102
+ unless processor = transformers[src][dst]
103
+ raise ArgumentError, "missing transformer for type: #{src} to #{dst}"
104
+ end
105
+ processors.concat config[:postprocessors][src]
106
+ processors << processor
107
+ processors.concat config[:preprocessors][dst]
108
+ end
109
+
110
+ if processors.size > 1
111
+ compose_processors(*processors.reverse)
112
+ elsif processors.size == 1
113
+ processors.first
100
114
  end
101
115
  end
116
+
117
+ private
118
+ def compute_transformers!
119
+ registered_transformers = self.config[:registered_transformers]
120
+ transformers = Hash.new { {} }
121
+ inverted_transformers = Hash.new { Set.new }
122
+
123
+ registered_transformers.keys.flat_map do |key|
124
+ dfs_paths([key]) { |k| registered_transformers[k].keys }
125
+ end.each do |types|
126
+ src, dst = types.first, types.last
127
+ processor = compose_transformers(registered_transformers, types)
128
+
129
+ transformers[src] = {} unless transformers.key?(src)
130
+ transformers[src][dst] = processor
131
+
132
+ inverted_transformers[dst] = Set.new unless inverted_transformers.key?(dst)
133
+ inverted_transformers[dst] << src
134
+ end
135
+
136
+ self.config = hash_reassoc(config, :transformers) { transformers }
137
+ self.config = hash_reassoc(config, :inverted_transformers) { inverted_transformers }
138
+ end
102
139
  end
103
140
  end