sprockets 3.7.3 → 4.2.2

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -259
  3. data/{LICENSE → MIT-LICENSE} +2 -2
  4. data/README.md +527 -320
  5. data/bin/sprockets +11 -7
  6. data/lib/rake/sprocketstask.rb +9 -4
  7. data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
  8. data/lib/sprockets/asset.rb +39 -27
  9. data/lib/sprockets/autoload/babel.rb +8 -0
  10. data/lib/sprockets/autoload/closure.rb +1 -0
  11. data/lib/sprockets/autoload/coffee_script.rb +1 -0
  12. data/lib/sprockets/autoload/eco.rb +1 -0
  13. data/lib/sprockets/autoload/ejs.rb +1 -0
  14. data/lib/sprockets/autoload/jsminc.rb +8 -0
  15. data/lib/sprockets/autoload/sass.rb +1 -0
  16. data/lib/sprockets/autoload/sassc.rb +8 -0
  17. data/lib/sprockets/autoload/uglifier.rb +1 -0
  18. data/lib/sprockets/autoload/yui.rb +1 -0
  19. data/lib/sprockets/autoload/zopfli.rb +7 -0
  20. data/lib/sprockets/autoload.rb +5 -0
  21. data/lib/sprockets/babel_processor.rb +66 -0
  22. data/lib/sprockets/base.rb +49 -12
  23. data/lib/sprockets/bower.rb +6 -3
  24. data/lib/sprockets/bundle.rb +41 -5
  25. data/lib/sprockets/cache/file_store.rb +25 -3
  26. data/lib/sprockets/cache/memory_store.rb +28 -10
  27. data/lib/sprockets/cache/null_store.rb +8 -0
  28. data/lib/sprockets/cache.rb +37 -2
  29. data/lib/sprockets/cached_environment.rb +15 -20
  30. data/lib/sprockets/closure_compressor.rb +1 -0
  31. data/lib/sprockets/coffee_script_processor.rb +19 -5
  32. data/lib/sprockets/compressing.rb +43 -3
  33. data/lib/sprockets/configuration.rb +5 -9
  34. data/lib/sprockets/context.rb +99 -25
  35. data/lib/sprockets/dependencies.rb +2 -1
  36. data/lib/sprockets/digest_utils.rb +35 -18
  37. data/lib/sprockets/directive_processor.rb +64 -38
  38. data/lib/sprockets/eco_processor.rb +2 -1
  39. data/lib/sprockets/ejs_processor.rb +2 -1
  40. data/lib/sprockets/encoding_utils.rb +2 -2
  41. data/lib/sprockets/environment.rb +9 -4
  42. data/lib/sprockets/erb_processor.rb +33 -32
  43. data/lib/sprockets/errors.rb +1 -0
  44. data/lib/sprockets/exporters/base.rb +71 -0
  45. data/lib/sprockets/exporters/file_exporter.rb +24 -0
  46. data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
  47. data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
  48. data/lib/sprockets/exporting.rb +73 -0
  49. data/lib/sprockets/file_reader.rb +1 -0
  50. data/lib/sprockets/http_utils.rb +25 -7
  51. data/lib/sprockets/jsminc_compressor.rb +32 -0
  52. data/lib/sprockets/jst_processor.rb +11 -10
  53. data/lib/sprockets/loader.rb +91 -69
  54. data/lib/sprockets/manifest.rb +67 -64
  55. data/lib/sprockets/manifest_utils.rb +9 -6
  56. data/lib/sprockets/mime.rb +8 -62
  57. data/lib/sprockets/npm.rb +52 -0
  58. data/lib/sprockets/path_dependency_utils.rb +3 -11
  59. data/lib/sprockets/path_digest_utils.rb +2 -1
  60. data/lib/sprockets/path_utils.rb +88 -8
  61. data/lib/sprockets/paths.rb +1 -0
  62. data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
  63. data/lib/sprockets/processing.rb +32 -62
  64. data/lib/sprockets/processor_utils.rb +28 -38
  65. data/lib/sprockets/resolve.rb +177 -93
  66. data/lib/sprockets/sass_cache_store.rb +2 -6
  67. data/lib/sprockets/sass_compressor.rb +13 -1
  68. data/lib/sprockets/sass_functions.rb +1 -0
  69. data/lib/sprockets/sass_importer.rb +1 -0
  70. data/lib/sprockets/sass_processor.rb +31 -10
  71. data/lib/sprockets/sassc_compressor.rb +56 -0
  72. data/lib/sprockets/sassc_processor.rb +297 -0
  73. data/lib/sprockets/server.rb +63 -40
  74. data/lib/sprockets/source_map_processor.rb +66 -0
  75. data/lib/sprockets/source_map_utils.rb +483 -0
  76. data/lib/sprockets/transformers.rb +63 -35
  77. data/lib/sprockets/uglifier_compressor.rb +21 -11
  78. data/lib/sprockets/unloaded_asset.rb +13 -11
  79. data/lib/sprockets/uri_tar.rb +1 -0
  80. data/lib/sprockets/uri_utils.rb +19 -16
  81. data/lib/sprockets/utils/gzip.rb +46 -14
  82. data/lib/sprockets/utils.rb +64 -90
  83. data/lib/sprockets/version.rb +2 -1
  84. data/lib/sprockets/yui_compressor.rb +1 -0
  85. data/lib/sprockets.rb +102 -39
  86. metadata +148 -45
  87. data/lib/sprockets/coffee_script_template.rb +0 -17
  88. data/lib/sprockets/deprecation.rb +0 -90
  89. data/lib/sprockets/eco_template.rb +0 -17
  90. data/lib/sprockets/ejs_template.rb +0 -17
  91. data/lib/sprockets/engines.rb +0 -92
  92. data/lib/sprockets/erb_template.rb +0 -11
  93. data/lib/sprockets/legacy.rb +0 -330
  94. data/lib/sprockets/legacy_proc_processor.rb +0 -35
  95. data/lib/sprockets/legacy_tilt_processor.rb +0 -29
  96. data/lib/sprockets/sass_template.rb +0 -19
@@ -1,10 +1,10 @@
1
- require 'pathname'
1
+ # frozen_string_literal: true
2
2
  require 'rack/utils'
3
3
  require 'set'
4
4
  require 'sprockets/errors'
5
+ require 'delegate'
5
6
 
6
7
  module Sprockets
7
- # Deprecated: `Context` provides helper methods to all processors.
8
8
  # They are typically accessed by ERB templates. You can mix in custom helpers
9
9
  # by injecting them into `Environment#context_class`. Do not mix them into
10
10
  # `Context` directly.
@@ -19,10 +19,25 @@ module Sprockets
19
19
  # The `Context` also collects dependencies declared by
20
20
  # assets. See `DirectiveProcessor` for an example of this.
21
21
  class Context
22
- attr_reader :environment, :filename, :pathname
22
+ # Internal: Proxy for ENV that keeps track of the environment variables used
23
+ class ENVProxy < SimpleDelegator
24
+ def initialize(context)
25
+ @context = context
26
+ super(ENV)
27
+ end
23
28
 
24
- # Deprecated
25
- attr_accessor :__LINE__
29
+ def [](key)
30
+ @context.depend_on_env(key)
31
+ super
32
+ end
33
+
34
+ def fetch(key, *)
35
+ @context.depend_on_env(key)
36
+ super
37
+ end
38
+ end
39
+
40
+ attr_reader :environment, :filename
26
41
 
27
42
  def initialize(input)
28
43
  @environment = input[:environment]
@@ -31,7 +46,6 @@ module Sprockets
31
46
  @logical_path = input[:name]
32
47
  @filename = input[:filename]
33
48
  @dirname = File.dirname(@filename)
34
- @pathname = Pathname.new(@filename)
35
49
  @content_type = input[:content_type]
36
50
 
37
51
  @required = Set.new(@metadata[:required])
@@ -47,6 +61,10 @@ module Sprockets
47
61
  dependencies: @dependencies }
48
62
  end
49
63
 
64
+ def env_proxy
65
+ ENVProxy.new(self)
66
+ end
67
+
50
68
  # Returns the environment path that contains the file.
51
69
  #
52
70
  # If `app/javascripts` and `app/stylesheets` are in your path, and
@@ -79,13 +97,13 @@ module Sprockets
79
97
  # resolve("./bar.js")
80
98
  # # => "file:///path/to/app/javascripts/bar.js?type=application/javascript"
81
99
  #
82
- # path - String logical or absolute path
83
- # options
84
- # accept - String content accept type
100
+ # path - String logical or absolute path
101
+ # accept - String content accept type
85
102
  #
86
103
  # Returns an Asset URI String.
87
- def resolve(path, options = {})
88
- uri, deps = environment.resolve!(path, options.merge(base_path: @dirname))
104
+ def resolve(path, **kargs)
105
+ kargs[:base_path] = @dirname
106
+ uri, deps = environment.resolve!(path, **kargs)
89
107
  @dependencies.merge(deps)
90
108
  uri
91
109
  end
@@ -105,15 +123,13 @@ module Sprockets
105
123
  # including it.
106
124
  #
107
125
  # This is used for caching purposes. Any changes made to
108
- # the dependency file with invalidate the cache of the
126
+ # the dependency file will invalidate the cache of the
109
127
  # source file.
110
128
  def depend_on(path)
111
- path = path.to_s if path.is_a?(Pathname)
112
-
113
129
  if environment.absolute_path?(path) && environment.stat(path)
114
130
  @dependencies << environment.build_file_digest_uri(path)
115
131
  else
116
- resolve(path, compat: false)
132
+ resolve(path)
117
133
  end
118
134
  nil
119
135
  end
@@ -123,10 +139,19 @@ module Sprockets
123
139
  #
124
140
  # This is used for caching purposes. Any changes that would
125
141
  # invalidate the dependency asset will invalidate the source
126
- # file. Unlike `depend_on`, this will include recursively include
142
+ # file. Unlike `depend_on`, this will recursively include
127
143
  # the target asset's dependencies.
128
144
  def depend_on_asset(path)
129
- load(resolve(path, compat: false))
145
+ load(resolve(path))
146
+ end
147
+
148
+ # `depend_on_env` allows you to state a dependency on an environment
149
+ # variable.
150
+ #
151
+ # This is used for caching purposes. Any changes in the value of the
152
+ # environment variable will invalidate the cache of the source file.
153
+ def depend_on_env(key)
154
+ @dependencies << "env:#{key}"
130
155
  end
131
156
 
132
157
  # `require_asset` declares `path` as a dependency of the file. The
@@ -139,7 +164,7 @@ module Sprockets
139
164
  # <%= require_asset "#{framework}.js" %>
140
165
  #
141
166
  def require_asset(path)
142
- @required << resolve(path, accept: @content_type, pipeline: :self, compat: false)
167
+ @required << resolve(path, accept: @content_type, pipeline: :self)
143
168
  nil
144
169
  end
145
170
 
@@ -147,7 +172,7 @@ module Sprockets
147
172
  # `path` must be an asset which may or may not already be included
148
173
  # in the bundle.
149
174
  def stub_asset(path)
150
- @stubbed << resolve(path, accept: @content_type, pipeline: :self, compat: false)
175
+ @stubbed << resolve(path, accept: @content_type, pipeline: :self)
151
176
  nil
152
177
  end
153
178
 
@@ -162,9 +187,10 @@ module Sprockets
162
187
  asset
163
188
  end
164
189
 
165
- # Returns a Base64-encoded `data:` URI with the contents of the
166
- # asset at the specified path, and marks that path as a dependency
167
- # of the current file.
190
+ # Returns a `data:` URI with the contents of the asset at the specified
191
+ # path, and marks that path as a dependency of the current file.
192
+ #
193
+ # Uses URI encoding for SVG files, base64 encoding for all the other files.
168
194
  #
169
195
  # Use `asset_data_uri` from ERB with CSS or JavaScript assets:
170
196
  #
@@ -174,15 +200,18 @@ module Sprockets
174
200
  #
175
201
  def asset_data_uri(path)
176
202
  asset = depend_on_asset(path)
177
- data = EncodingUtils.base64(asset.source)
178
- "data:#{asset.content_type};base64,#{Rack::Utils.escape(data)}"
203
+ if asset.content_type == 'image/svg+xml'
204
+ svg_asset_data_uri(asset)
205
+ else
206
+ base64_asset_data_uri(asset)
207
+ end
179
208
  end
180
209
 
181
210
  # Expands logical path to full url to asset.
182
211
  #
183
212
  # NOTE: This helper is currently not implemented and should be
184
213
  # customized by the application. Though, in the future, some
185
- # basics implemention may be provided with different methods that
214
+ # basic implementation may be provided with different methods that
186
215
  # are required to be overridden.
187
216
  def asset_path(path, options = {})
188
217
  message = <<-EOS
@@ -227,5 +256,50 @@ Extend your environment context with a custom method.
227
256
  def stylesheet_path(path)
228
257
  asset_path(path, type: :stylesheet)
229
258
  end
259
+
260
+ protected
261
+
262
+ # Returns a URI-encoded data URI (always "-quoted).
263
+ def svg_asset_data_uri(asset)
264
+ svg = asset.source.dup
265
+ optimize_svg_for_uri_escaping!(svg)
266
+ data = Rack::Utils.escape(svg)
267
+ optimize_quoted_uri_escapes!(data)
268
+ "\"data:#{asset.content_type};charset=utf-8,#{data}\""
269
+ end
270
+
271
+ # Returns a Base64-encoded data URI.
272
+ def base64_asset_data_uri(asset)
273
+ data = Rack::Utils.escape(EncodingUtils.base64(asset.source))
274
+ "data:#{asset.content_type};base64,#{data}"
275
+ end
276
+
277
+ # Optimizes an SVG for being URI-escaped.
278
+ #
279
+ # This method only performs these basic but crucial optimizations:
280
+ # * Replaces " with ', because ' does not need escaping.
281
+ # * Removes comments, meta, doctype, and newlines.
282
+ # * Collapses whitespace.
283
+ def optimize_svg_for_uri_escaping!(svg)
284
+ # Remove comments, xml meta, and doctype
285
+ svg.gsub!(/<!--.*?-->|<\?.*?\?>|<!.*?>/m, '')
286
+ # Replace consecutive whitespace and newlines with a space
287
+ svg.gsub!(/\s+/, ' ')
288
+ # Collapse inter-tag whitespace
289
+ svg.gsub!('> <', '><')
290
+ # Replace " with '
291
+ svg.gsub!(/([\w:])="(.*?)"/, "\\1='\\2'")
292
+ svg.strip!
293
+ end
294
+
295
+ # Un-escapes characters in the given URI-escaped string that do not need
296
+ # escaping in "-quoted data URIs.
297
+ def optimize_quoted_uri_escapes!(escaped)
298
+ escaped.gsub!('%3D', '=')
299
+ escaped.gsub!('%3A', ':')
300
+ escaped.gsub!('%2F', '/')
301
+ escaped.gsub!('%27', "'")
302
+ escaped.tr!('+', ' ')
303
+ end
230
304
  end
231
305
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/digest_utils'
2
3
  require 'sprockets/path_digest_utils'
3
4
  require 'sprockets/uri_utils'
@@ -39,7 +40,7 @@ module Sprockets
39
40
  end
40
41
  end
41
42
 
42
- # Public: Add environmental dependency inheirted by all assets.
43
+ # Public: Add environmental dependency inherited by all assets.
43
44
  #
44
45
  # uri - String dependency URI
45
46
  #
@@ -1,4 +1,4 @@
1
- require 'digest/md5'
1
+ # frozen_string_literal: true
2
2
  require 'digest/sha1'
3
3
  require 'digest/sha2'
4
4
  require 'set'
@@ -18,7 +18,6 @@ module Sprockets
18
18
 
19
19
  # Internal: Maps digest bytesize to the digest class.
20
20
  DIGEST_SIZES = {
21
- 16 => Digest::MD5,
22
21
  20 => Digest::SHA1,
23
22
  32 => Digest::SHA256,
24
23
  48 => Digest::SHA384,
@@ -62,23 +61,16 @@ module Sprockets
62
61
  },
63
62
  Set => ->(val, digest) {
64
63
  digest << 'Set'.freeze
65
- ADD_VALUE_TO_DIGEST[Array].call(val.to_a, digest)
64
+ ADD_VALUE_TO_DIGEST[Array].call(val, digest)
66
65
  },
67
66
  Encoding => ->(val, digest) {
68
67
  digest << 'Encoding'.freeze
69
68
  digest << val.name
70
- },
71
- }
72
- if 0.class != Integer # Ruby < 2.4
73
- ADD_VALUE_TO_DIGEST[Fixnum] = ->(val, digest) {
74
- digest << 'Integer'.freeze
75
- digest << val.to_s
76
- }
77
- ADD_VALUE_TO_DIGEST[Bignum] = ->(val, digest) {
78
- digest << 'Integer'.freeze
79
- digest << val.to_s
80
69
  }
81
- end
70
+ }
71
+
72
+ ADD_VALUE_TO_DIGEST.compare_by_identity.rehash
73
+
82
74
  ADD_VALUE_TO_DIGEST.default_proc = ->(_, val) {
83
75
  raise TypeError, "couldn't digest #{ val }"
84
76
  }
@@ -93,10 +85,18 @@ module Sprockets
93
85
  #
94
86
  # Returns a String digest of the object.
95
87
  def digest(obj)
96
- digest = digest_class.new
88
+ build_digest(obj).digest
89
+ end
97
90
 
98
- ADD_VALUE_TO_DIGEST[obj.class].call(obj, digest)
99
- digest.digest
91
+ # Internal: Generate a hexdigest for a nested JSON serializable object.
92
+ #
93
+ # The same as `pack_hexdigest(digest(obj))`.
94
+ #
95
+ # obj - A JSON serializable object.
96
+ #
97
+ # Returns a String digest of the object.
98
+ def hexdigest(obj)
99
+ build_digest(obj).hexdigest!
100
100
  end
101
101
 
102
102
  # Internal: Pack a binary digest to a hex encoded string.
@@ -105,7 +105,7 @@ module Sprockets
105
105
  #
106
106
  # Returns hex String.
107
107
  def pack_hexdigest(bin)
108
- bin.unpack('H*').first
108
+ bin.unpack('H*'.freeze).first
109
109
  end
110
110
 
111
111
  # Internal: Unpack a hex encoded digest string into binary bytes.
@@ -176,5 +176,22 @@ module Sprockets
176
176
  def hexdigest_integrity_uri(hexdigest)
177
177
  integrity_uri(unpack_hexdigest(hexdigest))
178
178
  end
179
+
180
+ # Internal: Checks an asset name for a valid digest
181
+ #
182
+ # name - The name of the asset
183
+ #
184
+ # Returns true if the name contains a digest like string and .digested before the extension
185
+ def already_digested?(name)
186
+ return name =~ /-([0-9a-zA-Z]{7,128})\.digested/
187
+ end
188
+
189
+ private
190
+ def build_digest(obj)
191
+ digest = digest_class.new
192
+
193
+ ADD_VALUE_TO_DIGEST[obj.class].call(obj, digest)
194
+ digest
195
+ end
179
196
  end
180
197
  end
@@ -1,5 +1,4 @@
1
- # frozen_string_literal: false
2
-
1
+ # frozen_string_literal: true
3
2
  require 'set'
4
3
  require 'shellwords'
5
4
 
@@ -36,8 +35,6 @@ module Sprockets
36
35
  # env.register_processor('text/css', MyProcessor)
37
36
  #
38
37
  class DirectiveProcessor
39
- VERSION = '1'
40
-
41
38
  # Directives are denoted by a `=` followed by the name, then
42
39
  # argument list.
43
40
  #
@@ -52,18 +49,16 @@ module Sprockets
52
49
  /x
53
50
 
54
51
  def self.instance
55
- @instance ||= new(
56
- # Deprecated: Default to C and Ruby comment styles
57
- comments: ["//", ["/*", "*/"]] + ["#", ["###", "###"]]
58
- )
52
+ # Default to C comment styles
53
+ @instance ||= new(comments: ["//", ["/*", "*/"]])
59
54
  end
60
55
 
61
56
  def self.call(input)
62
57
  instance.call(input)
63
58
  end
64
59
 
65
- def initialize(options = {})
66
- @header_pattern = compile_header_pattern(Array(options[:comments]))
60
+ def initialize(comments: [])
61
+ @header_pattern = compile_header_pattern(Array(comments))
67
62
  end
68
63
 
69
64
  def call(input)
@@ -75,20 +70,28 @@ module Sprockets
75
70
  @uri = input[:uri]
76
71
  @filename = input[:filename]
77
72
  @dirname = File.dirname(@filename)
78
- @content_type = input[:content_type]
73
+ # If loading a source map file like `application.js.map` resolve
74
+ # dependencies using `.js` instead of `.js.map`
75
+ @content_type = SourceMapProcessor.original_content_type(input[:content_type], error_when_not_found: false)
79
76
  @required = Set.new(input[:metadata][:required])
80
77
  @stubbed = Set.new(input[:metadata][:stubbed])
81
78
  @links = Set.new(input[:metadata][:links])
82
79
  @dependencies = Set.new(input[:metadata][:dependencies])
80
+ @to_link = Set.new
81
+ @to_load = Set.new
83
82
 
84
83
  data, directives = process_source(input[:data])
85
84
  process_directives(directives)
86
85
 
87
- { data: data,
88
- required: @required,
89
- stubbed: @stubbed,
90
- links: @links,
91
- dependencies: @dependencies }
86
+ {
87
+ data: data,
88
+ required: @required,
89
+ stubbed: @stubbed,
90
+ links: @links,
91
+ to_load: @to_load,
92
+ to_link: @to_link,
93
+ dependencies: @dependencies
94
+ }
92
95
  end
93
96
 
94
97
  protected
@@ -118,9 +121,9 @@ module Sprockets
118
121
 
119
122
  header, directives = extract_directives(header)
120
123
 
121
- data = ""
124
+ data = +""
122
125
  data.force_encoding(body.encoding)
123
- data << header << "\n" unless header.empty?
126
+ data << header unless header.empty?
124
127
  data << body
125
128
  # Ensure body ends in a new line
126
129
  data << "\n" if data.length > 0 && data[-1] != "\n"
@@ -136,7 +139,7 @@ module Sprockets
136
139
  # [[1, "require", "foo"], [2, "require", "bar"]]
137
140
  #
138
141
  def extract_directives(header)
139
- processed_header = ""
142
+ processed_header = +""
140
143
  directives = []
141
144
 
142
145
  header.lines.each_with_index do |line, index|
@@ -151,7 +154,11 @@ module Sprockets
151
154
  processed_header << line
152
155
  end
153
156
 
154
- return processed_header.chomp, directives
157
+ processed_header.chomp!
158
+ # Ensure header ends in a new line like before it was processed
159
+ processed_header << "\n" if processed_header.length > 0 && header[-1] == "\n"
160
+
161
+ return processed_header, directives
155
162
  end
156
163
 
157
164
  # Gathers comment directives in the source and processes them.
@@ -164,7 +171,7 @@ module Sprockets
164
171
  # `process_require_glob_directive`.
165
172
  #
166
173
  # class DirectiveProcessor < Sprockets::DirectiveProcessor
167
- # def process_require_glob_directive
174
+ # def process_require_glob_directive(glob)
168
175
  # Dir["#{dirname}/#{glob}"].sort.each do |filename|
169
176
  # require(filename)
170
177
  # end
@@ -189,7 +196,7 @@ module Sprockets
189
196
 
190
197
  # The `require` directive functions similar to Ruby's own `require`.
191
198
  # It provides a way to declare a dependency on a file in your path
192
- # and ensures its only loaded once before the source file.
199
+ # and ensures it's only loaded once before the source file.
193
200
  #
194
201
  # `require` works with files in the environment path:
195
202
  #
@@ -267,15 +274,33 @@ module Sprockets
267
274
  # it.
268
275
  #
269
276
  # This is used for caching purposes. Any changes that would
270
- # invalid the asset dependency will invalidate the cache our the
271
- # source file.
277
+ # invalidate the asset dependency will invalidate the cache of
278
+ # the source file.
272
279
  #
273
280
  # Unlike `depend_on`, the path must be a requirable asset.
274
281
  #
275
282
  # //= depend_on_asset "bar.js"
276
283
  #
277
284
  def process_depend_on_asset_directive(path)
278
- load(resolve(path))
285
+ to_load(resolve(path))
286
+ end
287
+
288
+ # Allows you to state a dependency on a relative directory
289
+ # without including it.
290
+ #
291
+ # This is used for caching purposes. Any changes made to
292
+ # the dependency directory will invalidate the cache of the
293
+ # source file.
294
+ #
295
+ # This is useful if you are using ERB and File.read to pull
296
+ # in contents from multiple files in a directory.
297
+ #
298
+ # //= depend_on_directory ./data
299
+ #
300
+ def process_depend_on_directory_directive(path = ".", accept = nil)
301
+ path = expand_relative_dirname(:depend_on_directory, path)
302
+ accept = expand_accept_shorthand(accept)
303
+ resolve_paths(*@environment.stat_directory_with_dependencies(path), accept: accept)
279
304
  end
280
305
 
281
306
  # Allows dependency to be excluded from the asset bundle.
@@ -299,7 +324,8 @@ module Sprockets
299
324
  # /*= link "logo.png" */
300
325
  #
301
326
  def process_link_directive(path)
302
- @links << load(resolve(path)).uri
327
+ uri = to_load(resolve(path))
328
+ @to_link << uri
303
329
  end
304
330
 
305
331
  # `link_directory` links all the files inside a single
@@ -309,7 +335,7 @@ module Sprockets
309
335
  # //= link_directory "./fonts"
310
336
  #
311
337
  # Use caution when linking against JS or CSS assets. Include an explicit
312
- # extension or content type in these cases
338
+ # extension or content type in these cases.
313
339
  #
314
340
  # //= link_directory "./scripts" .js
315
341
  #
@@ -325,7 +351,7 @@ module Sprockets
325
351
  # //= link_tree "./images"
326
352
  #
327
353
  # Use caution when linking against JS or CSS assets. Include an explicit
328
- # extension or content type in these cases
354
+ # extension or content type in these cases.
329
355
  #
330
356
  # //= link_tree "./styles" .css
331
357
  #
@@ -356,17 +382,17 @@ module Sprockets
356
382
 
357
383
  def link_paths(paths, deps, accept)
358
384
  resolve_paths(paths, deps, accept: accept) do |uri|
359
- @links << load(uri).uri
385
+ @to_link << to_load(uri)
360
386
  end
361
387
  end
362
388
 
363
- def resolve_paths(paths, deps, options = {})
389
+ def resolve_paths(paths, deps, **kargs)
364
390
  @dependencies.merge(deps)
365
391
  paths.each do |subpath, stat|
366
392
  next if subpath == @filename || stat.directory?
367
- uri, deps = @environment.resolve(subpath, options.merge(compat: false))
393
+ uri, deps = @environment.resolve(subpath, **kargs)
368
394
  @dependencies.merge(deps)
369
- yield uri if uri
395
+ yield uri if uri && block_given?
370
396
  end
371
397
  end
372
398
 
@@ -386,19 +412,19 @@ module Sprockets
386
412
  end
387
413
  end
388
414
 
389
- def load(uri)
390
- asset = @environment.load(uri)
391
- @dependencies.merge(asset.metadata[:dependencies])
392
- asset
415
+ def to_load(uri)
416
+ @to_load << uri
417
+ uri
393
418
  end
394
419
 
395
- def resolve(path, options = {})
420
+ def resolve(path, **kargs)
396
421
  # Prevent absolute paths in directives
397
422
  if @environment.absolute_path?(path)
398
423
  raise FileOutsidePaths, "can't require absolute file: #{path}"
399
424
  end
400
425
 
401
- uri, deps = @environment.resolve!(path, options.merge(base_path: @dirname))
426
+ kargs[:base_path] = @dirname
427
+ uri, deps = @environment.resolve!(path, **kargs)
402
428
  @dependencies.merge(deps)
403
429
  uri
404
430
  end
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/autoload'
2
3
 
3
4
  module Sprockets
4
5
  # Processor engine class for the Eco compiler. Depends on the `eco` gem.
5
6
  #
6
- # For more infomation see:
7
+ # For more information see:
7
8
  #
8
9
  # https://github.com/sstephenson/ruby-eco
9
10
  # https://github.com/sstephenson/eco
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/autoload'
2
3
 
3
4
  module Sprockets
4
5
  # Processor engine class for the EJS compiler. Depends on the `ejs` gem.
5
6
  #
6
- # For more infomation see:
7
+ # For more information see:
7
8
  #
8
9
  # https://github.com/sstephenson/ruby-ejs
9
10
  #
@@ -1,4 +1,4 @@
1
- require 'base64'
1
+ # frozen_string_literal: true
2
2
  require 'stringio'
3
3
  require 'zlib'
4
4
 
@@ -70,7 +70,7 @@ module Sprockets
70
70
  #
71
71
  # Returns a encoded String
72
72
  def base64(str)
73
- Base64.strict_encode64(str)
73
+ [str].pack("m0")
74
74
  end
75
75
 
76
76
 
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'sprockets/base'
2
3
  require 'sprockets/cache/memory_store'
3
4
  require 'sprockets/cached_environment'
4
5
 
5
6
  module Sprockets
6
7
  class Environment < Base
7
- # `Environment` should initialized with your application's root
8
+ # `Environment` should be initialized with your application's root
8
9
  # directory. This should be the same as your Rails or Rack root.
9
10
  #
10
11
  # env = Environment.new(Rails.root)
@@ -18,7 +19,7 @@ module Sprockets
18
19
 
19
20
  # Returns a cached version of the environment.
20
21
  #
21
- # All its file system calls are cached which makes `cached` much
22
+ # All of its file system calls are cached which makes `cached` much
22
23
  # faster. This behavior is ideal in production since the file
23
24
  # system only changes between deploys.
24
25
  def cached
@@ -26,8 +27,12 @@ module Sprockets
26
27
  end
27
28
  alias_method :index, :cached
28
29
 
29
- def find_asset(*args)
30
- cached.find_asset(*args)
30
+ def find_asset(*args, **options)
31
+ cached.find_asset(*args, **options)
32
+ end
33
+
34
+ def find_asset!(*args)
35
+ cached.find_asset!(*args)
31
36
  end
32
37
 
33
38
  def find_all_linked_assets(*args, &block)