sprockets 3.0.0.beta.8 → 3.0.0.beta.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -6
  3. data/lib/sprockets.rb +39 -15
  4. data/lib/sprockets/autoload.rb +11 -0
  5. data/lib/sprockets/autoload/closure.rb +7 -0
  6. data/lib/sprockets/autoload/coffee_script.rb +7 -0
  7. data/lib/sprockets/autoload/eco.rb +7 -0
  8. data/lib/sprockets/autoload/ejs.rb +7 -0
  9. data/lib/sprockets/autoload/sass.rb +7 -0
  10. data/lib/sprockets/autoload/uglifier.rb +7 -0
  11. data/lib/sprockets/autoload/yui.rb +7 -0
  12. data/lib/sprockets/bundle.rb +33 -3
  13. data/lib/sprockets/cache.rb +15 -6
  14. data/lib/sprockets/closure_compressor.rb +3 -5
  15. data/lib/sprockets/coffee_script_processor.rb +2 -5
  16. data/lib/sprockets/compressing.rb +2 -2
  17. data/lib/sprockets/context.rb +2 -2
  18. data/lib/sprockets/dependencies.rb +1 -1
  19. data/lib/sprockets/directive_processor.rb +3 -3
  20. data/lib/sprockets/eco_processor.rb +2 -4
  21. data/lib/sprockets/ejs_processor.rb +1 -3
  22. data/lib/sprockets/engines.rb +1 -1
  23. data/lib/sprockets/http_utils.rb +17 -1
  24. data/lib/sprockets/legacy.rb +3 -2
  25. data/lib/sprockets/loader.rb +11 -8
  26. data/lib/sprockets/manifest.rb +27 -17
  27. data/lib/sprockets/manifest_utils.rb +45 -0
  28. data/lib/sprockets/mime.rb +10 -7
  29. data/lib/sprockets/paths.rb +2 -2
  30. data/lib/sprockets/processing.rb +35 -52
  31. data/lib/sprockets/processor_utils.rb +34 -28
  32. data/lib/sprockets/resolve.rb +35 -25
  33. data/lib/sprockets/sass_cache_store.rb +29 -2
  34. data/lib/sprockets/sass_compressor.rb +3 -5
  35. data/lib/sprockets/sass_processor.rb +11 -32
  36. data/lib/sprockets/server.rb +4 -4
  37. data/lib/sprockets/transformers.rb +1 -1
  38. data/lib/sprockets/uglifier_compressor.rb +3 -5
  39. data/lib/sprockets/uri_utils.rb +3 -3
  40. data/lib/sprockets/version.rb +1 -1
  41. data/lib/sprockets/yui_compressor.rb +3 -5
  42. metadata +12 -4
  43. data/lib/sprockets/autoload_processor.rb +0 -48
@@ -1,5 +1,3 @@
1
- require 'sprockets/autoload_processor'
2
-
3
1
  module Sprockets
4
2
  # Functional utilities for dealing with Processor functions.
5
3
  #
@@ -16,19 +14,6 @@ module Sprockets
16
14
  module ProcessorUtils
17
15
  extend self
18
16
 
19
- # Internal: Setup autoload and wrapper for lazy loaded processor.
20
- #
21
- # Sprockets.autoload_processor :CoffeeScriptProcessor, 'sprockets/coffee_script_processor'
22
- #
23
- # mod - Symbol name of processor class/module
24
- # filename - String require path for module
25
- #
26
- # Returns AutoloadProcessor.
27
- def autoload_processor(mod, filename)
28
- autoload(mod, filename)
29
- AutoloadProcessor.new(self, mod)
30
- end
31
-
32
17
  # Public: Compose processors in right to left order.
33
18
  #
34
19
  # processors - Array of processors callables
@@ -36,11 +21,18 @@ module Sprockets
36
21
  # Returns a composed Proc.
37
22
  def compose_processors(*processors)
38
23
  context = self
39
- obj = method(:call_processors).to_proc.curry[processors]
24
+
25
+ if processors.length == 1
26
+ obj = method(:call_processor).to_proc.curry[processors.first]
27
+ else
28
+ obj = method(:call_processors).to_proc.curry[processors]
29
+ end
30
+
40
31
  metaclass = (class << obj; self; end)
41
32
  metaclass.send(:define_method, :cache_key) do
42
33
  context.processors_cache_keys(processors)
43
34
  end
35
+
44
36
  obj
45
37
  end
46
38
 
@@ -57,25 +49,39 @@ module Sprockets
57
49
  # Returns a Hash with :data and other processor metadata key/values.
58
50
  def call_processors(processors, input)
59
51
  data = input[:data] || ""
60
- metadata = input[:metadata] || {}
52
+ metadata = (input[:metadata] || {}).dup
61
53
 
62
54
  processors.reverse_each do |processor|
63
- result = processor.call(input.merge(data: data, metadata: metadata))
64
- case result
65
- when NilClass
66
- when Hash
67
- data = result.delete(:data) if result.key?(:data)
68
- metadata.merge!(result)
69
- when String
70
- data = result
71
- else
72
- raise TypeError, "invalid processor return type: #{result.class}"
73
- end
55
+ result = call_processor(processor, input.merge(data: data, metadata: metadata))
56
+ data = result.delete(:data)
57
+ metadata.merge!(result)
74
58
  end
75
59
 
76
60
  metadata.merge(data: data)
77
61
  end
78
62
 
63
+ # Public: Invoke processor.
64
+ #
65
+ # processor - Processor callables
66
+ # input - Hash of input data to pass to processor
67
+ #
68
+ # Returns a Hash with :data and other processor metadata key/values.
69
+ def call_processor(processor, input)
70
+ metadata = (input[:metadata] || {}).dup
71
+ metadata[:data] = input[:data]
72
+
73
+ case result = processor.call({data: "", metadata: {}}.merge(input))
74
+ when NilClass
75
+ metadata
76
+ when Hash
77
+ metadata.merge(result)
78
+ when String
79
+ metadata.merge(data: result)
80
+ else
81
+ raise TypeError, "invalid processor return type: #{result.class}"
82
+ end
83
+ end
84
+
79
85
  # Internal: Get processor defined cached key.
80
86
  #
81
87
  # processor - Processor function
@@ -22,19 +22,28 @@ module Sprockets
22
22
  # The String Asset URI is returned or nil if no results are found.
23
23
  def resolve(path, options = {})
24
24
  path = path.to_s
25
- paths = options[:load_paths] || self.paths
25
+ paths = options[:load_paths] || config[:paths]
26
26
  accept = options[:accept]
27
- skip_bundle = options.key?(:bundle) ? !options[:bundle] : false
28
27
 
29
28
  if valid_asset_uri?(path)
30
- resolve_asset_uri(path)
29
+ uri, deps = resolve_asset_uri(path)
31
30
  elsif absolute_path?(path)
32
- resolve_absolute_path(paths, path, accept, skip_bundle)
31
+ filename, type, deps = resolve_absolute_path(paths, path, accept)
33
32
  elsif relative_path?(path)
34
- resolve_relative_path(paths, path, options[:base_path], accept, skip_bundle)
33
+ filename, type, pipeline, deps = resolve_relative_path(paths, path, options[:base_path], accept)
35
34
  else
36
- resolve_logical_path(paths, path, accept, skip_bundle)
35
+ filename, type, pipeline, deps = resolve_logical_path(paths, path, accept)
37
36
  end
37
+
38
+ if filename
39
+ params = {}
40
+ params[:type] = type if type
41
+ params[:pipeline] = pipeline if pipeline
42
+ params[:pipeline] = options[:pipeline] if options[:pipeline]
43
+ uri = build_asset_uri(filename, params)
44
+ end
45
+
46
+ return uri, deps
38
47
  end
39
48
 
40
49
  # Public: Same as resolve() but raises a FileNotFound exception instead of
@@ -57,36 +66,35 @@ module Sprockets
57
66
  return uri, Set.new([build_file_digest_uri(filename)])
58
67
  end
59
68
 
60
- def resolve_absolute_path(paths, filename, accept, skip_bundle)
69
+ def resolve_absolute_path(paths, filename, accept)
61
70
  deps = Set.new
62
71
  filename = File.expand_path(filename)
63
72
 
64
73
  # Ensure path is under load paths
65
- return nil, deps unless paths_split(paths, filename)
74
+ return nil, nil, deps unless paths_split(paths, filename)
66
75
 
67
- mime_type = parse_path_extnames(filename)[1]
76
+ _, mime_type, _, _ = parse_path_extnames(filename)
68
77
  type = resolve_transform_type(mime_type, accept)
69
- return nil, deps if accept && !type
78
+ return nil, nil, deps if accept && !type
70
79
 
71
- return nil, deps unless file?(filename)
80
+ return nil, nil, deps unless file?(filename)
72
81
 
73
- uri = build_asset_uri(filename, type: type, skip_bundle: skip_bundle)
74
82
  deps << build_file_digest_uri(filename)
75
- return uri, deps
83
+ return filename, type, deps
76
84
  end
77
85
 
78
- def resolve_relative_path(paths, path, dirname, accept, skip_bundle)
86
+ def resolve_relative_path(paths, path, dirname, accept)
79
87
  filename = File.expand_path(path, dirname)
80
88
  load_path, _ = paths_split(paths, dirname)
81
89
  if load_path && logical_path = split_subpath(load_path, filename)
82
- resolve_logical_path([load_path], logical_path, accept, skip_bundle)
90
+ resolve_logical_path([load_path], logical_path, accept)
83
91
  else
84
- [nil, Set.new]
92
+ return nil, nil, Set.new
85
93
  end
86
94
  end
87
95
 
88
- def resolve_logical_path(paths, logical_path, accept, skip_bundle)
89
- logical_name, mime_type, _ = parse_path_extnames(logical_path)
96
+ def resolve_logical_path(paths, logical_path, accept)
97
+ logical_name, mime_type, _, pipeline = parse_path_extnames(logical_path)
90
98
  parsed_accept = parse_accept_options(mime_type, accept)
91
99
  transformed_accepts = expand_transform_accepts(parsed_accept)
92
100
  filename, mime_type, deps = resolve_under_paths(paths, logical_name, transformed_accepts)
@@ -94,10 +102,9 @@ module Sprockets
94
102
  if filename
95
103
  deps << build_file_digest_uri(filename)
96
104
  type = resolve_transform_type(mime_type, parsed_accept)
97
- uri = build_asset_uri(filename, type: type, skip_bundle: skip_bundle)
98
- return uri, deps
105
+ return filename, type, pipeline, deps
99
106
  else
100
- return nil, deps
107
+ return nil, nil, nil, deps
101
108
  end
102
109
  end
103
110
 
@@ -168,7 +175,7 @@ module Sprockets
168
175
  candidates = []
169
176
  entries, deps = self.entries_with_dependencies(dirname)
170
177
  entries.each do |entry|
171
- name, type, _ = parse_path_extnames(entry)
178
+ name, type, _, _ = parse_path_extnames(entry)
172
179
  if basename == name
173
180
  candidates << [File.join(dirname, entry), type]
174
181
  end
@@ -186,12 +193,15 @@ module Sprockets
186
193
  # # => ["foo", "application/javascript", [".coffee", ".erb"]]
187
194
  #
188
195
  def parse_path_extnames(path)
196
+ engines = []
189
197
  extname, value = match_path_extname(path, config[:_extnames])
198
+
190
199
  if extname
191
- return path.chomp(extname), value[:type], value[:engines]
192
- else
193
- return path, nil, []
200
+ path = path.chomp(extname)
201
+ type, engines, pipeline = value.values_at(:type, :engines, :pipeline)
194
202
  end
203
+
204
+ return path, type, engines, pipeline
195
205
  end
196
206
  end
197
207
  end
@@ -1,2 +1,29 @@
1
- # Deprecated: Require sprockets/sass_processor instead
2
- require 'sprockets/sass_processor'
1
+ require 'sass'
2
+
3
+ module Sprockets
4
+ class SassProcessor
5
+ # Internal: Cache wrapper for Sprockets cache adapter.
6
+ class CacheStore < ::Sass::CacheStores::Base
7
+ VERSION = '1'
8
+
9
+ def initialize(cache, version)
10
+ @cache, @version = cache, "#{VERSION}/#{version}"
11
+ end
12
+
13
+ def _store(key, version, sha, contents)
14
+ @cache.set("#{@version}/#{version}/#{key}/#{sha}", contents, true)
15
+ end
16
+
17
+ def _retrieve(key, version, sha)
18
+ @cache.get("#{@version}/#{version}/#{key}/#{sha}", true)
19
+ end
20
+
21
+ def path_to(key)
22
+ key
23
+ end
24
+ end
25
+ end
26
+
27
+ # Deprecated: Use Sprockets::SassProcessor::CacheStore instead.
28
+ SassCacheStore = SassProcessor::CacheStore
29
+ end
@@ -1,5 +1,3 @@
1
- require 'sass'
2
-
3
1
  module Sprockets
4
2
  # Public: Sass CSS minifier.
5
3
  #
@@ -27,7 +25,7 @@ module Sprockets
27
25
  instance.call(input)
28
26
  end
29
27
 
30
- def cache_key
28
+ def self.cache_key
31
29
  instance.cache_key
32
30
  end
33
31
 
@@ -37,7 +35,7 @@ module Sprockets
37
35
  @options = options
38
36
  @cache_key = [
39
37
  self.class.name,
40
- ::Sass::VERSION,
38
+ Autoload::Sass::VERSION,
41
39
  VERSION,
42
40
  options
43
41
  ].freeze
@@ -52,7 +50,7 @@ module Sprockets
52
50
  read_cache: false,
53
51
  style: :compressed
54
52
  }.merge(@options)
55
- ::Sass::Engine.new(data, options).render
53
+ Autoload::Sass::Engine.new(data, options).render
56
54
  end
57
55
  end
58
56
  end
@@ -1,5 +1,4 @@
1
1
  require 'rack/utils'
2
- require 'sass'
3
2
  require 'uri'
4
3
 
5
4
  module Sprockets
@@ -11,6 +10,8 @@ module Sprockets
11
10
  # https://github.com/rails/sass-rails
12
11
  #
13
12
  class SassProcessor
13
+ autoload :CacheStore, 'sprockets/sass_cache_store'
14
+
14
15
  # Internal: Defines default sass syntax to use. Exposed so the ScssProcessor
15
16
  # may override it.
16
17
  def self.syntax
@@ -45,7 +46,7 @@ module Sprockets
45
46
  @cache_key = [
46
47
  self.class.name,
47
48
  VERSION,
48
- Sass::VERSION,
49
+ Autoload::Sass::VERSION,
49
50
  @cache_version
50
51
  ].freeze
51
52
 
@@ -71,18 +72,20 @@ module Sprockets
71
72
  }
72
73
  }
73
74
 
74
- engine = ::Sass::Engine.new(input[:data], options)
75
+ engine = Autoload::Sass::Engine.new(input[:data], options)
75
76
 
76
- css = Utils.module_include(::Sass::Script::Functions, @functions) do
77
+ css = Utils.module_include(Autoload::Sass::Script::Functions, @functions) do
77
78
  engine.render
78
79
  end
79
80
 
80
81
  # Track all imported files
82
+ sass_dependencies = Set.new([input[:filename]])
81
83
  engine.dependencies.map do |dependency|
84
+ sass_dependencies << dependency.options[:filename]
82
85
  context.metadata[:dependencies] << URIUtils.build_file_digest_uri(dependency.options[:filename])
83
86
  end
84
87
 
85
- context.metadata.merge(data: css)
88
+ context.metadata.merge(data: css, sass_dependencies: sass_dependencies)
86
89
  end
87
90
 
88
91
  # Public: Functions injected into Sass context during Sprockets evaluation.
@@ -114,7 +117,7 @@ module Sprockets
114
117
  query = "?#{query}" if query
115
118
  fragment = "##{fragment}" if fragment
116
119
 
117
- ::Sass::Script::String.new("#{path}#{query}#{fragment}", :string)
120
+ Autoload::Sass::Script::String.new("#{path}#{query}#{fragment}", :string)
118
121
  end
119
122
 
120
123
  # Public: Generate a asset url() link.
@@ -123,7 +126,7 @@ module Sprockets
123
126
  #
124
127
  # Returns a Sass::Script::String.
125
128
  def asset_url(path, options = {})
126
- ::Sass::Script::String.new("url(#{asset_path(path, options).value})")
129
+ Autoload::Sass::Script::String.new("url(#{asset_path(path, options).value})")
127
130
  end
128
131
 
129
132
  # Public: Generate url for image path.
@@ -241,7 +244,7 @@ module Sprockets
241
244
  # Returns a Sass::Script::String.
242
245
  def asset_data_url(path)
243
246
  url = sprockets_context.asset_data_uri(path.value)
244
- ::Sass::Script::String.new("url(" + url + ")")
247
+ Autoload::Sass::Script::String.new("url(" + url + ")")
245
248
  end
246
249
 
247
250
  protected
@@ -268,27 +271,6 @@ module Sprockets
268
271
  end
269
272
 
270
273
  end
271
-
272
- # Internal: Cache wrapper for Sprockets cache adapter.
273
- class CacheStore < ::Sass::CacheStores::Base
274
- VERSION = '1'
275
-
276
- def initialize(cache, version)
277
- @cache, @version = cache, "#{VERSION}/#{version}"
278
- end
279
-
280
- def _store(key, version, sha, contents)
281
- @cache.set("#{@version}/#{version}/#{key}/#{sha}", contents)
282
- end
283
-
284
- def _retrieve(key, version, sha)
285
- @cache.get("#{@version}/#{version}/#{key}/#{sha}")
286
- end
287
-
288
- def path_to(key)
289
- key
290
- end
291
- end
292
274
  end
293
275
 
294
276
  class ScssProcessor < SassProcessor
@@ -299,7 +281,4 @@ module Sprockets
299
281
 
300
282
  # Deprecated: Use Sprockets::SassProcessor::Functions instead.
301
283
  SassFunctions = SassProcessor::Functions
302
-
303
- # Deprecated: Use Sprockets::SassProcessor::CacheStore instead.
304
- SassCacheStore = SassProcessor::CacheStore
305
284
  end
@@ -44,12 +44,14 @@ module Sprockets
44
44
 
45
45
  # Look up the asset.
46
46
  options = {}
47
- options[:bundle] = !body_only?(env)
47
+ options[:pipeline] = :self if body_only?(env)
48
+
49
+ asset = find_asset(path, options)
48
50
 
49
51
  # 2.x/3.x compatibility hack. Just ignore fingerprints on ?body=1 requests.
50
52
  # 3.x/4.x prefers strong validation of fingerprint to body contents, but
51
53
  # 2.x just ignored it.
52
- if options[:bundle] == false
54
+ if asset && parse_asset_uri(asset.uri)[1][:pipeline] == "self"
53
55
  fingerprint = nil
54
56
  end
55
57
 
@@ -63,8 +65,6 @@ module Sprockets
63
65
  if_none_match = env['HTTP_IF_NONE_MATCH'][/^"(\w+)"$/, 1]
64
66
  end
65
67
 
66
- asset = find_asset(path, options)
67
-
68
68
  if asset.nil?
69
69
  status = :not_found
70
70
  elsif fingerprint && asset.etag != fingerprint
@@ -58,7 +58,7 @@ module Sprockets
58
58
  #
59
59
  # Returns String mime type or nil is no type satisfied the accept value.
60
60
  def resolve_transform_type(type, accept)
61
- find_best_mime_type_match(accept || '*/*', [type].compact + transformers[type].keys)
61
+ find_best_mime_type_match(accept || '*/*', [type].compact + config[:transformers][type].keys)
62
62
  end
63
63
 
64
64
  # Internal: Expand accept type list to include possible transformed types.
@@ -1,5 +1,3 @@
1
- require 'uglifier'
2
-
3
1
  module Sprockets
4
2
  # Public: Uglifier/Uglify compressor.
5
3
  #
@@ -35,7 +33,7 @@ module Sprockets
35
33
 
36
34
  def initialize(options = {})
37
35
  # Feature detect Uglifier 2.0 option support
38
- if Uglifier::DEFAULTS[:copyright]
36
+ if Autoload::Uglifier::DEFAULTS[:copyright]
39
37
  # Uglifier < 2.x
40
38
  options[:copyright] ||= false
41
39
  else
@@ -43,11 +41,11 @@ module Sprockets
43
41
  options[:copyright] ||= :none
44
42
  end
45
43
 
46
- @uglifier = ::Uglifier.new(options)
44
+ @uglifier = Autoload::Uglifier.new(options)
47
45
 
48
46
  @cache_key = [
49
47
  self.class.name,
50
- ::Uglifier::VERSION,
48
+ Autoload::Uglifier::VERSION,
51
49
  VERSION,
52
50
  options
53
51
  ].freeze