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

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 (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