sprockets 2.12.5 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sprockets might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/LICENSE +2 -2
- data/README.md +61 -34
- data/lib/rake/sprocketstask.rb +5 -4
- data/lib/sprockets.rb +123 -85
- data/lib/sprockets/asset.rb +161 -200
- data/lib/sprockets/asset_uri.rb +64 -0
- data/lib/sprockets/base.rb +138 -373
- data/lib/sprockets/bower.rb +56 -0
- data/lib/sprockets/bundle.rb +32 -0
- data/lib/sprockets/cache.rb +220 -0
- data/lib/sprockets/cache/file_store.rb +145 -13
- data/lib/sprockets/cache/memory_store.rb +66 -0
- data/lib/sprockets/cache/null_store.rb +46 -0
- data/lib/sprockets/cached_environment.rb +103 -0
- data/lib/sprockets/closure_compressor.rb +30 -12
- data/lib/sprockets/coffee_script_template.rb +23 -0
- data/lib/sprockets/compressing.rb +20 -25
- data/lib/sprockets/configuration.rb +95 -0
- data/lib/sprockets/context.rb +68 -131
- data/lib/sprockets/directive_processor.rb +138 -179
- data/lib/sprockets/eco_template.rb +10 -19
- data/lib/sprockets/ejs_template.rb +10 -19
- data/lib/sprockets/encoding_utils.rb +246 -0
- data/lib/sprockets/engines.rb +40 -29
- data/lib/sprockets/environment.rb +10 -66
- data/lib/sprockets/erb_template.rb +23 -0
- data/lib/sprockets/errors.rb +5 -13
- data/lib/sprockets/http_utils.rb +97 -0
- data/lib/sprockets/jst_processor.rb +28 -15
- data/lib/sprockets/lazy_processor.rb +15 -0
- data/lib/sprockets/legacy.rb +23 -0
- data/lib/sprockets/legacy_proc_processor.rb +35 -0
- data/lib/sprockets/legacy_tilt_processor.rb +29 -0
- data/lib/sprockets/manifest.rb +128 -99
- data/lib/sprockets/mime.rb +114 -33
- data/lib/sprockets/path_utils.rb +179 -0
- data/lib/sprockets/paths.rb +13 -26
- data/lib/sprockets/processing.rb +198 -107
- data/lib/sprockets/resolve.rb +289 -0
- data/lib/sprockets/sass_compressor.rb +36 -17
- data/lib/sprockets/sass_template.rb +269 -46
- data/lib/sprockets/server.rb +113 -83
- data/lib/sprockets/transformers.rb +69 -0
- data/lib/sprockets/uglifier_compressor.rb +36 -15
- data/lib/sprockets/utils.rb +161 -44
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +37 -12
- metadata +64 -106
- data/lib/sprockets/asset_attributes.rb +0 -137
- data/lib/sprockets/bundled_asset.rb +0 -78
- data/lib/sprockets/caching.rb +0 -96
- data/lib/sprockets/charset_normalizer.rb +0 -41
- data/lib/sprockets/index.rb +0 -100
- data/lib/sprockets/processed_asset.rb +0 -152
- data/lib/sprockets/processor.rb +0 -32
- data/lib/sprockets/safety_colons.rb +0 -28
- data/lib/sprockets/sass_cache_store.rb +0 -29
- data/lib/sprockets/sass_functions.rb +0 -70
- data/lib/sprockets/sass_importer.rb +0 -30
- data/lib/sprockets/scss_template.rb +0 -13
- data/lib/sprockets/static_asset.rb +0 -60
@@ -0,0 +1,289 @@
|
|
1
|
+
module Sprockets
|
2
|
+
module Resolve
|
3
|
+
# Public: Iterate over every file under all load paths.
|
4
|
+
#
|
5
|
+
# Returns Enumerator if no block is given.
|
6
|
+
def each_file
|
7
|
+
return to_enum(__method__) unless block_given?
|
8
|
+
|
9
|
+
paths.each do |root|
|
10
|
+
stat_tree(root).each do |filename, stat|
|
11
|
+
if stat.file?
|
12
|
+
yield filename
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds the expanded real path for a given logical path by
|
21
|
+
# searching the environment's paths.
|
22
|
+
#
|
23
|
+
# resolve("application.js")
|
24
|
+
# # => "/path/to/app/javascripts/application.js.coffee"
|
25
|
+
#
|
26
|
+
# A `FileNotFound` exception is raised if the file does not exist.
|
27
|
+
def resolve(path, options = {})
|
28
|
+
resolve_all(path, options) do |filename|
|
29
|
+
return filename
|
30
|
+
end
|
31
|
+
|
32
|
+
accept = options[:accept]
|
33
|
+
message = "couldn't find file '#{path}'"
|
34
|
+
message << " with type '#{accept}'" if accept
|
35
|
+
raise FileNotFound, message
|
36
|
+
end
|
37
|
+
|
38
|
+
def resolve_in_load_path(load_path, logical_path, options = {})
|
39
|
+
if !self.paths.include?(load_path.to_s)
|
40
|
+
raise FileOutsidePaths, "#{load_path} isn't in paths: #{self.paths.join(', ')}"
|
41
|
+
end
|
42
|
+
|
43
|
+
resolve_all_under_load_path(load_path, logical_path, options) do |filename|
|
44
|
+
return filename
|
45
|
+
end
|
46
|
+
|
47
|
+
accept = options[:accept]
|
48
|
+
message = "couldn't find file '#{logical_path}' under '#{load_path}'"
|
49
|
+
message << " with type '#{accept}'" if accept
|
50
|
+
raise FileNotFound, message
|
51
|
+
end
|
52
|
+
|
53
|
+
def resolve_all_under_load_path(load_path, logical_path, options = {}, &block)
|
54
|
+
return to_enum(__method__, load_path, logical_path, options) unless block_given?
|
55
|
+
|
56
|
+
logical_name, mime_type, _ = parse_path_extnames(logical_path)
|
57
|
+
logical_basename = File.basename(logical_name)
|
58
|
+
|
59
|
+
accepts = parse_accept_options(mime_type, options[:accept])
|
60
|
+
|
61
|
+
_resolve_all_under_load_path(load_path, logical_name, logical_basename, accepts, &block)
|
62
|
+
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
|
66
|
+
# Public: Finds the expanded real path for a given logical path by searching
|
67
|
+
# the environment's paths. Includes all matching paths including fallbacks
|
68
|
+
# and shadowed matches.
|
69
|
+
#
|
70
|
+
# resolve_all("application.js").first
|
71
|
+
# # => "/path/to/app/javascripts/application.js.coffee"
|
72
|
+
#
|
73
|
+
# `resolve_all` returns an `Enumerator`. This allows you to filter your
|
74
|
+
# matches by any condition.
|
75
|
+
#
|
76
|
+
# resolve_all("application").find do |path|
|
77
|
+
# mime_type_for(path) == "text/css"
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
def resolve_all(path, options = {}, &block)
|
81
|
+
return to_enum(__method__, path, options) unless block_given?
|
82
|
+
path = path.to_s
|
83
|
+
|
84
|
+
logical_name, mime_type, _ = parse_path_extnames(path)
|
85
|
+
logical_basename = File.basename(logical_name)
|
86
|
+
|
87
|
+
accepts = parse_accept_options(mime_type, options[:accept])
|
88
|
+
|
89
|
+
self.paths.each do |load_path|
|
90
|
+
_resolve_all_under_load_path(load_path, logical_name, logical_basename, accepts, &block)
|
91
|
+
end
|
92
|
+
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
# Experimental: Get transform type for filename
|
97
|
+
def resolve_path_transform_type(filename, accept)
|
98
|
+
mime_type = parse_path_extnames(filename)[1]
|
99
|
+
resolve_transform_type(mime_type, accept)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Experimental
|
103
|
+
def resolve_asset_uri(path, options = {})
|
104
|
+
path = path.to_s
|
105
|
+
accept = options[:accept]
|
106
|
+
skip_bundle = options.key?(:bundle) ? !options[:bundle] : false
|
107
|
+
|
108
|
+
available_encodings = self.encodings.keys + ['identity']
|
109
|
+
encoding = find_best_q_match(options[:accept_encoding], available_encodings)
|
110
|
+
|
111
|
+
if absolute_path?(path)
|
112
|
+
path = File.expand_path(path)
|
113
|
+
if file?(path) && (accept.nil? || resolve_path_transform_type(path, accept))
|
114
|
+
filename = path
|
115
|
+
type = resolve_path_transform_type(path, accept)
|
116
|
+
end
|
117
|
+
else
|
118
|
+
if filename = resolve_all(path, accept: accept).first
|
119
|
+
mime_type = parse_path_extnames(path)[1]
|
120
|
+
accept = parse_accept_options(mime_type, accept).map { |t, v| "#{t}; q=#{v}" }.join(", ")
|
121
|
+
type = resolve_path_transform_type(filename, accept)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if filename
|
126
|
+
encoding = nil if encoding == 'identity'
|
127
|
+
AssetURI.build(filename, type: type, skip_bundle: skip_bundle, encoding: encoding)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Public: Enumerate over all logical paths in the environment.
|
132
|
+
#
|
133
|
+
# Returns an Enumerator of [logical_path, filename].
|
134
|
+
def logical_paths
|
135
|
+
return to_enum(__method__) unless block_given?
|
136
|
+
|
137
|
+
seen = Set.new
|
138
|
+
|
139
|
+
self.paths.each do |load_path|
|
140
|
+
stat_tree(load_path).each do |filename, stat|
|
141
|
+
next unless stat.file?
|
142
|
+
|
143
|
+
path = split_subpath(load_path, filename)
|
144
|
+
path, mime_type, _ = parse_path_extnames(path)
|
145
|
+
path = normalize_logical_path(path)
|
146
|
+
path += mime_types[mime_type][:extensions].first if mime_type
|
147
|
+
|
148
|
+
if !seen.include?(path)
|
149
|
+
yield path, filename
|
150
|
+
seen << path
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
nil
|
156
|
+
end
|
157
|
+
|
158
|
+
# Deprecated: Iterate over all logical paths with a matcher.
|
159
|
+
#
|
160
|
+
# Remove from 4.x.
|
161
|
+
#
|
162
|
+
# args - List of matcher objects.
|
163
|
+
#
|
164
|
+
# Returns Enumerator if no block is given.
|
165
|
+
def each_logical_path(*args, &block)
|
166
|
+
return to_enum(__method__, *args) unless block_given?
|
167
|
+
|
168
|
+
filters = args.flatten.map { |arg| Manifest.compile_match_filter(arg) }
|
169
|
+
logical_paths.each do |a, b|
|
170
|
+
if filters.any? { |f| f.call(a, b) }
|
171
|
+
if block.arity == 2
|
172
|
+
yield a, b
|
173
|
+
else
|
174
|
+
yield a
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
nil
|
180
|
+
end
|
181
|
+
|
182
|
+
protected
|
183
|
+
def parse_accept_options(mime_type, types)
|
184
|
+
accepts = []
|
185
|
+
accepts += parse_q_values(types) if types
|
186
|
+
|
187
|
+
if mime_type
|
188
|
+
if accepts.empty? || accepts.any? { |accept, _| match_mime_type?(mime_type, accept) }
|
189
|
+
accepts = [[mime_type, 1.0]]
|
190
|
+
else
|
191
|
+
return []
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if accepts.empty?
|
196
|
+
accepts << ['*/*', 1.0]
|
197
|
+
end
|
198
|
+
|
199
|
+
accepts
|
200
|
+
end
|
201
|
+
|
202
|
+
def normalize_logical_path(path)
|
203
|
+
dirname, basename = File.split(path)
|
204
|
+
path = dirname if basename == 'index'
|
205
|
+
path
|
206
|
+
end
|
207
|
+
|
208
|
+
def _resolve_all_under_load_path(load_path, logical_name, logical_basename, accepts, &block)
|
209
|
+
filenames = path_matches(load_path, logical_name, logical_basename)
|
210
|
+
|
211
|
+
matches = []
|
212
|
+
|
213
|
+
# TODO: Cleanup double iteration of accept and filenames
|
214
|
+
|
215
|
+
# Exact mime type match first
|
216
|
+
matches += find_q_matches(accepts, filenames) do |filename, accepted|
|
217
|
+
if !file?(filename)
|
218
|
+
nil
|
219
|
+
elsif accepted == '*/*'
|
220
|
+
filename
|
221
|
+
elsif parse_path_extnames(filename)[1] == accepted
|
222
|
+
filename
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Then transformable match
|
227
|
+
matches += find_q_matches(accepts, filenames) do |filename, accepted|
|
228
|
+
if !file?(filename)
|
229
|
+
nil
|
230
|
+
elsif accepted == '*/*'
|
231
|
+
filename
|
232
|
+
elsif resolve_path_transform_type(filename, accepted)
|
233
|
+
filename
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
matches.uniq.each(&block)
|
238
|
+
end
|
239
|
+
|
240
|
+
def path_matches(load_path, logical_name, logical_basename)
|
241
|
+
filenames = []
|
242
|
+
dirname = File.dirname(File.join(load_path, logical_name))
|
243
|
+
dirname_matches(dirname, logical_basename) { |fn| filenames << fn }
|
244
|
+
resolve_alternates(load_path, logical_name) { |fn| filenames << fn }
|
245
|
+
dirname_matches(File.join(load_path, logical_name), "index") { |fn| filenames << fn }
|
246
|
+
filenames
|
247
|
+
end
|
248
|
+
|
249
|
+
def dirname_matches(dirname, basename)
|
250
|
+
self.entries(dirname).each do |entry|
|
251
|
+
name = parse_path_extnames(entry)[0]
|
252
|
+
if basename == name
|
253
|
+
yield File.join(dirname, entry)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def resolve_alternates(load_path, logical_name)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Internal: Returns the name, mime type and `Array` of engine extensions.
|
262
|
+
#
|
263
|
+
# "foo.js.coffee.erb"
|
264
|
+
# # => ["foo", "application/javascript", [".coffee", ".erb"]]
|
265
|
+
#
|
266
|
+
def parse_path_extnames(path)
|
267
|
+
mime_type = nil
|
268
|
+
engine_extnames = []
|
269
|
+
len = path.length
|
270
|
+
|
271
|
+
path_extnames(path).reverse_each do |extname|
|
272
|
+
if engines.key?(extname)
|
273
|
+
mime_type = engine_mime_types[extname]
|
274
|
+
engine_extnames.unshift(extname)
|
275
|
+
len -= extname.length
|
276
|
+
elsif mime_exts.key?(extname)
|
277
|
+
mime_type = mime_exts[extname]
|
278
|
+
len -= extname.length
|
279
|
+
break
|
280
|
+
else
|
281
|
+
break
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
name = path[0, len]
|
286
|
+
return [name, mime_type, engine_extnames]
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
@@ -1,27 +1,46 @@
|
|
1
|
-
require '
|
1
|
+
require 'sass'
|
2
2
|
|
3
3
|
module Sprockets
|
4
|
-
|
5
|
-
|
4
|
+
# Public: Sass CSS minifier.
|
5
|
+
#
|
6
|
+
# To accept the default options
|
7
|
+
#
|
8
|
+
# environment.register_bundle_processor 'text/css',
|
9
|
+
# Sprockets::SassCompressor
|
10
|
+
#
|
11
|
+
# Or to pass options to the Sass::Engine class.
|
12
|
+
#
|
13
|
+
# environment.register_bundle_processor 'text/css',
|
14
|
+
# Sprockets::SassCompressor.new({ ... })
|
15
|
+
#
|
16
|
+
class SassCompressor
|
17
|
+
VERSION = '1'
|
6
18
|
|
7
|
-
def self.
|
8
|
-
|
19
|
+
def self.call(*args)
|
20
|
+
new.call(*args)
|
9
21
|
end
|
10
22
|
|
11
|
-
def
|
12
|
-
|
23
|
+
def initialize(options = {})
|
24
|
+
@options = options
|
25
|
+
@cache_key = [
|
26
|
+
'SassCompressor',
|
27
|
+
::Sass::VERSION,
|
28
|
+
VERSION,
|
29
|
+
options
|
30
|
+
]
|
13
31
|
end
|
14
32
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
33
|
+
def call(input)
|
34
|
+
data = input[:data]
|
35
|
+
input[:cache].fetch(@cache_key + [data]) do
|
36
|
+
options = {
|
37
|
+
syntax: :scss,
|
38
|
+
cache: false,
|
39
|
+
read_cache: false,
|
40
|
+
style: :compressed
|
41
|
+
}.merge(@options)
|
42
|
+
::Sass::Engine.new(data, options).render
|
43
|
+
end
|
25
44
|
end
|
26
45
|
end
|
27
46
|
end
|
@@ -1,66 +1,289 @@
|
|
1
|
-
require '
|
1
|
+
require 'rack/utils'
|
2
|
+
require 'sass'
|
3
|
+
require 'uri'
|
2
4
|
|
3
5
|
module Sprockets
|
4
|
-
#
|
5
|
-
# main difference is that it uses a custom importer that plays nice
|
6
|
-
# with sprocket's caching system.
|
6
|
+
# Template engine class for the SASS/SCSS compiler. Depends on the `sass` gem.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
# For more infomation see:
|
9
|
+
#
|
10
|
+
# https://github.com/sass/sass
|
11
|
+
# https://github.com/rails/sass-rails
|
12
|
+
#
|
13
|
+
class SassTemplate
|
14
|
+
# Internal: Defines default sass syntax to use. Exposed so the ScssTemplate
|
15
|
+
# may override it.
|
16
|
+
def self.syntax
|
17
|
+
:sass
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
|
19
|
-
unless defined? ::Sass
|
20
|
-
require_template_library 'sass'
|
21
|
-
end
|
22
|
-
|
23
|
-
# Install custom functions. It'd be great if this didn't need to
|
24
|
-
# be installed globally, but could be passed into Engine as an
|
25
|
-
# option.
|
26
|
-
::Sass::Script::Functions.send :include, Sprockets::SassFunctions
|
20
|
+
def self.call(*args)
|
21
|
+
new.call(*args)
|
27
22
|
end
|
28
23
|
|
29
|
-
|
30
|
-
|
24
|
+
# Public: Initialize template with custom options.
|
25
|
+
#
|
26
|
+
# options - Hash
|
27
|
+
# cache_version - String custom cache version. Used to force a cache
|
28
|
+
# change after code changes are made to Sass Functions.
|
29
|
+
#
|
30
|
+
def initialize(options = {}, &block)
|
31
|
+
@cache_version = options[:cache_version]
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
@functions = Module.new do
|
34
|
+
include Functions
|
35
|
+
include options[:functions] if options[:functions]
|
36
|
+
class_eval(&block) if block_given?
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
36
|
-
def
|
37
|
-
|
38
|
-
cache_store = SassCacheStore.new(context.environment)
|
40
|
+
def call(input)
|
41
|
+
context = input[:environment].context_class.new(input)
|
39
42
|
|
40
43
|
options = {
|
41
|
-
:filename
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
|
47
|
-
|
48
|
-
:
|
49
|
-
:environment => context.environment
|
44
|
+
filename: input[:filename],
|
45
|
+
syntax: self.class.syntax,
|
46
|
+
cache_store: CacheStore.new(input[:cache], @cache_version),
|
47
|
+
load_paths: input[:environment].paths,
|
48
|
+
sprockets: {
|
49
|
+
context: context,
|
50
|
+
environment: input[:environment],
|
51
|
+
dependencies: context.metadata[:dependency_paths]
|
50
52
|
}
|
51
53
|
}
|
52
54
|
|
53
|
-
|
55
|
+
engine = ::Sass::Engine.new(input[:data], options)
|
56
|
+
|
57
|
+
css = Utils.module_include(::Sass::Script::Functions, @functions) do
|
58
|
+
engine.render
|
59
|
+
end
|
54
60
|
|
55
61
|
# Track all imported files
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
engine.dependencies.map do |dependency|
|
63
|
+
context.metadata[:dependency_paths] << dependency.options[:filename]
|
64
|
+
end
|
65
|
+
|
66
|
+
context.metadata.merge(data: css)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Public: Functions injected into Sass context during Sprockets evaluation.
|
70
|
+
#
|
71
|
+
# This module may be extended to add global functionality to all Sprockets
|
72
|
+
# Sass environments. Though, scoping your functions to just your environment
|
73
|
+
# is preferred.
|
74
|
+
#
|
75
|
+
# module Sprockets::SassTemplate::Functions
|
76
|
+
# def asset_path(path, options = {})
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
module Functions
|
81
|
+
# Public: Generate a url for asset path.
|
82
|
+
#
|
83
|
+
# Default implementation is deprecated. Currently defaults to
|
84
|
+
# Context#asset_path.
|
85
|
+
#
|
86
|
+
# Will raise NotImplementedError in the future. Users should provide their
|
87
|
+
# own base implementation.
|
88
|
+
#
|
89
|
+
# Returns a Sass::Script::String.
|
90
|
+
def asset_path(path, options = {})
|
91
|
+
path = path.value
|
92
|
+
|
93
|
+
path, _, query, fragment = URI.split(path)[5..8]
|
94
|
+
path = sprockets_context.asset_path(path, options)
|
95
|
+
query = "?#{query}" if query
|
96
|
+
fragment = "##{fragment}" if fragment
|
97
|
+
|
98
|
+
::Sass::Script::String.new("#{path}#{query}#{fragment}", :string)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Public: Generate a asset url() link.
|
102
|
+
#
|
103
|
+
# path - Sass::Script::String URL path
|
104
|
+
#
|
105
|
+
# Returns a Sass::Script::String.
|
106
|
+
def asset_url(path, options = {})
|
107
|
+
::Sass::Script::String.new("url(#{asset_path(path, options).value})")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Public: Generate url for image path.
|
111
|
+
#
|
112
|
+
# path - Sass::Script::String URL path
|
113
|
+
#
|
114
|
+
# Returns a Sass::Script::String.
|
115
|
+
def image_path(path)
|
116
|
+
asset_path(path, type: :image)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Public: Generate a image url() link.
|
120
|
+
#
|
121
|
+
# path - Sass::Script::String URL path
|
122
|
+
#
|
123
|
+
# Returns a Sass::Script::String.
|
124
|
+
def image_url(path)
|
125
|
+
asset_url(path, type: :image)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Public: Generate url for video path.
|
129
|
+
#
|
130
|
+
# path - Sass::Script::String URL path
|
131
|
+
#
|
132
|
+
# Returns a Sass::Script::String.
|
133
|
+
def video_path(path)
|
134
|
+
asset_path(path, type: :video)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Public: Generate a video url() link.
|
138
|
+
#
|
139
|
+
# path - Sass::Script::String URL path
|
140
|
+
#
|
141
|
+
# Returns a Sass::Script::String.
|
142
|
+
def video_url(path)
|
143
|
+
asset_url(path, type: :video)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Public: Generate url for audio path.
|
147
|
+
#
|
148
|
+
# path - Sass::Script::String URL path
|
149
|
+
#
|
150
|
+
# Returns a Sass::Script::String.
|
151
|
+
def audio_path(path)
|
152
|
+
asset_path(path, type: :audio)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Public: Generate a audio url() link.
|
156
|
+
#
|
157
|
+
# path - Sass::Script::String URL path
|
158
|
+
#
|
159
|
+
# Returns a Sass::Script::String.
|
160
|
+
def audio_url(path)
|
161
|
+
asset_url(path, type: :audio)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Public: Generate url for font path.
|
165
|
+
#
|
166
|
+
# path - Sass::Script::String URL path
|
167
|
+
#
|
168
|
+
# Returns a Sass::Script::String.
|
169
|
+
def font_path(path)
|
170
|
+
asset_path(path, type: :font)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Public: Generate a font url() link.
|
174
|
+
#
|
175
|
+
# path - Sass::Script::String URL path
|
176
|
+
#
|
177
|
+
# Returns a Sass::Script::String.
|
178
|
+
def font_url(path)
|
179
|
+
asset_url(path, type: :font)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Public: Generate url for javascript path.
|
183
|
+
#
|
184
|
+
# path - Sass::Script::String URL path
|
185
|
+
#
|
186
|
+
# Returns a Sass::Script::String.
|
187
|
+
def javascript_path(path)
|
188
|
+
asset_path(path, type: :javascript)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Public: Generate a javascript url() link.
|
192
|
+
#
|
193
|
+
# path - Sass::Script::String URL path
|
194
|
+
#
|
195
|
+
# Returns a Sass::Script::String.
|
196
|
+
def javascript_url(path)
|
197
|
+
asset_url(path, type: :javascript)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Public: Generate url for stylesheet path.
|
201
|
+
#
|
202
|
+
# path - Sass::Script::String URL path
|
203
|
+
#
|
204
|
+
# Returns a Sass::Script::String.
|
205
|
+
def stylesheet_path(path)
|
206
|
+
asset_path(path, type: :stylesheet)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Public: Generate a stylesheet url() link.
|
210
|
+
#
|
211
|
+
# path - Sass::Script::String URL path
|
212
|
+
#
|
213
|
+
# Returns a Sass::Script::String.
|
214
|
+
def stylesheet_url(path)
|
215
|
+
asset_url(path, type: :stylesheet)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Public: Generate a data URI for asset path.
|
219
|
+
#
|
220
|
+
# path - Sass::Script::String logical asset path
|
221
|
+
#
|
222
|
+
# Returns a Sass::Script::String.
|
223
|
+
def asset_data_url(path)
|
224
|
+
if asset = sprockets_environment.find_asset(path.value, accept_encoding: 'base64')
|
225
|
+
sprockets_dependencies << asset.filename
|
226
|
+
url = "data:#{asset.content_type};base64,#{Rack::Utils.escape(asset.to_s)}"
|
227
|
+
::Sass::Script::String.new("url(" + url + ")")
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
protected
|
232
|
+
# Public: The Environment.
|
233
|
+
#
|
234
|
+
# Returns Sprockets::Environment.
|
235
|
+
def sprockets_environment
|
236
|
+
options[:sprockets][:environment]
|
237
|
+
end
|
238
|
+
|
239
|
+
# Public: Mutatable set dependency paths.
|
240
|
+
#
|
241
|
+
# Returns a Set.
|
242
|
+
def sprockets_dependencies
|
243
|
+
options[:sprockets][:dependencies]
|
244
|
+
end
|
245
|
+
|
246
|
+
# Deprecated: Get the Context instance. Use APIs on
|
247
|
+
# sprockets_environment or sprockets_dependencies directly.
|
248
|
+
#
|
249
|
+
# Returns a Context instance.
|
250
|
+
def sprockets_context
|
251
|
+
options[:sprockets][:context]
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
# Internal: Cache wrapper for Sprockets cache adapter.
|
257
|
+
class CacheStore < ::Sass::CacheStores::Base
|
258
|
+
VERSION = '1'
|
259
|
+
|
260
|
+
def initialize(cache, version)
|
261
|
+
@cache, @version = cache, "#{VERSION}/#{version}"
|
262
|
+
end
|
263
|
+
|
264
|
+
def _store(key, version, sha, contents)
|
265
|
+
@cache._set("#{@version}/#{version}/#{key}/#{sha}", contents)
|
266
|
+
end
|
267
|
+
|
268
|
+
def _retrieve(key, version, sha)
|
269
|
+
@cache._get("#{@version}/#{version}/#{key}/#{sha}")
|
270
|
+
end
|
271
|
+
|
272
|
+
def path_to(key)
|
273
|
+
key
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
class ScssTemplate < SassTemplate
|
279
|
+
def self.syntax
|
280
|
+
:scss
|
64
281
|
end
|
65
282
|
end
|
283
|
+
|
284
|
+
# Deprecated: Use Sprockets::SassTemplate::Functions instead.
|
285
|
+
SassFunctions = SassTemplate::Functions
|
286
|
+
|
287
|
+
# Deprecated: Use Sprockets::SassTemplate::CacheStore instead.
|
288
|
+
SassCacheStore = SassTemplate::CacheStore
|
66
289
|
end
|