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.
- checksums.yaml +4 -4
- data/README.md +171 -100
- data/lib/rake/sprocketstask.rb +2 -2
- data/lib/sprockets.rb +69 -63
- data/lib/sprockets/asset.rb +2 -61
- data/lib/sprockets/autoload_processor.rb +48 -0
- data/lib/sprockets/base.rb +4 -6
- data/lib/sprockets/bower.rb +8 -5
- data/lib/sprockets/bundle.rb +9 -13
- data/lib/sprockets/cache.rb +19 -14
- data/lib/sprockets/cache/file_store.rb +2 -1
- data/lib/sprockets/cached_environment.rb +15 -68
- data/lib/sprockets/closure_compressor.rb +17 -4
- data/lib/sprockets/coffee_script_processor.rb +26 -0
- data/lib/sprockets/coffee_script_template.rb +3 -20
- data/lib/sprockets/compressing.rb +10 -4
- data/lib/sprockets/configuration.rb +21 -37
- data/lib/sprockets/context.rb +37 -67
- data/lib/sprockets/dependencies.rb +73 -0
- data/lib/sprockets/digest_utils.rb +8 -2
- data/lib/sprockets/directive_processor.rb +122 -165
- data/lib/sprockets/eco_processor.rb +32 -0
- data/lib/sprockets/eco_template.rb +3 -26
- data/lib/sprockets/ejs_processor.rb +31 -0
- data/lib/sprockets/ejs_template.rb +3 -25
- data/lib/sprockets/encoding_utils.rb +9 -21
- data/lib/sprockets/engines.rb +25 -27
- data/lib/sprockets/environment.rb +9 -1
- data/lib/sprockets/erb_processor.rb +30 -0
- data/lib/sprockets/erb_template.rb +3 -20
- data/lib/sprockets/file_reader.rb +15 -0
- data/lib/sprockets/http_utils.rb +2 -0
- data/lib/sprockets/jst_processor.rb +9 -2
- data/lib/sprockets/legacy.rb +212 -3
- data/lib/sprockets/legacy_tilt_processor.rb +1 -1
- data/lib/sprockets/loader.rb +95 -89
- data/lib/sprockets/manifest.rb +23 -59
- data/lib/sprockets/mime.rb +28 -41
- data/lib/sprockets/path_dependency_utils.rb +76 -0
- data/lib/sprockets/path_utils.rb +21 -1
- data/lib/sprockets/paths.rb +23 -8
- data/lib/sprockets/processing.rb +102 -91
- data/lib/sprockets/processor_utils.rb +97 -0
- data/lib/sprockets/resolve.rb +110 -97
- data/lib/sprockets/sass_cache_store.rb +2 -2
- data/lib/sprockets/sass_compressor.rb +17 -4
- data/lib/sprockets/sass_functions.rb +2 -2
- data/lib/sprockets/sass_importer.rb +2 -2
- data/lib/sprockets/sass_processor.rb +305 -0
- data/lib/sprockets/sass_template.rb +4 -286
- data/lib/sprockets/server.rb +1 -13
- data/lib/sprockets/transformers.rb +62 -25
- data/lib/sprockets/uglifier_compressor.rb +17 -4
- data/lib/sprockets/uri_utils.rb +190 -0
- data/lib/sprockets/utils.rb +87 -6
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets/yui_compressor.rb +17 -4
- metadata +14 -5
- data/lib/sprockets/asset_uri.rb +0 -80
- data/lib/sprockets/lazy_processor.rb +0 -15
@@ -1,289 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
require 'sass'
|
3
|
-
require 'uri'
|
1
|
+
require 'sprockets/sass_processor'
|
4
2
|
|
5
3
|
module Sprockets
|
6
|
-
#
|
7
|
-
|
8
|
-
|
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
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.call(*args)
|
21
|
-
new.call(*args)
|
22
|
-
end
|
23
|
-
|
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]
|
32
|
-
|
33
|
-
@functions = Module.new do
|
34
|
-
include Functions
|
35
|
-
include options[:functions] if options[:functions]
|
36
|
-
class_eval(&block) if block_given?
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def call(input)
|
41
|
-
context = input[:environment].context_class.new(input)
|
42
|
-
|
43
|
-
options = {
|
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]
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
engine = ::Sass::Engine.new(input[:data], options)
|
56
|
-
|
57
|
-
css = Utils.module_include(::Sass::Script::Functions, @functions) do
|
58
|
-
engine.render
|
59
|
-
end
|
60
|
-
|
61
|
-
# Track all imported files
|
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
|
281
|
-
end
|
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
|
4
|
+
# Deprecated
|
5
|
+
SassTemplate = SassProcessor
|
6
|
+
ScssTemplate = ScssProcessor
|
289
7
|
end
|
data/lib/sprockets/server.rb
CHANGED
@@ -48,7 +48,7 @@ module Sprockets
|
|
48
48
|
|
49
49
|
# 2.x/3.x compatibility hack. Just ignore fingerprints on ?body=1 requests.
|
50
50
|
# 3.x/4.x prefers strong validation of fingerprint to body contents, but
|
51
|
-
# 2.x just ignored it.
|
51
|
+
# 2.x just ignored it.
|
52
52
|
if options[:bundle] == false
|
53
53
|
fingerprint = nil
|
54
54
|
end
|
@@ -63,13 +63,6 @@ module Sprockets
|
|
63
63
|
if_none_match = env['HTTP_IF_NONE_MATCH'][/^"(\w+)"$/, 1]
|
64
64
|
end
|
65
65
|
|
66
|
-
if !if_match && !if_none_match && env['HTTP_ACCEPT_ENCODING']
|
67
|
-
# Accept-Encoding negotiation is only enabled for non-fingerprinted
|
68
|
-
# assets. Avoids the "Apache ETag gzip" bug. Just Google it.
|
69
|
-
# https://issues.apache.org/bugzilla/show_bug.cgi?id=39727
|
70
|
-
options[:accept_encoding] = env['HTTP_ACCEPT_ENCODING']
|
71
|
-
end
|
72
|
-
|
73
66
|
asset = find_asset(path, options)
|
74
67
|
|
75
68
|
if asset.nil?
|
@@ -252,11 +245,6 @@ module Sprockets
|
|
252
245
|
def headers(env, asset, length)
|
253
246
|
headers = {}
|
254
247
|
|
255
|
-
# Set content encoding
|
256
|
-
if asset.encoding
|
257
|
-
headers["Content-Encoding"] = asset.encoding
|
258
|
-
end
|
259
|
-
|
260
248
|
# Set content length header
|
261
249
|
headers["Content-Length"] = length.to_s
|
262
250
|
|
@@ -1,5 +1,11 @@
|
|
1
|
+
require 'sprockets/http_utils'
|
2
|
+
require 'sprockets/processor_utils'
|
3
|
+
require 'sprockets/utils'
|
4
|
+
|
1
5
|
module Sprockets
|
2
6
|
module Transformers
|
7
|
+
include HTTPUtils, ProcessorUtils, Utils
|
8
|
+
|
3
9
|
# Public: Two level mapping of a source mime type to a target mime type.
|
4
10
|
#
|
5
11
|
# environment.transformers
|
@@ -8,17 +14,9 @@ module Sprockets
|
|
8
14
|
# }
|
9
15
|
# }
|
10
16
|
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
# environment.inverted_transformers
|
16
|
-
# # => { 'application/javascript' => {
|
17
|
-
# 'text/coffeescript' => ConvertCoffeeScriptToJavaScript
|
18
|
-
# }
|
19
|
-
# }
|
20
|
-
#
|
21
|
-
attr_reader :inverted_transformers
|
17
|
+
def transformers
|
18
|
+
config[:transformers]
|
19
|
+
end
|
22
20
|
|
23
21
|
# Public: Register a transformer from and to a mime type.
|
24
22
|
#
|
@@ -35,12 +33,10 @@ module Sprockets
|
|
35
33
|
#
|
36
34
|
# Returns nothing.
|
37
35
|
def register_transformer(from, to, proc)
|
38
|
-
|
36
|
+
self.config = hash_reassoc(config, :registered_transformers, from) do |transformers|
|
39
37
|
transformers.merge(to => proc)
|
40
38
|
end
|
41
|
-
|
42
|
-
transformers.merge(from => proc)
|
43
|
-
end
|
39
|
+
compute_transformers!
|
44
40
|
end
|
45
41
|
|
46
42
|
# Internal: Resolve target mime type that the source type should be
|
@@ -79,25 +75,66 @@ module Sprockets
|
|
79
75
|
accepts = []
|
80
76
|
parsed_accepts.each do |(type, q)|
|
81
77
|
accepts.push([type, q])
|
82
|
-
inverted_transformers[type].
|
78
|
+
config[:inverted_transformers][type].each do |subtype|
|
83
79
|
accepts.push([subtype, q * 0.8])
|
84
80
|
end
|
85
81
|
end
|
86
82
|
accepts
|
87
83
|
end
|
88
84
|
|
89
|
-
# Internal:
|
85
|
+
# Internal: Compose multiple transformer steps into a single processor
|
86
|
+
# function.
|
90
87
|
#
|
91
|
-
#
|
92
|
-
#
|
88
|
+
# transformers - Two level Hash of a source mime type to a target mime type
|
89
|
+
# types - Array of mime type steps
|
93
90
|
#
|
94
|
-
# Returns
|
95
|
-
def
|
96
|
-
if
|
97
|
-
|
98
|
-
|
99
|
-
|
91
|
+
# Returns Processor.
|
92
|
+
def compose_transformers(transformers, types)
|
93
|
+
if types.length < 2
|
94
|
+
raise ArgumentError, "too few transform types: #{types.inspect}"
|
95
|
+
end
|
96
|
+
|
97
|
+
processors = []
|
98
|
+
enum = types.each
|
99
|
+
|
100
|
+
loop do
|
101
|
+
src, dst = enum.next, enum.peek
|
102
|
+
unless processor = transformers[src][dst]
|
103
|
+
raise ArgumentError, "missing transformer for type: #{src} to #{dst}"
|
104
|
+
end
|
105
|
+
processors.concat config[:postprocessors][src]
|
106
|
+
processors << processor
|
107
|
+
processors.concat config[:preprocessors][dst]
|
108
|
+
end
|
109
|
+
|
110
|
+
if processors.size > 1
|
111
|
+
compose_processors(*processors.reverse)
|
112
|
+
elsif processors.size == 1
|
113
|
+
processors.first
|
100
114
|
end
|
101
115
|
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def compute_transformers!
|
119
|
+
registered_transformers = self.config[:registered_transformers]
|
120
|
+
transformers = Hash.new { {} }
|
121
|
+
inverted_transformers = Hash.new { Set.new }
|
122
|
+
|
123
|
+
registered_transformers.keys.flat_map do |key|
|
124
|
+
dfs_paths([key]) { |k| registered_transformers[k].keys }
|
125
|
+
end.each do |types|
|
126
|
+
src, dst = types.first, types.last
|
127
|
+
processor = compose_transformers(registered_transformers, types)
|
128
|
+
|
129
|
+
transformers[src] = {} unless transformers.key?(src)
|
130
|
+
transformers[src][dst] = processor
|
131
|
+
|
132
|
+
inverted_transformers[dst] = Set.new unless inverted_transformers.key?(dst)
|
133
|
+
inverted_transformers[dst] << src
|
134
|
+
end
|
135
|
+
|
136
|
+
self.config = hash_reassoc(config, :transformers) { transformers }
|
137
|
+
self.config = hash_reassoc(config, :inverted_transformers) { inverted_transformers }
|
138
|
+
end
|
102
139
|
end
|
103
140
|
end
|