sprockets 3.0.0.beta.6 → 3.0.0.beta.7

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,97 @@
1
+ require 'sprockets/autoload_processor'
2
+
3
+ module Sprockets
4
+ # Functional utilities for dealing with Processor functions.
5
+ #
6
+ # A Processor is a general function that my modify or transform an asset as
7
+ # part of the pipeline. CoffeeScript to JavaScript conversion, Minification
8
+ # or Concatenation are all implemented as seperate Processor steps.
9
+ #
10
+ # Processors maybe any object that responds to call. So procs or a class that
11
+ # defines a self.call method.
12
+ #
13
+ # For ergonomics, processors may return a number of shorthand values.
14
+ # Unfortunately, this means that processors can not compose via ordinary
15
+ # function composition. The composition helpers here can help.
16
+ module ProcessorUtils
17
+ extend self
18
+
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
+ # Public: Compose processors in right to left order.
33
+ #
34
+ # processors - Array of processors callables
35
+ #
36
+ # Returns a composed Proc.
37
+ def compose_processors(*processors)
38
+ context = self
39
+ obj = method(:call_processors).to_proc.curry[processors]
40
+ metaclass = (class << obj; self; end)
41
+ metaclass.send(:define_method, :cache_key) do
42
+ context.processors_cache_keys(processors)
43
+ end
44
+ obj
45
+ end
46
+
47
+ # Public: Invoke list of processors in right to left order.
48
+ #
49
+ # The right to left order processing mirrors standard function composition.
50
+ # Think about:
51
+ #
52
+ # bundle.call(uglify.call(coffee.call(input)))
53
+ #
54
+ # processors - Array of processor callables
55
+ # input - Hash of input data to pass to each processor
56
+ #
57
+ # Returns a Hash with :data and other processor metadata key/values.
58
+ def call_processors(processors, input)
59
+ data = input[:data] || ""
60
+ metadata = input[:metadata] || {}
61
+
62
+ 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
74
+ end
75
+
76
+ metadata.merge(data: data)
77
+ end
78
+
79
+ # Internal: Get processor defined cached key.
80
+ #
81
+ # processor - Processor function
82
+ #
83
+ # Returns JSON serializable key or nil.
84
+ def processor_cache_key(processor)
85
+ processor.cache_key if processor.respond_to?(:cache_key)
86
+ end
87
+
88
+ # Internal: Get combined cache keys for set of processors.
89
+ #
90
+ # processors - Array of processor functions
91
+ #
92
+ # Returns Array of JSON serializable keys.
93
+ def processors_cache_keys(processors)
94
+ processors.map { |processor| processor_cache_key(processor) }
95
+ end
96
+ end
97
+ end
@@ -1,110 +1,121 @@
1
- require 'sprockets/asset_uri'
1
+ require 'set'
2
+ require 'sprockets/http_utils'
3
+ require 'sprockets/path_dependency_utils'
4
+ require 'sprockets/uri_utils'
2
5
 
3
6
  module Sprockets
4
7
  module Resolve
5
- # Public: Finds the absolute path for a given logical path by searching the
8
+ include HTTPUtils, PathDependencyUtils, URIUtils
9
+
10
+ # Public: Find Asset URI for given a logical path by searching the
6
11
  # environment's load paths.
7
12
  #
8
13
  # resolve("application.js")
9
- # # => "/path/to/app/javascripts/application.js"
14
+ # # => "file:///path/to/app/javascripts/application.js?type=application/javascript"
10
15
  #
11
16
  # An accept content type can be given if the logical path doesn't have a
12
17
  # format extension.
13
18
  #
14
19
  # resolve("application", accept: "application/javascript")
15
- # # => "/path/to/app/javascripts/application.js"
20
+ # # => "file:///path/to/app/javascripts/application.coffee?type=application/javascript"
16
21
  #
17
- # The String path is returned or nil if no results are found.
22
+ # The String Asset URI is returned or nil if no results are found.
18
23
  def resolve(path, options = {})
19
- logical_name, mime_type, _ = parse_path_extnames(path)
20
-
24
+ path = path.to_s
21
25
  paths = options[:load_paths] || self.paths
26
+ accept = options[:accept]
27
+ skip_bundle = options.key?(:bundle) ? !options[:bundle] : false
22
28
 
23
- if absolute_path?(path)
24
- path = File.expand_path(path)
25
- if paths_split(paths, path) && file?(path)
26
- if accept = options[:accept]
27
- find_best_q_match(accept, [path]) do |candidate, matcher|
28
- match_mime_type?(mime_type || "application/octet-stream", matcher)
29
- end
30
- else
31
- path
32
- end
33
- end
29
+ if valid_asset_uri?(path)
30
+ resolve_asset_uri(path)
31
+ elsif absolute_path?(path)
32
+ resolve_absolute_path(paths, path, accept, skip_bundle)
33
+ elsif relative_path?(path)
34
+ resolve_relative_path(paths, path, options[:base_path], accept, skip_bundle)
34
35
  else
35
- accepts = parse_accept_options(mime_type, options[:accept])
36
- filename, _ = resolve_under_paths(paths, logical_name, mime_type, accepts)
37
- filename
36
+ resolve_logical_path(paths, path, accept, skip_bundle)
38
37
  end
39
38
  end
40
39
 
41
- # Public: Find Asset URI for given a logical path by searching the
42
- # environment's load paths.
43
- #
44
- # locate("application.js")
45
- # # => "file:///path/to/app/javascripts/application.js?content_type=application/javascript"
46
- #
47
- # An accept content type can be given if the logical path doesn't have a
48
- # format extension.
49
- #
50
- # locate("application", accept: "application/javascript")
51
- # # => "file:///path/to/app/javascripts/application.coffee?content_type=application/javascript"
52
- #
53
- # The String Asset URI is returned or nil if no results are found.
54
- def locate(path, options = {})
55
- path = path.to_s
56
- accept = options[:accept]
57
- skip_bundle = options.key?(:bundle) ? !options[:bundle] : false
40
+ # Public: Same as resolve() but raises a FileNotFound exception instead of
41
+ # nil if no assets are found.
42
+ def resolve!(path, options = {})
43
+ uri, deps = resolve(path, options.merge(compat: false))
58
44
 
59
- available_encodings = self.encodings.keys + ['identity']
60
- encoding = find_best_q_match(options[:accept_encoding], available_encodings)
45
+ unless uri
46
+ message = "couldn't find file '#{path}'"
47
+ message << " with type '#{options[:accept]}'" if options[:accept]
48
+ raise FileNotFound, message
49
+ end
61
50
 
62
- paths = options[:load_paths] || self.paths
51
+ return uri, deps
52
+ end
63
53
 
64
- if AssetURI.valid?(path)
65
- return path
66
- elsif absolute_path?(path)
67
- path = File.expand_path(path)
68
- if paths_split(paths, path) && file?(path)
69
- mime_type = parse_path_extnames(path)[1]
70
- _type = resolve_transform_type(mime_type, accept)
71
- if !accept || _type
72
- filename = path
73
- type = _type
74
- end
75
- end
76
- else
77
- logical_name, mime_type, _ = parse_path_extnames(path)
78
- parsed_accept = parse_accept_options(mime_type, accept)
54
+ protected
55
+ def resolve_asset_uri(uri)
56
+ filename, _ = parse_asset_uri(uri)
57
+ return uri, Set.new([build_file_digest_uri(filename)])
58
+ end
59
+
60
+ def resolve_absolute_path(paths, filename, accept, skip_bundle)
61
+ deps = Set.new
62
+ filename = File.expand_path(filename)
63
+
64
+ # Ensure path is under load paths
65
+ return nil, deps unless paths_split(paths, filename)
79
66
 
80
- if parsed_accept.empty?
81
- return
67
+ mime_type = parse_path_extnames(filename)[1]
68
+ type = resolve_transform_type(mime_type, accept)
69
+ return nil, deps if accept && !type
70
+
71
+ return nil, deps unless file?(filename)
72
+
73
+ uri = build_asset_uri(filename, type: type, skip_bundle: skip_bundle)
74
+ deps << build_file_digest_uri(filename)
75
+ return uri, deps
76
+ end
77
+
78
+ def resolve_relative_path(paths, path, dirname, accept, skip_bundle)
79
+ filename = File.expand_path(path, dirname)
80
+ load_path, _ = paths_split(paths, dirname)
81
+ if load_path && logical_path = split_subpath(load_path, filename)
82
+ resolve_logical_path([load_path], logical_path, accept, skip_bundle)
83
+ else
84
+ [nil, Set.new]
82
85
  end
86
+ end
83
87
 
88
+ def resolve_logical_path(paths, logical_path, accept, skip_bundle)
89
+ logical_name, mime_type, _ = parse_path_extnames(logical_path)
90
+ parsed_accept = parse_accept_options(mime_type, accept)
84
91
  transformed_accepts = expand_transform_accepts(parsed_accept)
85
- filename, mime_type = resolve_under_paths(paths, logical_name, mime_type, transformed_accepts)
86
- type = resolve_transform_type(mime_type, parsed_accept) if filename
92
+ filename, mime_type, deps = resolve_under_paths(paths, logical_name, transformed_accepts)
93
+
94
+ if filename
95
+ deps << build_file_digest_uri(filename)
96
+ type = resolve_transform_type(mime_type, parsed_accept)
97
+ uri = build_asset_uri(filename, type: type, skip_bundle: skip_bundle)
98
+ return uri, deps
99
+ else
100
+ return nil, deps
101
+ end
87
102
  end
88
103
 
89
- if filename
90
- encoding = nil if encoding == 'identity'
91
- AssetURI.build(filename, type: type, skip_bundle: skip_bundle, encoding: encoding)
92
- end
93
- end
104
+ def resolve_under_paths(paths, logical_name, accepts)
105
+ all_deps = Set.new
106
+ return nil, nil, all_deps if accepts.empty?
94
107
 
95
- protected
96
- def resolve_under_paths(paths, logical_name, mime_type, accepts)
97
108
  logical_basename = File.basename(logical_name)
98
-
99
109
  paths.each do |load_path|
100
- candidates = path_matches(load_path, logical_name, logical_basename)
110
+ candidates, deps = path_matches(load_path, logical_name, logical_basename)
111
+ all_deps.merge(deps)
101
112
  candidate = find_best_q_match(accepts, candidates) do |c, matcher|
102
113
  match_mime_type?(c[1] || "application/octet-stream", matcher)
103
114
  end
104
- return candidate if candidate
115
+ return candidate + [all_deps] if candidate
105
116
  end
106
117
 
107
- nil
118
+ return nil, nil, all_deps
108
119
  end
109
120
 
110
121
  def parse_accept_options(mime_type, types)
@@ -133,24 +144,40 @@ module Sprockets
133
144
  end
134
145
 
135
146
  def path_matches(load_path, logical_name, logical_basename)
136
- candidates = []
147
+ candidates, deps = [], Set.new
137
148
  dirname = File.dirname(File.join(load_path, logical_name))
138
- dirname_matches(dirname, logical_basename) { |candidate| candidates << candidate }
139
- resolve_alternates(load_path, logical_name) { |fn| candidates << [fn, parse_path_extnames(fn)[1]] }
140
- dirname_matches(File.join(load_path, logical_name), "index") { |candidate| candidates << candidate }
141
- candidates.select { |fn, _| file?(fn) }
149
+
150
+ result = dirname_matches(dirname, logical_basename)
151
+ candidates.concat(result[0])
152
+ deps.merge(result[1])
153
+
154
+ result = resolve_alternates(load_path, logical_name)
155
+ result[0].each do |fn|
156
+ candidates << [fn, parse_path_extnames(fn)[1]]
157
+ end
158
+ deps.merge(result[1])
159
+
160
+ result = dirname_matches(File.join(load_path, logical_name), "index")
161
+ candidates.concat(result[0])
162
+ deps.merge(result[1])
163
+
164
+ return candidates.select { |fn, _| file?(fn) }, deps
142
165
  end
143
166
 
144
167
  def dirname_matches(dirname, basename)
145
- self.entries(dirname).each do |entry|
168
+ candidates = []
169
+ entries, deps = self.entries_with_dependencies(dirname)
170
+ entries.each do |entry|
146
171
  name, type, _ = parse_path_extnames(entry)
147
172
  if basename == name
148
- yield [File.join(dirname, entry), type]
173
+ candidates << [File.join(dirname, entry), type]
149
174
  end
150
175
  end
176
+ return candidates, deps
151
177
  end
152
178
 
153
179
  def resolve_alternates(load_path, logical_name)
180
+ return [], Set.new
154
181
  end
155
182
 
156
183
  # Internal: Returns the name, mime type and `Array` of engine extensions.
@@ -159,26 +186,12 @@ module Sprockets
159
186
  # # => ["foo", "application/javascript", [".coffee", ".erb"]]
160
187
  #
161
188
  def parse_path_extnames(path)
162
- mime_type = nil
163
- engine_extnames = []
164
- len = path.length
165
-
166
- path_extnames(path).reverse_each do |extname|
167
- if engines.key?(extname)
168
- mime_type = engine_mime_types[extname]
169
- engine_extnames.unshift(extname)
170
- len -= extname.length
171
- elsif mime_exts.key?(extname)
172
- mime_type = mime_exts[extname]
173
- len -= extname.length
174
- break
175
- else
176
- break
177
- end
189
+ extname, value = match_path_extname(path, config[:_extnames])
190
+ if extname
191
+ return path.chomp(extname), value[:type], value[:engines]
192
+ else
193
+ return path, nil, []
178
194
  end
179
-
180
- name = path[0, len]
181
- return [name, mime_type, engine_extnames]
182
195
  end
183
196
  end
184
197
  end
@@ -1,2 +1,2 @@
1
- # Deprecated: Require sprockets/sass_template instead
2
- require 'sprockets/sass_template'
1
+ # Deprecated: Require sprockets/sass_processor instead
2
+ require 'sprockets/sass_processor'
@@ -16,18 +16,31 @@ module Sprockets
16
16
  class SassCompressor
17
17
  VERSION = '1'
18
18
 
19
- def self.call(*args)
20
- new.call(*args)
19
+ # Public: Return singleton instance with default options.
20
+ #
21
+ # Returns SassCompressor object.
22
+ def self.instance
23
+ @instance ||= new
21
24
  end
22
25
 
26
+ def self.call(input)
27
+ instance.call(input)
28
+ end
29
+
30
+ def cache_key
31
+ instance.cache_key
32
+ end
33
+
34
+ attr_reader :cache_key
35
+
23
36
  def initialize(options = {})
24
37
  @options = options
25
38
  @cache_key = [
26
- 'SassCompressor',
39
+ self.class.name,
27
40
  ::Sass::VERSION,
28
41
  VERSION,
29
42
  options
30
- ]
43
+ ].freeze
31
44
  end
32
45
 
33
46
  def call(input)
@@ -1,2 +1,2 @@
1
- # Deprecated: Require sprockets/sass_template instead
2
- require 'sprockets/sass_template'
1
+ # Deprecated: Require sprockets/sass_processor instead
2
+ require 'sprockets/sass_processor'
@@ -1,2 +1,2 @@
1
- # Deprecated: Require sprockets/sass_template instead
2
- require 'sprockets/sass_template'
1
+ # Deprecated: Require sprockets/sass_processor instead
2
+ require 'sprockets/sass_processor'
@@ -0,0 +1,305 @@
1
+ require 'rack/utils'
2
+ require 'sass'
3
+ require 'uri'
4
+
5
+ module Sprockets
6
+ # Processor engine class for the SASS/SCSS compiler. Depends on the `sass` gem.
7
+ #
8
+ # For more infomation see:
9
+ #
10
+ # https://github.com/sass/sass
11
+ # https://github.com/rails/sass-rails
12
+ #
13
+ class SassProcessor
14
+ # Internal: Defines default sass syntax to use. Exposed so the ScssProcessor
15
+ # may override it.
16
+ def self.syntax
17
+ :sass
18
+ end
19
+
20
+ # Public: Return singleton instance with default options.
21
+ #
22
+ # Returns SassProcessor object.
23
+ def self.instance
24
+ @instance ||= new
25
+ end
26
+
27
+ def self.call(input)
28
+ instance.call(input)
29
+ end
30
+
31
+ def self.cache_key
32
+ instance.cache_key
33
+ end
34
+
35
+ attr_reader :cache_key
36
+
37
+ # Public: Initialize template with custom options.
38
+ #
39
+ # options - Hash
40
+ # cache_version - String custom cache version. Used to force a cache
41
+ # change after code changes are made to Sass Functions.
42
+ #
43
+ def initialize(options = {}, &block)
44
+ @cache_version = options[:cache_version]
45
+ @cache_key = [
46
+ self.class.name,
47
+ VERSION,
48
+ Sass::VERSION,
49
+ @cache_version
50
+ ].freeze
51
+
52
+ @functions = Module.new do
53
+ include Functions
54
+ include options[:functions] if options[:functions]
55
+ class_eval(&block) if block_given?
56
+ end
57
+ end
58
+
59
+ def call(input)
60
+ context = input[:environment].context_class.new(input)
61
+
62
+ options = {
63
+ filename: input[:filename],
64
+ syntax: self.class.syntax,
65
+ cache_store: CacheStore.new(input[:cache], @cache_version),
66
+ load_paths: input[:environment].paths,
67
+ sprockets: {
68
+ context: context,
69
+ environment: input[:environment],
70
+ dependencies: context.metadata[:dependencies]
71
+ }
72
+ }
73
+
74
+ engine = ::Sass::Engine.new(input[:data], options)
75
+
76
+ css = Utils.module_include(::Sass::Script::Functions, @functions) do
77
+ engine.render
78
+ end
79
+
80
+ # Track all imported files
81
+ engine.dependencies.map do |dependency|
82
+ context.metadata[:dependencies] << URIUtils.build_file_digest_uri(dependency.options[:filename])
83
+ end
84
+
85
+ context.metadata.merge(data: css)
86
+ end
87
+
88
+ # Public: Functions injected into Sass context during Sprockets evaluation.
89
+ #
90
+ # This module may be extended to add global functionality to all Sprockets
91
+ # Sass environments. Though, scoping your functions to just your environment
92
+ # is preferred.
93
+ #
94
+ # module Sprockets::SassProcessor::Functions
95
+ # def asset_path(path, options = {})
96
+ # end
97
+ # end
98
+ #
99
+ module Functions
100
+ # Public: Generate a url for asset path.
101
+ #
102
+ # Default implementation is deprecated. Currently defaults to
103
+ # Context#asset_path.
104
+ #
105
+ # Will raise NotImplementedError in the future. Users should provide their
106
+ # own base implementation.
107
+ #
108
+ # Returns a Sass::Script::String.
109
+ def asset_path(path, options = {})
110
+ path = path.value
111
+
112
+ path, _, query, fragment = URI.split(path)[5..8]
113
+ path = sprockets_context.asset_path(path, options)
114
+ query = "?#{query}" if query
115
+ fragment = "##{fragment}" if fragment
116
+
117
+ ::Sass::Script::String.new("#{path}#{query}#{fragment}", :string)
118
+ end
119
+
120
+ # Public: Generate a asset url() link.
121
+ #
122
+ # path - Sass::Script::String URL path
123
+ #
124
+ # Returns a Sass::Script::String.
125
+ def asset_url(path, options = {})
126
+ ::Sass::Script::String.new("url(#{asset_path(path, options).value})")
127
+ end
128
+
129
+ # Public: Generate url for image path.
130
+ #
131
+ # path - Sass::Script::String URL path
132
+ #
133
+ # Returns a Sass::Script::String.
134
+ def image_path(path)
135
+ asset_path(path, type: :image)
136
+ end
137
+
138
+ # Public: Generate a image url() link.
139
+ #
140
+ # path - Sass::Script::String URL path
141
+ #
142
+ # Returns a Sass::Script::String.
143
+ def image_url(path)
144
+ asset_url(path, type: :image)
145
+ end
146
+
147
+ # Public: Generate url for video path.
148
+ #
149
+ # path - Sass::Script::String URL path
150
+ #
151
+ # Returns a Sass::Script::String.
152
+ def video_path(path)
153
+ asset_path(path, type: :video)
154
+ end
155
+
156
+ # Public: Generate a video url() link.
157
+ #
158
+ # path - Sass::Script::String URL path
159
+ #
160
+ # Returns a Sass::Script::String.
161
+ def video_url(path)
162
+ asset_url(path, type: :video)
163
+ end
164
+
165
+ # Public: Generate url for audio path.
166
+ #
167
+ # path - Sass::Script::String URL path
168
+ #
169
+ # Returns a Sass::Script::String.
170
+ def audio_path(path)
171
+ asset_path(path, type: :audio)
172
+ end
173
+
174
+ # Public: Generate a audio url() link.
175
+ #
176
+ # path - Sass::Script::String URL path
177
+ #
178
+ # Returns a Sass::Script::String.
179
+ def audio_url(path)
180
+ asset_url(path, type: :audio)
181
+ end
182
+
183
+ # Public: Generate url for font path.
184
+ #
185
+ # path - Sass::Script::String URL path
186
+ #
187
+ # Returns a Sass::Script::String.
188
+ def font_path(path)
189
+ asset_path(path, type: :font)
190
+ end
191
+
192
+ # Public: Generate a font url() link.
193
+ #
194
+ # path - Sass::Script::String URL path
195
+ #
196
+ # Returns a Sass::Script::String.
197
+ def font_url(path)
198
+ asset_url(path, type: :font)
199
+ end
200
+
201
+ # Public: Generate url for javascript path.
202
+ #
203
+ # path - Sass::Script::String URL path
204
+ #
205
+ # Returns a Sass::Script::String.
206
+ def javascript_path(path)
207
+ asset_path(path, type: :javascript)
208
+ end
209
+
210
+ # Public: Generate a javascript url() link.
211
+ #
212
+ # path - Sass::Script::String URL path
213
+ #
214
+ # Returns a Sass::Script::String.
215
+ def javascript_url(path)
216
+ asset_url(path, type: :javascript)
217
+ end
218
+
219
+ # Public: Generate url for stylesheet path.
220
+ #
221
+ # path - Sass::Script::String URL path
222
+ #
223
+ # Returns a Sass::Script::String.
224
+ def stylesheet_path(path)
225
+ asset_path(path, type: :stylesheet)
226
+ end
227
+
228
+ # Public: Generate a stylesheet url() link.
229
+ #
230
+ # path - Sass::Script::String URL path
231
+ #
232
+ # Returns a Sass::Script::String.
233
+ def stylesheet_url(path)
234
+ asset_url(path, type: :stylesheet)
235
+ end
236
+
237
+ # Public: Generate a data URI for asset path.
238
+ #
239
+ # path - Sass::Script::String logical asset path
240
+ #
241
+ # Returns a Sass::Script::String.
242
+ def asset_data_url(path)
243
+ url = sprockets_context.asset_data_uri(path.value)
244
+ ::Sass::Script::String.new("url(" + url + ")")
245
+ end
246
+
247
+ protected
248
+ # Public: The Environment.
249
+ #
250
+ # Returns Sprockets::Environment.
251
+ def sprockets_environment
252
+ options[:sprockets][:environment]
253
+ end
254
+
255
+ # Public: Mutatable set of dependencies.
256
+ #
257
+ # Returns a Set.
258
+ def sprockets_dependencies
259
+ options[:sprockets][:dependencies]
260
+ end
261
+
262
+ # Deprecated: Get the Context instance. Use APIs on
263
+ # sprockets_environment or sprockets_dependencies directly.
264
+ #
265
+ # Returns a Context instance.
266
+ def sprockets_context
267
+ options[:sprockets][:context]
268
+ end
269
+
270
+ 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
+ end
293
+
294
+ class ScssProcessor < SassProcessor
295
+ def self.syntax
296
+ :scss
297
+ end
298
+ end
299
+
300
+ # Deprecated: Use Sprockets::SassProcessor::Functions instead.
301
+ SassFunctions = SassProcessor::Functions
302
+
303
+ # Deprecated: Use Sprockets::SassProcessor::CacheStore instead.
304
+ SassCacheStore = SassProcessor::CacheStore
305
+ end