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
@@ -106,50 +106,6 @@ module Sprockets
106
106
  @data['files'] ||= {}
107
107
  end
108
108
 
109
- # Deprecated: Compile logical path matching filter into a proc that can be
110
- # passed to logical_paths.select(&proc).
111
- #
112
- # compile_match_filter(proc { |logical_path|
113
- # File.extname(logical_path) == '.js'
114
- # })
115
- #
116
- # compile_match_filter(/application.js/)
117
- #
118
- # compile_match_filter("foo/*.js")
119
- #
120
- # Returns a Proc or raise a TypeError.
121
- def self.compile_match_filter(filter)
122
- # If the filter is already a proc, great nothing to do.
123
- if filter.respond_to?(:call)
124
- filter
125
- # If the filter is a regexp, wrap it in a proc that tests it against the
126
- # logical path.
127
- elsif filter.is_a?(Regexp)
128
- proc { |logical_path| filter.match(logical_path) }
129
- elsif filter.is_a?(String)
130
- # If its an absolute path, detect the matching full filename
131
- if PathUtils.absolute_path?(filter)
132
- proc { |logical_path, filename| filename == filter.to_s }
133
- else
134
- # Otherwise do an fnmatch against the logical path.
135
- proc { |logical_path| File.fnmatch(filter.to_s, logical_path) }
136
- end
137
- else
138
- raise TypeError, "unknown filter type: #{filter.inspect}"
139
- end
140
- end
141
-
142
- # Deprecated: Filter logical paths in environment. Useful for selecting what
143
- # files you want to compile.
144
- #
145
- # Returns an Enumerator.
146
- def filter_logical_paths(*args)
147
- filters = args.flatten.map { |arg| self.class.compile_match_filter(arg) }
148
- environment.logical_paths.select do |a, b|
149
- filters.any? { |f| f.call(a, b) }
150
- end
151
- end
152
-
153
109
  # Public: Find all assets matching pattern set in environment.
154
110
  #
155
111
  # Returns Enumerator of Assets.
@@ -162,6 +118,7 @@ module Sprockets
162
118
 
163
119
  filters = args.flatten.map { |arg| self.class.compile_match_filter(arg) }
164
120
 
121
+ environment = self.environment.cached
165
122
  environment.logical_paths do |logical_path, filename|
166
123
  if filters.any? { |f| f.call(logical_path, filename) }
167
124
  environment.find_all_linked_assets(filename) do |asset|
@@ -173,9 +130,6 @@ module Sprockets
173
130
  nil
174
131
  end
175
132
 
176
- # Deprecated alias.
177
- alias_method :find_logical_paths, :filter_logical_paths
178
-
179
133
  # Compile and write asset to directory. The asset is written to a
180
134
  # fingerprinted filename like
181
135
  # `application-2e8e9a7c6b0aafa0c9bdeec90ea30213.js`. An entry is
@@ -240,25 +194,34 @@ module Sprockets
240
194
  end
241
195
 
242
196
  # Cleanup old assets in the compile directory. By default it will
243
- # keep the latest version plus 2 backups.
244
- def clean(keep = 2)
197
+ # keep the latest version, 2 backups and any created within the past hour.
198
+ #
199
+ # Examples
200
+ #
201
+ # To force only 1 backup to be kept, set count=1 and age=0.
202
+ #
203
+ # To only keep files created within the last 10 minutes, set count=0 and
204
+ # age=600.
205
+ #
206
+ def clean(count = 2, age = 3600)
245
207
  asset_versions = files.group_by { |_, attrs| attrs['logical_path'] }
246
208
 
247
209
  asset_versions.each do |logical_path, versions|
248
210
  current = assets[logical_path]
249
211
 
250
- backups = versions.reject { |path, _|
212
+ versions.reject { |path, _|
251
213
  path == current
252
214
  }.sort_by { |_, attrs|
253
215
  # Sort by timestamp
254
216
  Time.parse(attrs['mtime'])
255
- }.reverse
256
-
257
- # Keep the last N backups
258
- backups = backups[keep..-1] || []
259
-
260
- # Remove old assets
261
- backups.each { |path, _| remove(path) }
217
+ }.reverse.each_with_index.drop_while { |(_, attrs), index|
218
+ age = [0, Time.now - Time.parse(attrs['mtime'])].max
219
+ # Keep if under age or within the count limit
220
+ age < age || index < count
221
+ }.each { |(path, _), _|
222
+ # Remove old assets
223
+ remove(path)
224
+ }
262
225
  end
263
226
  end
264
227
 
@@ -272,9 +235,10 @@ module Sprockets
272
235
  protected
273
236
  # Persist manfiest back to FS
274
237
  def save
238
+ data = json_encode(@data)
275
239
  FileUtils.mkdir_p File.dirname(filename)
276
- File.open(filename, 'w') do |f|
277
- f.write json_encode(@data)
240
+ PathUtils.atomic_write(filename) do |f|
241
+ f.write(data)
278
242
  end
279
243
  end
280
244
 
@@ -1,9 +1,10 @@
1
1
  require 'sprockets/encoding_utils'
2
2
  require 'sprockets/http_utils'
3
+ require 'sprockets/utils'
3
4
 
4
5
  module Sprockets
5
6
  module Mime
6
- include HTTPUtils
7
+ include HTTPUtils, Utils
7
8
 
8
9
  # Public: Mapping of MIME type Strings to properties Hash.
9
10
  #
@@ -13,7 +14,9 @@ module Sprockets
13
14
  # charset - Default Encoding or function to detect encoding
14
15
  #
15
16
  # Returns Hash.
16
- attr_reader :mime_types
17
+ def mime_types
18
+ config[:mime_types]
19
+ end
17
20
 
18
21
  # Internal: Mapping of MIME extension Strings to MIME type Strings.
19
22
  #
@@ -27,7 +30,9 @@ module Sprockets
27
30
  # value - MIME Type String
28
31
  #
29
32
  # Returns Hash.
30
- attr_reader :mime_exts
33
+ def mime_exts
34
+ config[:mime_exts]
35
+ end
31
36
 
32
37
  # Public: Register a new mime type.
33
38
  #
@@ -49,20 +54,25 @@ module Sprockets
49
54
  }
50
55
 
51
56
  charset = options[:charset]
52
- charset ||= EncodingUtils::DETECT if mime_type.start_with?('text/')
57
+ charset ||= :default if mime_type.start_with?('text/')
58
+ charset = EncodingUtils::CHARSET_DETECT[charset] if charset.is_a?(Symbol)
53
59
 
54
- mutate_config(:mime_exts) do |mime_exts|
60
+ self.config = hash_reassoc(config, :mime_exts) do |mime_exts|
55
61
  extnames.each do |extname|
56
62
  mime_exts[extname] = mime_type
57
63
  end
58
64
  mime_exts
59
65
  end
60
66
 
61
- mutate_config(:mime_types) do |mime_types|
67
+ self.config = hash_reassoc(config, :mime_types) do |mime_types|
62
68
  type = { extensions: extnames }
63
69
  type[:charset] = charset if charset
64
70
  mime_types.merge(mime_type => type)
65
71
  end
72
+
73
+ self.config = hash_reassoc(config, :_extnames) do
74
+ compute_extname_map
75
+ end
66
76
  end
67
77
 
68
78
  # Internal: Get detecter function for MIME type.
@@ -95,44 +105,21 @@ module Sprockets
95
105
  end
96
106
  end
97
107
 
98
- # Public: Mapping of supported HTTP Content/Transfer encodings
99
- #
100
- # key - String name
101
- # value - Method/Proc to encode data
102
- #
103
- # Returns Hash.
104
- attr_reader :encodings
105
-
106
- # Public: Register a new encoding.
107
- #
108
- # Examples
109
- #
110
- # register_encoding :gzip, EncodingUtils::GZIP
111
- #
112
- # key - String name
113
- # encode - Method/Proc to encode data
114
- #
115
- # Returns nothing.
116
- def register_encoding(name, encode)
117
- mutate_config(:encodings) do |encodings|
118
- encodings.merge(name.to_s => encode)
119
- end
120
- end
121
-
122
108
  private
123
- # Internal: Get a postprocessor to perform the encoding.
124
- #
125
- # encoding - String encoding.
126
- #
127
- # Returns an Array of Processors.
128
- def unwrap_encoding_processors(encoding)
129
- processors = []
130
- if encoder = self.encodings[encoding]
131
- processors << lambda do |input|
132
- { data: encoder.call(input[:data]), encoding: encoding }
109
+ def compute_extname_map
110
+ graph = {}
111
+
112
+ ([[nil, nil]] + mime_exts.to_a).each do |format_extname, format_type|
113
+ 3.times do |n|
114
+ engines.keys.permutation(n).each do |engine_extnames|
115
+ key = "#{format_extname}#{engine_extnames.join}"
116
+ type = format_type || engine_mime_types[engine_extnames.first]
117
+ graph[key] = {type: type, engines: engine_extnames}
118
+ end
133
119
  end
134
120
  end
135
- processors
121
+
122
+ graph
136
123
  end
137
124
  end
138
125
  end
@@ -0,0 +1,76 @@
1
+ require 'set'
2
+ require 'sprockets/path_utils'
3
+ require 'sprockets/uri_utils'
4
+
5
+ module Sprockets
6
+ # Internal: Related PathUtils helpers that also track all the file system
7
+ # calls they make for caching purposes. All functions return a standard
8
+ # return value and a Set of cache dependency URIs that can be used in the
9
+ # future to see if the returned value should be invalidated from cache.
10
+ #
11
+ # entries_with_dependencies("app/assets/javascripts")
12
+ # # => [
13
+ # # ["application.js", "projects.js", "users.js", ...]
14
+ # # #<Set: {"file-digest:/path/to/app/assets/javascripts"}>
15
+ # # ]
16
+ #
17
+ # The returned dependency set can be passed to resolve_dependencies(deps)
18
+ # to check if the returned result is still fresh. In this case, entry always
19
+ # returns a single path, but multiple calls should accumulate dependencies
20
+ # into a single set thats saved off and checked later.
21
+ #
22
+ # resolve_dependencies(deps)
23
+ # # => "\x01\x02\x03"
24
+ #
25
+ # Later, resolving the same set again will produce a different hash if
26
+ # something on the file system has changed.
27
+ #
28
+ # resolve_dependencies(deps)
29
+ # # => "\x03\x04\x05"
30
+ #
31
+ module PathDependencyUtils
32
+ include PathUtils
33
+ include URIUtils
34
+
35
+ # Internal: List directory entries and return a set of dependencies that
36
+ # would invalid the cached return result.
37
+ #
38
+ # See PathUtils#entries
39
+ #
40
+ # path - String directory path
41
+ #
42
+ # Returns an Array of entry names and a Set of dependency URIs.
43
+ def entries_with_dependencies(path)
44
+ return entries(path), Set.new([build_file_digest_uri(path)])
45
+ end
46
+
47
+ # Internal: List directory filenames and associated Stats under a
48
+ # directory.
49
+ #
50
+ # See PathUtils#stat_directory
51
+ #
52
+ # dir - A String directory
53
+ #
54
+ # Returns an Array of filenames and a Set of dependency URIs.
55
+ def stat_directory_with_dependencies(dir)
56
+ return stat_directory(dir).to_a, Set.new([build_file_digest_uri(dir)])
57
+ end
58
+
59
+ # Internal: List directory filenames and associated Stats under an entire
60
+ # directory tree.
61
+ #
62
+ # See PathUtils#stat_sorted_tree
63
+ #
64
+ # dir - A String directory
65
+ #
66
+ # Returns an Array of filenames and a Set of dependency URIs.
67
+ def stat_sorted_tree_with_dependencies(dir)
68
+ deps = Set.new([build_file_digest_uri(dir)])
69
+ results = stat_sorted_tree(dir).map do |path, stat|
70
+ deps << build_file_digest_uri(path) if stat.directory?
71
+ [path, stat]
72
+ end
73
+ return results, deps
74
+ end
75
+ end
76
+ end
@@ -57,7 +57,7 @@ module Sprockets
57
57
  require 'pathname'
58
58
 
59
59
  # On Windows, ALT_SEPARATOR is \
60
- # Delegate to Pathname nice the logic gets complex.
60
+ # Delegate to Pathname since the logic gets complex.
61
61
  def absolute_path?(path)
62
62
  Pathname.new(path).absolute?
63
63
  end
@@ -91,6 +91,7 @@ module Sprockets
91
91
  # Returns relative String path if subpath is a subpath of path, or nil if
92
92
  # subpath is outside of path.
93
93
  def split_subpath(path, subpath)
94
+ return "" if path == subpath
94
95
  path = File.join(path, '')
95
96
  if subpath.start_with?(path)
96
97
  subpath[path.length..-1]
@@ -123,6 +124,25 @@ module Sprockets
123
124
  File.basename(path).scan(/\.[^.]+/)
124
125
  end
125
126
 
127
+ # Internal: Match path extnames against available extensions.
128
+ #
129
+ # path - String
130
+ # extensions - Hash of String extnames to values
131
+ #
132
+ # Returns [String extname, Object value] or nil nothing matched.
133
+ def match_path_extname(path, extensions)
134
+ match, key = nil, ""
135
+ path_extnames(path).reverse_each do |extname|
136
+ key.prepend(extname)
137
+ if value = extensions[key]
138
+ match = [key.dup, value]
139
+ elsif match
140
+ break
141
+ end
142
+ end
143
+ match
144
+ end
145
+
126
146
  # Internal: Returns all parents for path
127
147
  #
128
148
  # path - String absolute filename or directory
@@ -1,26 +1,41 @@
1
1
  require 'sprockets/path_utils'
2
+ require 'sprockets/utils'
2
3
 
3
4
  module Sprockets
4
5
  module Paths
5
- include PathUtils
6
+ include PathUtils, Utils
6
7
 
7
8
  # Returns `Environment` root.
8
9
  #
9
10
  # All relative paths are expanded with root as its base. To be
10
11
  # useful set this to your applications root directory. (`Rails.root`)
11
- attr_reader :root
12
+ def root
13
+ config[:root]
14
+ end
15
+
16
+ # Internal: Change Environment root.
17
+ #
18
+ # Only the initializer should change the root.
19
+ def root=(path)
20
+ self.config = hash_reassoc(config, :root) do
21
+ File.expand_path(path)
22
+ end
23
+ end
24
+ private :root=
12
25
 
13
26
  # Returns an `Array` of path `String`s.
14
27
  #
15
28
  # These paths will be used for asset logical path lookups.
16
- attr_reader :paths
29
+ def paths
30
+ config[:paths]
31
+ end
17
32
 
18
33
  # Prepend a `path` to the `paths` list.
19
34
  #
20
35
  # Paths at the end of the `Array` have the least priority.
21
36
  def prepend_path(path)
22
- mutate_config(:paths) do |paths|
23
- path = File.expand_path(path, root).dup.freeze
37
+ self.config = hash_reassoc(config, :paths) do |paths|
38
+ path = File.expand_path(path, root).freeze
24
39
  paths.unshift(path)
25
40
  end
26
41
  end
@@ -29,8 +44,8 @@ module Sprockets
29
44
  #
30
45
  # Paths at the beginning of the `Array` have a higher priority.
31
46
  def append_path(path)
32
- mutate_config(:paths) do |paths|
33
- path = File.expand_path(path, root).dup.freeze
47
+ self.config = hash_reassoc(config, :paths) do |paths|
48
+ path = File.expand_path(path, root).freeze
34
49
  paths.push(path)
35
50
  end
36
51
  end
@@ -41,7 +56,7 @@ module Sprockets
41
56
  # completely wipe the paths list and reappend them in the order
42
57
  # you want.
43
58
  def clear_paths
44
- mutate_config(:paths) do |paths|
59
+ self.config = hash_reassoc(config, :paths) do |paths|
45
60
  paths.clear
46
61
  end
47
62
  end
@@ -1,41 +1,27 @@
1
1
  require 'sprockets/engines'
2
- require 'sprockets/lazy_processor'
3
2
  require 'sprockets/legacy_proc_processor'
4
3
  require 'sprockets/legacy_tilt_processor'
5
4
  require 'sprockets/mime'
5
+ require 'sprockets/processor_utils'
6
+ require 'sprockets/uri_utils'
6
7
  require 'sprockets/utils'
7
8
 
8
9
  module Sprockets
9
10
  # `Processing` is an internal mixin whose public methods are exposed on
10
11
  # the `Environment` and `CachedEnvironment` classes.
11
12
  module Processing
13
+ include ProcessorUtils, URIUtils, Utils
14
+
12
15
  # Preprocessors are ran before Postprocessors and Engine
13
16
  # processors.
14
- attr_reader :preprocessors
15
-
16
- # Internal: Find and load preprocessors by mime type.
17
- #
18
- # mime_type - String MIME type.
19
- #
20
- # Returns Array of Procs.
21
- def unwrap_preprocessors(mime_type)
22
- preprocessors[mime_type].map do |processor|
23
- unwrap_processor(processor)
24
- end
17
+ def preprocessors
18
+ config[:preprocessors]
25
19
  end
20
+ alias_method :processors, :preprocessors
26
21
 
27
22
  # Postprocessors are ran after Preprocessors and Engine processors.
28
- attr_reader :postprocessors
29
-
30
- # Internal: Find and load postprocessors by mime type.
31
- #
32
- # mime_type - String MIME type.
33
- #
34
- # Returns Array of Procs.
35
- def unwrap_postprocessors(mime_type)
36
- postprocessors[mime_type].map do |processor|
37
- unwrap_processor(processor)
38
- end
23
+ def postprocessors
24
+ config[:postprocessors]
39
25
  end
40
26
 
41
27
  # Registers a new Preprocessor `klass` for `mime_type`.
@@ -48,12 +34,10 @@ module Sprockets
48
34
  # data.gsub(...)
49
35
  # end
50
36
  #
51
- def register_preprocessor(mime_type, klass, &block)
52
- mutate_hash_config(:preprocessors, mime_type) do |processors|
53
- processors.push(wrap_processor(klass, block))
54
- processors
55
- end
37
+ def register_preprocessor(*args, &block)
38
+ register_config_processor(:preprocessors, *args, &block)
56
39
  end
40
+ alias_method :register_processor, :register_preprocessor
57
41
 
58
42
  # Registers a new Postprocessor `klass` for `mime_type`.
59
43
  #
@@ -65,61 +49,31 @@ module Sprockets
65
49
  # data.gsub(...)
66
50
  # end
67
51
  #
68
- def register_postprocessor(mime_type, klass, proc = nil, &block)
69
- proc ||= block
70
- mutate_hash_config(:postprocessors, mime_type) do |processors|
71
- processors.push(wrap_processor(klass, proc))
72
- processors
73
- end
52
+ def register_postprocessor(*args, &block)
53
+ register_config_processor(:postprocessors, *args, &block)
74
54
  end
75
55
 
76
56
  # Remove Preprocessor `klass` for `mime_type`.
77
57
  #
78
58
  # unregister_preprocessor 'text/css', Sprockets::DirectiveProcessor
79
59
  #
80
- def unregister_preprocessor(mime_type, klass)
81
- if klass.is_a?(String) || klass.is_a?(Symbol)
82
- klass = preprocessors[mime_type].detect { |cls|
83
- cls.respond_to?(:name) && cls.name == "Sprockets::LegacyProcProcessor (#{klass})"
84
- }
85
- end
86
-
87
- mutate_hash_config(:preprocessors, mime_type) do |processors|
88
- processors.delete(klass)
89
- processors
90
- end
60
+ def unregister_preprocessor(*args)
61
+ unregister_config_processor(:preprocessors, *args)
91
62
  end
63
+ alias_method :unregister_processor, :unregister_preprocessor
92
64
 
93
65
  # Remove Postprocessor `klass` for `mime_type`.
94
66
  #
95
67
  # unregister_postprocessor 'text/css', Sprockets::DirectiveProcessor
96
68
  #
97
- def unregister_postprocessor(mime_type, klass)
98
- if klass.is_a?(String) || klass.is_a?(Symbol)
99
- klass = postprocessors[mime_type].detect { |cls|
100
- cls.respond_to?(:name) && cls.name == "Sprockets::LegacyProcProcessor (#{klass})"
101
- }
102
- end
103
-
104
- mutate_hash_config(:postprocessors, mime_type) do |processors|
105
- processors.delete(klass)
106
- processors
107
- end
69
+ def unregister_postprocessor(*args)
70
+ unregister_config_processor(:postprocessors, *args)
108
71
  end
109
72
 
110
73
  # Bundle Processors are ran on concatenated assets rather than
111
74
  # individual files.
112
- attr_reader :bundle_processors
113
-
114
- # Internal: Find and load bundle processors by mime type.
115
- #
116
- # mime_type - String MIME type.
117
- #
118
- # Returns Array of Procs.
119
- def unwrap_bundle_processors(mime_type)
120
- bundle_processors[mime_type].map do |processor|
121
- unwrap_processor(processor)
122
- end
75
+ def bundle_processors
76
+ config[:bundle_processors]
123
77
  end
124
78
 
125
79
  # Registers a new Bundle Processor `klass` for `mime_type`.
@@ -132,33 +86,23 @@ module Sprockets
132
86
  # data.gsub(...)
133
87
  # end
134
88
  #
135
- def register_bundle_processor(mime_type, klass, &block)
136
- mutate_hash_config(:bundle_processors, mime_type) do |processors|
137
- processors.push(wrap_processor(klass, block))
138
- processors
139
- end
89
+ def register_bundle_processor(*args, &block)
90
+ register_config_processor(:bundle_processors, *args, &block)
140
91
  end
141
92
 
142
93
  # Remove Bundle Processor `klass` for `mime_type`.
143
94
  #
144
95
  # unregister_bundle_processor 'application/javascript', Sprockets::DirectiveProcessor
145
96
  #
146
- def unregister_bundle_processor(mime_type, klass)
147
- if klass.is_a?(String) || klass.is_a?(Symbol)
148
- klass = bundle_processors[mime_type].detect { |cls|
149
- cls.respond_to?(:name) && cls.name == "Sprockets::LegacyProcProcessor (#{klass})"
150
- }
151
- end
152
-
153
- mutate_hash_config(:bundle_processors, mime_type) do |processors|
154
- processors.delete(klass)
155
- processors
156
- end
97
+ def unregister_bundle_processor(*args)
98
+ unregister_config_processor(:bundle_processors, *args)
157
99
  end
158
100
 
159
101
  # Internal: Two dimensional Hash of reducer functions for a given mime type
160
102
  # and asset metadata key.
161
- attr_reader :bundle_reducers
103
+ def bundle_reducers
104
+ config[:bundle_reducers]
105
+ end
162
106
 
163
107
  # Public: Register bundle metadata reducer function.
164
108
  #
@@ -195,7 +139,7 @@ module Sprockets
195
139
  raise ArgumentError, "wrong number of arguments (#{args.size} for 0..2)"
196
140
  end
197
141
 
198
- mutate_hash_config(:bundle_reducers, mime_type) do |reducers|
142
+ self.config = hash_reassoc(config, :bundle_reducers, mime_type) do |reducers|
199
143
  reducers.merge(key => [initial, reducer])
200
144
  end
201
145
  end
@@ -205,7 +149,7 @@ module Sprockets
205
149
  # mime_type - String MIME type
206
150
  #
207
151
  # Returns an Array of [initial, reducer_proc] pairs.
208
- def unwrap_bundle_reducers(mime_type)
152
+ def load_bundle_reducers(mime_type)
209
153
  self.bundle_reducers['*/*'].merge(self.bundle_reducers[mime_type])
210
154
  end
211
155
 
@@ -231,10 +175,81 @@ module Sprockets
231
175
  end
232
176
  end
233
177
 
178
+ protected
179
+ def resolve_processors_cache_key_uri(uri)
180
+ params = parse_uri_query_params(uri[11..-1])
181
+ params[:engine_extnames] = params[:engines] ? params[:engines].split(',') : []
182
+ processors = processors_for(params[:type], params[:file_type], params[:engine_extnames], params[:skip_bundle])
183
+ processors_cache_keys(processors)
184
+ end
185
+
186
+ def build_processors_uri(type, file_type, engine_extnames, skip_bundle)
187
+ engines = engine_extnames.join(',') if engine_extnames.any?
188
+ query = encode_uri_query_params(
189
+ type: type,
190
+ file_type: file_type,
191
+ engines: engines,
192
+ skip_bundle: skip_bundle
193
+ )
194
+ "processors:#{query}"
195
+ end
196
+
197
+ def processors_for(type, file_type, engine_extnames, skip_bundle)
198
+ processors = []
199
+
200
+ bundled_processors = skip_bundle ? [] : config[:bundle_processors][type]
201
+
202
+ if bundled_processors.any?
203
+ processors.concat bundled_processors
204
+ else
205
+ processors.concat config[:postprocessors][type]
206
+
207
+ if type != file_type && processor = transformers[file_type][type]
208
+ processors << processor
209
+ end
210
+
211
+ processors.concat engine_extnames.map { |ext| engines[ext] }
212
+ processors.concat config[:preprocessors][file_type]
213
+ end
214
+
215
+ if processors.any? || mime_type_charset_detecter(type)
216
+ processors << FileReader
217
+ end
218
+
219
+ processors
220
+ end
221
+
234
222
  private
223
+ def register_config_processor(type, mime_type, klass, proc = nil, &block)
224
+ proc ||= block
225
+ processor = wrap_processor(klass, proc)
226
+
227
+ self.config = hash_reassoc(config, type, mime_type) do |processors|
228
+ processors.unshift(processor)
229
+ processors
230
+ end
231
+
232
+ compute_transformers!
233
+ end
234
+
235
+ def unregister_config_processor(type, mime_type, klass)
236
+ if klass.is_a?(String) || klass.is_a?(Symbol)
237
+ klass = config[type][mime_type].detect do |cls|
238
+ cls.respond_to?(:name) && cls.name == "Sprockets::LegacyProcProcessor (#{klass})"
239
+ end
240
+ end
241
+
242
+ self.config = hash_reassoc(config, type, mime_type) do |processors|
243
+ processors.delete(klass)
244
+ processors
245
+ end
246
+
247
+ compute_transformers!
248
+ end
249
+
235
250
  def wrap_processor(klass, proc)
236
251
  if !proc
237
- if klass.class == Sprockets::LazyProcessor || klass.respond_to?(:call)
252
+ if klass.class == Sprockets::AutoloadProcessor || klass.respond_to?(:call)
238
253
  klass
239
254
  else
240
255
  LegacyTiltProcessor.new(klass)
@@ -245,9 +260,5 @@ module Sprockets
245
260
  proc
246
261
  end
247
262
  end
248
-
249
- def unwrap_processor(processor)
250
- processor.respond_to?(:unwrap) ? processor.unwrap : processor
251
- end
252
263
  end
253
264
  end