sprockets 2.12.5 → 3.7.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +296 -0
  3. data/LICENSE +2 -2
  4. data/README.md +235 -262
  5. data/bin/sprockets +1 -0
  6. data/lib/rake/sprocketstask.rb +5 -4
  7. data/lib/sprockets/asset.rb +143 -212
  8. data/lib/sprockets/autoload/closure.rb +7 -0
  9. data/lib/sprockets/autoload/coffee_script.rb +7 -0
  10. data/lib/sprockets/autoload/eco.rb +7 -0
  11. data/lib/sprockets/autoload/ejs.rb +7 -0
  12. data/lib/sprockets/autoload/sass.rb +7 -0
  13. data/lib/sprockets/autoload/uglifier.rb +7 -0
  14. data/lib/sprockets/autoload/yui.rb +7 -0
  15. data/lib/sprockets/autoload.rb +11 -0
  16. data/lib/sprockets/base.rb +56 -393
  17. data/lib/sprockets/bower.rb +58 -0
  18. data/lib/sprockets/bundle.rb +69 -0
  19. data/lib/sprockets/cache/file_store.rb +168 -14
  20. data/lib/sprockets/cache/memory_store.rb +66 -0
  21. data/lib/sprockets/cache/null_store.rb +46 -0
  22. data/lib/sprockets/cache.rb +236 -0
  23. data/lib/sprockets/cached_environment.rb +69 -0
  24. data/lib/sprockets/closure_compressor.rb +35 -10
  25. data/lib/sprockets/coffee_script_processor.rb +25 -0
  26. data/lib/sprockets/coffee_script_template.rb +17 -0
  27. data/lib/sprockets/compressing.rb +44 -23
  28. data/lib/sprockets/configuration.rb +83 -0
  29. data/lib/sprockets/context.rb +86 -144
  30. data/lib/sprockets/dependencies.rb +73 -0
  31. data/lib/sprockets/deprecation.rb +90 -0
  32. data/lib/sprockets/digest_utils.rb +180 -0
  33. data/lib/sprockets/directive_processor.rb +207 -211
  34. data/lib/sprockets/eco_processor.rb +32 -0
  35. data/lib/sprockets/eco_template.rb +9 -30
  36. data/lib/sprockets/ejs_processor.rb +31 -0
  37. data/lib/sprockets/ejs_template.rb +9 -29
  38. data/lib/sprockets/encoding_utils.rb +261 -0
  39. data/lib/sprockets/engines.rb +53 -35
  40. data/lib/sprockets/environment.rb +17 -64
  41. data/lib/sprockets/erb_processor.rb +30 -0
  42. data/lib/sprockets/erb_template.rb +11 -0
  43. data/lib/sprockets/errors.rb +4 -13
  44. data/lib/sprockets/file_reader.rb +15 -0
  45. data/lib/sprockets/http_utils.rb +117 -0
  46. data/lib/sprockets/jst_processor.rb +35 -15
  47. data/lib/sprockets/legacy.rb +330 -0
  48. data/lib/sprockets/legacy_proc_processor.rb +35 -0
  49. data/lib/sprockets/legacy_tilt_processor.rb +29 -0
  50. data/lib/sprockets/loader.rb +325 -0
  51. data/lib/sprockets/manifest.rb +202 -127
  52. data/lib/sprockets/manifest_utils.rb +45 -0
  53. data/lib/sprockets/mime.rb +112 -31
  54. data/lib/sprockets/path_dependency_utils.rb +85 -0
  55. data/lib/sprockets/path_digest_utils.rb +47 -0
  56. data/lib/sprockets/path_utils.rb +287 -0
  57. data/lib/sprockets/paths.rb +42 -19
  58. data/lib/sprockets/processing.rb +178 -126
  59. data/lib/sprockets/processor_utils.rb +180 -0
  60. data/lib/sprockets/resolve.rb +211 -0
  61. data/lib/sprockets/sass_cache_store.rb +22 -17
  62. data/lib/sprockets/sass_compressor.rb +39 -15
  63. data/lib/sprockets/sass_functions.rb +2 -70
  64. data/lib/sprockets/sass_importer.rb +2 -30
  65. data/lib/sprockets/sass_processor.rb +292 -0
  66. data/lib/sprockets/sass_template.rb +12 -59
  67. data/lib/sprockets/server.rb +129 -84
  68. data/lib/sprockets/transformers.rb +145 -0
  69. data/lib/sprockets/uglifier_compressor.rb +39 -12
  70. data/lib/sprockets/unloaded_asset.rb +137 -0
  71. data/lib/sprockets/uri_tar.rb +98 -0
  72. data/lib/sprockets/uri_utils.rb +188 -0
  73. data/lib/sprockets/utils/gzip.rb +67 -0
  74. data/lib/sprockets/utils.rb +210 -44
  75. data/lib/sprockets/version.rb +1 -1
  76. data/lib/sprockets/yui_compressor.rb +39 -11
  77. data/lib/sprockets.rb +142 -81
  78. metadata +96 -90
  79. data/lib/sprockets/asset_attributes.rb +0 -137
  80. data/lib/sprockets/bundled_asset.rb +0 -78
  81. data/lib/sprockets/caching.rb +0 -96
  82. data/lib/sprockets/charset_normalizer.rb +0 -41
  83. data/lib/sprockets/index.rb +0 -100
  84. data/lib/sprockets/processed_asset.rb +0 -152
  85. data/lib/sprockets/processor.rb +0 -32
  86. data/lib/sprockets/safety_colons.rb +0 -28
  87. data/lib/sprockets/scss_template.rb +0 -13
  88. data/lib/sprockets/static_asset.rb +0 -60
@@ -0,0 +1,17 @@
1
+ require 'sprockets/coffee_script_processor'
2
+
3
+ module Sprockets
4
+ # Deprecated
5
+ module CoffeeScriptTemplate
6
+ VERSION = CoffeeScriptProcessor::VERSION
7
+
8
+ def self.cache_key
9
+ CoffeeScriptProcessor.cache_key
10
+ end
11
+
12
+ def self.call(*args)
13
+ Deprecation.new.warn "CoffeeScriptTemplate is deprecated please use CoffeeScriptProcessor instead"
14
+ CoffeeScriptProcessor.call(*args)
15
+ end
16
+ end
17
+ end
@@ -1,37 +1,41 @@
1
+ require 'sprockets/utils'
2
+
1
3
  module Sprockets
2
4
  # `Compressing` is an internal mixin whose public methods are exposed on
3
- # the `Environment` and `Index` classes.
5
+ # the `Environment` and `CachedEnvironment` classes.
4
6
  module Compressing
7
+ include Utils
8
+
5
9
  def compressors
6
- deep_copy_hash(@compressors)
10
+ config[:compressors]
7
11
  end
8
12
 
9
13
  def register_compressor(mime_type, sym, klass)
10
- @compressors[mime_type][sym] = klass
14
+ self.config = hash_reassoc(config, :compressors, mime_type) do |compressors|
15
+ compressors[sym] = klass
16
+ compressors
17
+ end
11
18
  end
12
19
 
13
20
  # Return CSS compressor or nil if none is set
14
21
  def css_compressor
15
- @css_compressor if defined? @css_compressor
22
+ if defined? @css_compressor
23
+ @css_compressor
24
+ end
16
25
  end
17
26
 
18
27
  # Assign a compressor to run on `text/css` assets.
19
28
  #
20
29
  # The compressor object must respond to `compress`.
21
30
  def css_compressor=(compressor)
22
- unregister_bundle_processor 'text/css', css_compressor if css_compressor
31
+ unregister_bundle_processor 'text/css', @css_compressor if defined? @css_compressor
23
32
  @css_compressor = nil
24
33
  return unless compressor
25
34
 
26
35
  if compressor.is_a?(Symbol)
27
- compressor = compressors['text/css'][compressor] || raise(Error, "unknown compressor: #{compressor}")
28
- end
29
-
30
- if compressor.respond_to?(:compress)
31
- klass = Class.new(Processor) do
32
- @name = "css_compressor"
33
- @processor = proc { |context, data| compressor.compress(data) }
34
- end
36
+ @css_compressor = klass = config[:compressors]['text/css'][compressor] || raise(Error, "unknown compressor: #{compressor}")
37
+ elsif compressor.respond_to?(:compress)
38
+ klass = LegacyProcProcessor.new(:css_compressor, proc { |context, data| compressor.compress(data) })
35
39
  @css_compressor = :css_compressor
36
40
  else
37
41
  @css_compressor = klass = compressor
@@ -42,26 +46,23 @@ module Sprockets
42
46
 
43
47
  # Return JS compressor or nil if none is set
44
48
  def js_compressor
45
- @js_compressor if defined? @js_compressor
49
+ if defined? @js_compressor
50
+ @js_compressor
51
+ end
46
52
  end
47
53
 
48
54
  # Assign a compressor to run on `application/javascript` assets.
49
55
  #
50
56
  # The compressor object must respond to `compress`.
51
57
  def js_compressor=(compressor)
52
- unregister_bundle_processor 'application/javascript', js_compressor if js_compressor
58
+ unregister_bundle_processor 'application/javascript', @js_compressor if defined? @js_compressor
53
59
  @js_compressor = nil
54
60
  return unless compressor
55
61
 
56
62
  if compressor.is_a?(Symbol)
57
- compressor = compressors['application/javascript'][compressor] || raise(Error, "unknown compressor: #{compressor}")
58
- end
59
-
60
- if compressor.respond_to?(:compress)
61
- klass = Class.new(Processor) do
62
- @name = "js_compressor"
63
- @processor = proc { |context, data| compressor.compress(data) }
64
- end
63
+ @js_compressor = klass = config[:compressors]['application/javascript'][compressor] || raise(Error, "unknown compressor: #{compressor}")
64
+ elsif compressor.respond_to?(:compress)
65
+ klass = LegacyProcProcessor.new(:js_compressor, proc { |context, data| compressor.compress(data) })
65
66
  @js_compressor = :js_compressor
66
67
  else
67
68
  @js_compressor = klass = compressor
@@ -69,5 +70,25 @@ module Sprockets
69
70
 
70
71
  register_bundle_processor 'application/javascript', klass
71
72
  end
73
+
74
+ # Public: Checks if Gzip is enabled.
75
+ def gzip?
76
+ config[:gzip_enabled]
77
+ end
78
+
79
+ # Public: Checks if Gzip is disabled.
80
+ def skip_gzip?
81
+ !gzip?
82
+ end
83
+
84
+ # Public: Enable or disable the creation of Gzip files.
85
+ #
86
+ # Defaults to true.
87
+ #
88
+ # environment.gzip = false
89
+ #
90
+ def gzip=(gzip)
91
+ self.config = config.merge(gzip_enabled: gzip).freeze
92
+ end
72
93
  end
73
94
  end
@@ -0,0 +1,83 @@
1
+ require 'sprockets/compressing'
2
+ require 'sprockets/dependencies'
3
+ require 'sprockets/engines'
4
+ require 'sprockets/mime'
5
+ require 'sprockets/paths'
6
+ require 'sprockets/processing'
7
+ require 'sprockets/transformers'
8
+ require 'sprockets/utils'
9
+
10
+ module Sprockets
11
+ module Configuration
12
+ include Paths, Mime, Engines, Transformers, Processing, Compressing, Dependencies, Utils
13
+
14
+ def initialize_configuration(parent)
15
+ @config = parent.config
16
+ @computed_config = parent.computed_config
17
+ @logger = parent.logger
18
+ @context_class = Class.new(parent.context_class)
19
+ end
20
+
21
+ attr_reader :config
22
+
23
+ attr_accessor :computed_config
24
+
25
+ def config=(config)
26
+ raise TypeError, "can't assign mutable config" unless config.frozen?
27
+ @config = config
28
+ end
29
+
30
+ # Get and set `Logger` instance.
31
+ attr_accessor :logger
32
+
33
+ # The `Environment#version` is a custom value used for manually
34
+ # expiring all asset caches.
35
+ #
36
+ # Sprockets is able to track most file and directory changes and
37
+ # will take care of expiring the cache for you. However, its
38
+ # impossible to know when any custom helpers change that you mix
39
+ # into the `Context`.
40
+ #
41
+ # It would be wise to increment this value anytime you make a
42
+ # configuration change to the `Environment` object.
43
+ def version
44
+ config[:version]
45
+ end
46
+
47
+ # Assign an environment version.
48
+ #
49
+ # environment.version = '2.0'
50
+ #
51
+ def version=(version)
52
+ self.config = hash_reassoc(config, :version) { version.dup }
53
+ end
54
+
55
+ # Public: Returns a `Digest` implementation class.
56
+ #
57
+ # Defaults to `Digest::SHA256`.
58
+ def digest_class
59
+ config[:digest_class]
60
+ end
61
+
62
+ # Deprecated: Assign a `Digest` implementation class. This maybe any Ruby
63
+ # `Digest::` implementation such as `Digest::SHA256` or
64
+ # `Digest::MD5`.
65
+ #
66
+ # environment.digest_class = Digest::MD5
67
+ #
68
+ def digest_class=(klass)
69
+ self.config = config.merge(digest_class: klass).freeze
70
+ end
71
+
72
+ # Deprecated: Get `Context` class.
73
+ #
74
+ # This class maybe mutated and mixed in with custom helpers.
75
+ #
76
+ # environment.context_class.instance_eval do
77
+ # include MyHelpers
78
+ # def asset_url; end
79
+ # end
80
+ #
81
+ attr_reader :context_class
82
+ end
83
+ end
@@ -1,15 +1,13 @@
1
- require 'base64'
2
- require 'rack/utils'
3
- require 'sprockets/errors'
4
- require 'sprockets/utils'
5
1
  require 'pathname'
2
+ require 'rack/utils'
6
3
  require 'set'
4
+ require 'sprockets/errors'
7
5
 
8
6
  module Sprockets
9
- # `Context` provides helper methods to all `Tilt` processors. They
10
- # are typically accessed by ERB templates. You can mix in custom
11
- # helpers by injecting them into `Environment#context_class`. Do not
12
- # mix them into `Context` directly.
7
+ # Deprecated: `Context` provides helper methods to all processors.
8
+ # They are typically accessed by ERB templates. You can mix in custom helpers
9
+ # by injecting them into `Environment#context_class`. Do not mix them into
10
+ # `Context` directly.
13
11
  #
14
12
  # environment.context_class.class_eval do
15
13
  # include MyHelper
@@ -21,92 +19,86 @@ module Sprockets
21
19
  # The `Context` also collects dependencies declared by
22
20
  # assets. See `DirectiveProcessor` for an example of this.
23
21
  class Context
24
- attr_reader :environment, :pathname
25
- attr_reader :_required_paths, :_stubbed_assets
26
- attr_reader :_dependency_paths, :_dependency_assets
27
- attr_writer :__LINE__
22
+ attr_reader :environment, :filename, :pathname
23
+
24
+ # Deprecated
25
+ attr_accessor :__LINE__
28
26
 
29
- def initialize(environment, logical_path, pathname)
30
- @environment = environment
31
- @logical_path = logical_path
32
- @pathname = pathname
33
- @__LINE__ = nil
27
+ def initialize(input)
28
+ @environment = input[:environment]
29
+ @metadata = input[:metadata]
30
+ @load_path = input[:load_path]
31
+ @logical_path = input[:name]
32
+ @filename = input[:filename]
33
+ @dirname = File.dirname(@filename)
34
+ @pathname = Pathname.new(@filename)
35
+ @content_type = input[:content_type]
34
36
 
35
- @_required_paths = []
36
- @_stubbed_assets = Set.new
37
- @_dependency_paths = Set.new
38
- @_dependency_assets = Set.new([pathname.to_s])
37
+ @required = Set.new(@metadata[:required])
38
+ @stubbed = Set.new(@metadata[:stubbed])
39
+ @links = Set.new(@metadata[:links])
40
+ @dependencies = Set.new(input[:metadata][:dependencies])
41
+ end
42
+
43
+ def metadata
44
+ { required: @required,
45
+ stubbed: @stubbed,
46
+ links: @links,
47
+ dependencies: @dependencies }
39
48
  end
40
49
 
41
50
  # Returns the environment path that contains the file.
42
51
  #
43
52
  # If `app/javascripts` and `app/stylesheets` are in your path, and
44
- # current file is `app/javascripts/foo/bar.js`, `root_path` would
53
+ # current file is `app/javascripts/foo/bar.js`, `load_path` would
45
54
  # return `app/javascripts`.
46
- def root_path
47
- environment.paths.detect { |path| pathname.to_s[path] }
48
- end
55
+ attr_reader :load_path
56
+ alias_method :root_path, :load_path
49
57
 
50
58
  # Returns logical path without any file extensions.
51
59
  #
52
60
  # 'app/javascripts/application.js'
53
61
  # # => 'application'
54
62
  #
55
- def logical_path
56
- @logical_path.chomp(File.extname(@logical_path))
57
- end
63
+ attr_reader :logical_path
58
64
 
59
65
  # Returns content type of file
60
66
  #
61
67
  # 'application/javascript'
62
68
  # 'text/css'
63
69
  #
64
- def content_type
65
- environment.content_type_of(pathname)
66
- end
70
+ attr_reader :content_type
67
71
 
68
- # Given a logical path, `resolve` will find and return the fully
69
- # expanded path. Relative paths will also be resolved. An optional
70
- # `:content_type` restriction can be supplied to restrict the
71
- # search.
72
+ # Public: Given a logical path, `resolve` will find and return an Asset URI.
73
+ # Relative paths will also be resolved. An accept type maybe given to
74
+ # restrict the search.
72
75
  #
73
76
  # resolve("foo.js")
74
- # # => "/path/to/app/javascripts/foo.js"
77
+ # # => "file:///path/to/app/javascripts/foo.js?type=application/javascript"
75
78
  #
76
79
  # resolve("./bar.js")
77
- # # => "/path/to/app/javascripts/bar.js"
80
+ # # => "file:///path/to/app/javascripts/bar.js?type=application/javascript"
78
81
  #
79
- def resolve(path, options = {}, &block)
80
- pathname = Pathname.new(path)
81
- attributes = environment.attributes_for(pathname)
82
-
83
- if pathname.absolute?
84
- if environment.stat(pathname)
85
- pathname
86
- else
87
- raise FileNotFound, "couldn't find file '#{pathname}'"
88
- end
89
-
90
- elsif content_type = options[:content_type]
91
- content_type = self.content_type if content_type == :self
92
-
93
- if attributes.format_extension
94
- if content_type != attributes.content_type
95
- raise ContentTypeMismatch, "#{path} is " +
96
- "'#{attributes.content_type}', not '#{content_type}'"
97
- end
98
- end
99
-
100
- resolve(path) do |candidate|
101
- if self.content_type == environment.content_type_of(candidate)
102
- return candidate
103
- end
104
- end
82
+ # path - String logical or absolute path
83
+ # options
84
+ # accept - String content accept type
85
+ #
86
+ # Returns an Asset URI String.
87
+ def resolve(path, options = {})
88
+ uri, deps = environment.resolve!(path, options.merge(base_path: @dirname))
89
+ @dependencies.merge(deps)
90
+ uri
91
+ end
105
92
 
106
- raise FileNotFound, "couldn't find file '#{path}'"
107
- else
108
- environment.resolve(path, {:base_path => self.pathname.dirname}.merge(options), &block)
109
- end
93
+ # Public: Load Asset by AssetURI and track it as a dependency.
94
+ #
95
+ # uri - AssetURI
96
+ #
97
+ # Returns Asset.
98
+ def load(uri)
99
+ asset = environment.load(uri)
100
+ @dependencies.merge(asset.metadata[:dependencies])
101
+ asset
110
102
  end
111
103
 
112
104
  # `depend_on` allows you to state a dependency on a file without
@@ -116,7 +108,13 @@ module Sprockets
116
108
  # the dependency file with invalidate the cache of the
117
109
  # source file.
118
110
  def depend_on(path)
119
- @_dependency_paths << resolve(path).to_s
111
+ path = path.to_s if path.is_a?(Pathname)
112
+
113
+ if environment.absolute_path?(path) && environment.stat(path)
114
+ @dependencies << environment.build_file_digest_uri(path)
115
+ else
116
+ resolve(path, compat: false)
117
+ end
120
118
  nil
121
119
  end
122
120
 
@@ -128,9 +126,7 @@ module Sprockets
128
126
  # file. Unlike `depend_on`, this will include recursively include
129
127
  # the target asset's dependencies.
130
128
  def depend_on_asset(path)
131
- filename = resolve(path).to_s
132
- @_dependency_assets << filename
133
- nil
129
+ load(resolve(path, compat: false))
134
130
  end
135
131
 
136
132
  # `require_asset` declares `path` as a dependency of the file. The
@@ -143,9 +139,7 @@ module Sprockets
143
139
  # <%= require_asset "#{framework}.js" %>
144
140
  #
145
141
  def require_asset(path)
146
- pathname = resolve(path, :content_type => :self)
147
- depend_on_asset(pathname)
148
- @_required_paths << pathname.to_s
142
+ @required << resolve(path, accept: @content_type, pipeline: :self, compat: false)
149
143
  nil
150
144
  end
151
145
 
@@ -153,55 +147,19 @@ module Sprockets
153
147
  # `path` must be an asset which may or may not already be included
154
148
  # in the bundle.
155
149
  def stub_asset(path)
156
- @_stubbed_assets << resolve(path, :content_type => :self).to_s
150
+ @stubbed << resolve(path, accept: @content_type, pipeline: :self, compat: false)
157
151
  nil
158
152
  end
159
153
 
160
- # Tests if target path is able to be safely required into the
161
- # current concatenation.
162
- def asset_requirable?(path)
163
- pathname = resolve(path)
164
- content_type = environment.content_type_of(pathname)
165
- stat = environment.stat(path)
166
- return false unless stat && stat.file?
167
- self.content_type.nil? || self.content_type == content_type
168
- end
169
-
170
- # Reads `path` and runs processors on the file.
171
- #
172
- # This allows you to capture the result of an asset and include it
173
- # directly in another.
174
- #
175
- # <%= evaluate "bar.js" %>
154
+ # `link_asset` declares an external dependency on an asset without directly
155
+ # including it. The target asset is returned from this function making it
156
+ # easy to construct a link to it.
176
157
  #
177
- def evaluate(path, options = {})
178
- pathname = resolve(path)
179
- attributes = environment.attributes_for(pathname)
180
- processors = options[:processors] || attributes.processors
181
-
182
- if options[:data]
183
- result = options[:data]
184
- else
185
- if environment.respond_to?(:default_external_encoding)
186
- mime_type = environment.mime_types(pathname.extname)
187
- encoding = environment.encoding_for_mime_type(mime_type)
188
- result = Sprockets::Utils.read_unicode(pathname, encoding)
189
- else
190
- result = Sprockets::Utils.read_unicode(pathname)
191
- end
192
- end
193
-
194
- processors.each do |processor|
195
- begin
196
- template = processor.new(pathname.to_s) { result }
197
- result = template.render(self, {})
198
- rescue Exception => e
199
- annotate_exception! e
200
- raise
201
- end
202
- end
203
-
204
- result
158
+ # Returns an Asset or nil.
159
+ def link_asset(path)
160
+ asset = depend_on_asset(path)
161
+ @links << asset.uri
162
+ asset
205
163
  end
206
164
 
207
165
  # Returns a Base64-encoded `data:` URI with the contents of the
@@ -215,10 +173,9 @@ module Sprockets
215
173
  # $('<img>').attr('src', '<%= asset_data_uri 'avatar.jpg' %>')
216
174
  #
217
175
  def asset_data_uri(path)
218
- depend_on_asset(path)
219
- asset = environment.find_asset(path)
220
- base64 = Base64.encode64(asset.to_s).gsub(/\s+/, "")
221
- "data:#{asset.content_type};base64,#{Rack::Utils.escape(base64)}"
176
+ asset = depend_on_asset(path)
177
+ data = EncodingUtils.base64(asset.source)
178
+ "data:#{asset.content_type};base64,#{Rack::Utils.escape(data)}"
222
179
  end
223
180
 
224
181
  # Expands logical path to full url to asset.
@@ -243,47 +200,32 @@ Extend your environment context with a custom method.
243
200
 
244
201
  # Expand logical image asset path.
245
202
  def image_path(path)
246
- asset_path(path, :type => :image)
203
+ asset_path(path, type: :image)
247
204
  end
248
205
 
249
206
  # Expand logical video asset path.
250
207
  def video_path(path)
251
- asset_path(path, :type => :video)
208
+ asset_path(path, type: :video)
252
209
  end
253
210
 
254
211
  # Expand logical audio asset path.
255
212
  def audio_path(path)
256
- asset_path(path, :type => :audio)
213
+ asset_path(path, type: :audio)
257
214
  end
258
215
 
259
216
  # Expand logical font asset path.
260
217
  def font_path(path)
261
- asset_path(path, :type => :font)
218
+ asset_path(path, type: :font)
262
219
  end
263
220
 
264
221
  # Expand logical javascript asset path.
265
222
  def javascript_path(path)
266
- asset_path(path, :type => :javascript)
223
+ asset_path(path, type: :javascript)
267
224
  end
268
225
 
269
226
  # Expand logical stylesheet asset path.
270
227
  def stylesheet_path(path)
271
- asset_path(path, :type => :stylesheet)
228
+ asset_path(path, type: :stylesheet)
272
229
  end
273
-
274
- private
275
- # Annotates exception backtrace with the original template that
276
- # the exception was raised in.
277
- def annotate_exception!(exception)
278
- location = pathname.to_s
279
- location << ":#{@__LINE__}" if @__LINE__
280
-
281
- exception.extend(Sprockets::EngineError)
282
- exception.sprockets_annotation = " (in #{location})"
283
- end
284
-
285
- def logger
286
- environment.logger
287
- end
288
230
  end
289
231
  end
@@ -0,0 +1,73 @@
1
+ require 'sprockets/digest_utils'
2
+ require 'sprockets/path_digest_utils'
3
+ require 'sprockets/uri_utils'
4
+
5
+ module Sprockets
6
+ # `Dependencies` is an internal mixin whose public methods are exposed on the
7
+ # `Environment` and `CachedEnvironment` classes.
8
+ module Dependencies
9
+ include DigestUtils, PathDigestUtils, URIUtils
10
+
11
+ # Public: Mapping dependency schemes to resolver functions.
12
+ #
13
+ # key - String scheme
14
+ # value - Proc.call(Environment, String)
15
+ #
16
+ # Returns Hash.
17
+ def dependency_resolvers
18
+ config[:dependency_resolvers]
19
+ end
20
+
21
+ # Public: Default set of dependency URIs for assets.
22
+ #
23
+ # Returns Set of String URIs.
24
+ def dependencies
25
+ config[:dependencies]
26
+ end
27
+
28
+ # Public: Register new dependency URI resolver.
29
+ #
30
+ # scheme - String scheme
31
+ # block -
32
+ # environment - Environment
33
+ # uri - String dependency URI
34
+ #
35
+ # Returns nothing.
36
+ def register_dependency_resolver(scheme, &block)
37
+ self.config = hash_reassoc(config, :dependency_resolvers) do |hash|
38
+ hash.merge(scheme => block)
39
+ end
40
+ end
41
+
42
+ # Public: Add environmental dependency inheirted by all assets.
43
+ #
44
+ # uri - String dependency URI
45
+ #
46
+ # Returns nothing.
47
+ def add_dependency(uri)
48
+ self.config = hash_reassoc(config, :dependencies) do |set|
49
+ set + Set.new([uri])
50
+ end
51
+ end
52
+ alias_method :depend_on, :add_dependency
53
+
54
+ # Internal: Resolve dependency URIs.
55
+ #
56
+ # Returns resolved Object.
57
+ def resolve_dependency(str)
58
+ # Optimize for the most common scheme to
59
+ # save 22k allocations on an average Spree app.
60
+ scheme = if str.start_with?('file-digest:'.freeze)
61
+ 'file-digest'.freeze
62
+ else
63
+ str[/([^:]+)/, 1]
64
+ end
65
+
66
+ if resolver = config[:dependency_resolvers][scheme]
67
+ resolver.call(self, str)
68
+ else
69
+ nil
70
+ end
71
+ end
72
+ end
73
+ end