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
@@ -1,7 +1,5 @@
1
- require 'pathname'
1
+ require 'set'
2
2
  require 'shellwords'
3
- require 'tilt'
4
- require 'yaml'
5
3
 
6
4
  module Sprockets
7
5
  # The `DirectiveProcessor` is responsible for parsing and evaluating
@@ -20,10 +18,9 @@ module Sprockets
20
18
  # *= require "baz"
21
19
  # */
22
20
  #
23
- # The Processor is implemented as a `Tilt::Template` and is loosely
24
- # coupled to Sprockets. This makes it possible to disable or modify
25
- # the processor to do whatever you'd like. You could add your own
26
- # custom directives or invent your own directive syntax.
21
+ # This makes it possible to disable or modify the processor to do whatever
22
+ # you'd like. You could add your own custom directives or invent your own
23
+ # directive syntax.
27
24
  #
28
25
  # `Environment#processors` includes `DirectiveProcessor` by default.
29
26
  #
@@ -36,24 +33,8 @@ module Sprockets
36
33
  #
37
34
  # env.register_processor('text/css', MyProcessor)
38
35
  #
39
- class DirectiveProcessor < Tilt::Template
40
- # Directives will only be picked up if they are in the header
41
- # of the source file. C style (/* */), JavaScript (//), and
42
- # Ruby (#) comments are supported.
43
- #
44
- # Directives in comments after the first non-whitespace line
45
- # of code will not be processed.
46
- #
47
- HEADER_PATTERN = /
48
- \A (
49
- (?m:\s*) (
50
- (\/\* (?m:.*?) \*\/) |
51
- (\#\#\# (?m:.*?) \#\#\#) |
52
- (\/\/ .* \n?)+ |
53
- (\# .* \n?)+
54
- )
55
- )+
56
- /x
36
+ class DirectiveProcessor
37
+ VERSION = '1'
57
38
 
58
39
  # Directives are denoted by a `=` followed by the name, then
59
40
  # argument list.
@@ -68,76 +49,108 @@ module Sprockets
68
49
  ^ \W* = \s* (\w+.*?) (\*\/)? $
69
50
  /x
70
51
 
71
- attr_reader :pathname
72
- attr_reader :header, :body
52
+ def self.instance
53
+ @instance ||= new(
54
+ # Deprecated: Default to C and Ruby comment styles
55
+ comments: ["//", ["/*", "*/"]] + ["#", ["###", "###"]]
56
+ )
57
+ end
73
58
 
74
- def prepare
75
- @pathname = Pathname.new(file)
59
+ def self.call(input)
60
+ instance.call(input)
61
+ end
76
62
 
77
- @header = data[HEADER_PATTERN, 0] || ""
78
- @body = $' || data
79
- # Ensure body ends in a new line
80
- @body += "\n" if @body != "" && @body !~ /\n\Z/m
63
+ def initialize(options = {})
64
+ @header_pattern = compile_header_pattern(Array(options[:comments]))
65
+ end
81
66
 
82
- @included_pathnames = []
83
- @compat = false
67
+ def call(input)
68
+ dup._call(input)
84
69
  end
85
70
 
86
- # Implemented for Tilt#render.
87
- #
88
- # `context` is a `Context` instance with methods that allow you to
89
- # access the environment and append to the bundle. See `Context`
90
- # for the complete API.
91
- def evaluate(context, locals, &block)
92
- @context = context
71
+ def _call(input)
72
+ @environment = input[:environment]
73
+ @uri = input[:uri]
74
+ @filename = input[:filename]
75
+ @dirname = File.dirname(@filename)
76
+ @content_type = input[:content_type]
77
+ @required = Set.new(input[:metadata][:required])
78
+ @stubbed = Set.new(input[:metadata][:stubbed])
79
+ @links = Set.new(input[:metadata][:links])
80
+ @dependencies = Set.new(input[:metadata][:dependencies])
81
+
82
+ data, directives = process_source(input[:data])
83
+ process_directives(directives)
84
+
85
+ { data: data,
86
+ required: @required,
87
+ stubbed: @stubbed,
88
+ links: @links,
89
+ dependencies: @dependencies }
90
+ end
93
91
 
94
- @result = ""
95
- @result.force_encoding(body.encoding) if body.respond_to?(:encoding)
92
+ protected
93
+ # Directives will only be picked up if they are in the header
94
+ # of the source file. C style (/* */), JavaScript (//), and
95
+ # Ruby (#) comments are supported.
96
+ #
97
+ # Directives in comments after the first non-whitespace line
98
+ # of code will not be processed.
99
+ def compile_header_pattern(comments)
100
+ re = comments.map { |c|
101
+ case c
102
+ when String
103
+ "(?:#{Regexp.escape(c)}.*\\n?)+"
104
+ when Array
105
+ "(?:#{Regexp.escape(c[0])}(?m:.*?)#{Regexp.escape(c[1])})"
106
+ else
107
+ raise TypeError, "unknown comment type: #{c.class}"
108
+ end
109
+ }.join("|")
110
+ Regexp.compile("\\A(?:(?m:\\s*)(?:#{re}))+")
111
+ end
96
112
 
97
- @has_written_body = false
113
+ def process_source(source)
114
+ header = source[@header_pattern, 0] || ""
115
+ body = $' || source
98
116
 
99
- process_directives
100
- process_source
117
+ header, directives = extract_directives(header)
101
118
 
102
- @result
103
- end
119
+ data = ""
120
+ data.force_encoding(body.encoding)
121
+ data << header << "\n" unless header.empty?
122
+ data << body
123
+ # Ensure body ends in a new line
124
+ data << "\n" if data.length > 0 && data[-1] != "\n"
104
125
 
105
- # Returns the header String with any directives stripped.
106
- def processed_header
107
- lineno = 0
108
- @processed_header ||= header.lines.map { |line|
109
- lineno += 1
110
- # Replace directive line with a clean break
111
- directives.assoc(lineno) ? "\n" : line
112
- }.join.chomp
113
- end
126
+ return data, directives
127
+ end
114
128
 
115
- # Returns the source String with any directives stripped.
116
- def processed_source
117
- @processed_source ||= processed_header + body
118
- end
129
+ # Returns an Array of directive structures. Each structure
130
+ # is an Array with the line number as the first element, the
131
+ # directive name as the second element, followed by any
132
+ # arguments.
133
+ #
134
+ # [[1, "require", "foo"], [2, "require", "bar"]]
135
+ #
136
+ def extract_directives(header)
137
+ processed_header = ""
138
+ directives = []
119
139
 
120
- # Returns an Array of directive structures. Each structure
121
- # is an Array with the line number as the first element, the
122
- # directive name as the second element, followed by any
123
- # arguments.
124
- #
125
- # [[1, "require", "foo"], [2, "require", "bar"]]
126
- #
127
- def directives
128
- @directives ||= header.lines.each_with_index.map { |line, index|
129
- if directive = line[DIRECTIVE_PATTERN, 1]
130
- name, *args = Shellwords.shellwords(directive)
131
- if respond_to?("process_#{name}_directive", true)
132
- [index + 1, name, *args]
140
+ header.lines.each_with_index do |line, index|
141
+ if directive = line[DIRECTIVE_PATTERN, 1]
142
+ name, *args = Shellwords.shellwords(directive)
143
+ if respond_to?("process_#{name}_directive", true)
144
+ directives << [index + 1, name, *args]
145
+ # Replace directive line with a clean break
146
+ line = "\n"
147
+ end
133
148
  end
149
+ processed_header << line
134
150
  end
135
- }.compact
136
- end
137
151
 
138
- protected
139
- attr_reader :included_pathnames
140
- attr_reader :context
152
+ return processed_header.chomp, directives
153
+ end
141
154
 
142
155
  # Gathers comment directives in the source and processes them.
143
156
  # Any directive method matching `process_*_directive` will
@@ -150,7 +163,7 @@ module Sprockets
150
163
  #
151
164
  # class DirectiveProcessor < Sprockets::DirectiveProcessor
152
165
  # def process_require_glob_directive
153
- # Dir["#{pathname.dirname}/#{glob}"].sort.each do |filename|
166
+ # Dir["#{dirname}/#{glob}"].sort.each do |filename|
154
167
  # require(filename)
155
168
  # end
156
169
  # end
@@ -161,29 +174,14 @@ module Sprockets
161
174
  # env.unregister_processor('text/css', Sprockets::DirectiveProcessor)
162
175
  # env.register_processor('text/css', DirectiveProcessor)
163
176
  #
164
- def process_directives
177
+ def process_directives(directives)
165
178
  directives.each do |line_number, name, *args|
166
- context.__LINE__ = line_number
167
- send("process_#{name}_directive", *args)
168
- context.__LINE__ = nil
169
- end
170
- end
171
-
172
- def process_source
173
- unless @has_written_body || processed_header.empty?
174
- @result << processed_header << "\n"
175
- end
176
-
177
- included_pathnames.each do |pathname|
178
- @result << context.evaluate(pathname)
179
- end
180
-
181
- unless @has_written_body
182
- @result << body
183
- end
184
-
185
- if compat? && constants.any?
186
- @result.gsub!(/<%=(.*?)%>/) { constants[$1.strip] }
179
+ begin
180
+ send("process_#{name}_directive", *args)
181
+ rescue Exception => e
182
+ e.set_backtrace(["#{@filename}:#{line_number}"] + e.backtrace)
183
+ raise e
184
+ end
187
185
  end
188
186
  end
189
187
 
@@ -206,22 +204,13 @@ module Sprockets
206
204
  # //= require "./bar"
207
205
  #
208
206
  def process_require_directive(path)
209
- if @compat
210
- if path =~ /<([^>]+)>/
211
- path = $1
212
- else
213
- path = "./#{path}" unless relative?(path)
214
- end
215
- end
216
-
217
- context.require_asset(path)
207
+ @required << resolve(path, accept: @content_type, pipeline: :self)
218
208
  end
219
209
 
220
- # `require_self` causes the body of the current file to be
221
- # inserted before any subsequent `require` or `include`
222
- # directives. Useful in CSS files, where it's common for the
223
- # index file to contain global styles that need to be defined
224
- # before other dependencies are loaded.
210
+ # `require_self` causes the body of the current file to be inserted
211
+ # before any subsequent `require` directives. Useful in CSS files, where
212
+ # it's common for the index file to contain global styles that need to
213
+ # be defined before other dependencies are loaded.
225
214
  #
226
215
  # /*= require "reset"
227
216
  # *= require_self
@@ -229,26 +218,10 @@ module Sprockets
229
218
  # */
230
219
  #
231
220
  def process_require_self_directive
232
- if @has_written_body
221
+ if @required.include?(@uri)
233
222
  raise ArgumentError, "require_self can only be called once per source file"
234
223
  end
235
-
236
- context.require_asset(pathname)
237
- process_source
238
- included_pathnames.clear
239
- @has_written_body = true
240
- end
241
-
242
- # The `include` directive works similar to `require` but
243
- # inserts the contents of the dependency even if it already
244
- # has been required.
245
- #
246
- # //= include "header"
247
- #
248
- def process_include_directive(path)
249
- pathname = context.resolve(path)
250
- context.depend_on_asset(pathname)
251
- included_pathnames << pathname
224
+ @required << @uri
252
225
  end
253
226
 
254
227
  # `require_directory` requires all the files inside a single
@@ -258,27 +231,8 @@ module Sprockets
258
231
  # //= require_directory "./javascripts"
259
232
  #
260
233
  def process_require_directory_directive(path = ".")
261
- if relative?(path)
262
- root = pathname.dirname.join(path).expand_path
263
-
264
- unless (stats = stat(root)) && stats.directory?
265
- raise ArgumentError, "require_directory argument must be a directory"
266
- end
267
-
268
- context.depend_on(root)
269
-
270
- entries(root).each do |pathname|
271
- pathname = root.join(pathname)
272
- if pathname.to_s == self.file
273
- next
274
- elsif context.asset_requirable?(pathname)
275
- context.require_asset(pathname)
276
- end
277
- end
278
- else
279
- # The path must be relative and start with a `./`.
280
- raise ArgumentError, "require_directory argument must be a relative path"
281
- end
234
+ path = expand_relative_dirname(:require_directory, path)
235
+ require_paths(*@environment.stat_directory_with_dependencies(path))
282
236
  end
283
237
 
284
238
  # `require_tree` requires all the nested files in a directory.
@@ -287,28 +241,8 @@ module Sprockets
287
241
  # //= require_tree "./public"
288
242
  #
289
243
  def process_require_tree_directive(path = ".")
290
- if relative?(path)
291
- root = pathname.dirname.join(path).expand_path
292
-
293
- unless (stats = stat(root)) && stats.directory?
294
- raise ArgumentError, "require_tree argument must be a directory"
295
- end
296
-
297
- context.depend_on(root)
298
-
299
- each_entry(root) do |pathname|
300
- if pathname.to_s == self.file
301
- next
302
- elsif stat(pathname).directory?
303
- context.depend_on(pathname)
304
- elsif context.asset_requirable?(pathname)
305
- context.require_asset(pathname)
306
- end
307
- end
308
- else
309
- # The path must be relative and start with a `./`.
310
- raise ArgumentError, "require_tree argument must be a relative path"
311
- end
244
+ path = expand_relative_dirname(:require_tree, path)
245
+ require_paths(*@environment.stat_sorted_tree_with_dependencies(path))
312
246
  end
313
247
 
314
248
  # Allows you to state a dependency on a file without
@@ -324,7 +258,7 @@ module Sprockets
324
258
  # //= depend_on "foo.png"
325
259
  #
326
260
  def process_depend_on_directive(path)
327
- context.depend_on(path)
261
+ resolve(path)
328
262
  end
329
263
 
330
264
  # Allows you to state a dependency on an asset without including
@@ -339,7 +273,7 @@ module Sprockets
339
273
  # //= depend_on_asset "bar.js"
340
274
  #
341
275
  def process_depend_on_asset_directive(path)
342
- context.depend_on_asset(path)
276
+ load(resolve(path))
343
277
  end
344
278
 
345
279
  # Allows dependency to be excluded from the asset bundle.
@@ -351,58 +285,120 @@ module Sprockets
351
285
  # //= stub "jquery"
352
286
  #
353
287
  def process_stub_directive(path)
354
- context.stub_asset(path)
288
+ @stubbed << resolve(path, accept: @content_type, pipeline: :self)
355
289
  end
356
290
 
357
- # Enable Sprockets 1.x compat mode.
291
+ # Declares a linked dependency on the target asset.
292
+ #
293
+ # The `path` must be a valid asset and should not already be part of the
294
+ # bundle. Any linked assets will automatically be compiled along with the
295
+ # current.
296
+ #
297
+ # /*= link "logo.png" */
298
+ #
299
+ def process_link_directive(path)
300
+ @links << load(resolve(path)).uri
301
+ end
302
+
303
+ # `link_directory` links all the files inside a single
304
+ # directory. It's similar to `path/*` since it does not follow
305
+ # nested directories.
306
+ #
307
+ # //= link_directory "./fonts"
358
308
  #
359
- # Makes it possible to use the same JavaScript source
360
- # file in both Sprockets 1 and 2.
309
+ # Use caution when linking against JS or CSS assets. Include an explicit
310
+ # extension or content type in these cases
361
311
  #
362
- # //= compat
312
+ # //= link_directory "./scripts" .js
363
313
  #
364
- def process_compat_directive
365
- @compat = true
314
+ def process_link_directory_directive(path = ".", accept = nil)
315
+ path = expand_relative_dirname(:link_directory, path)
316
+ accept = expand_accept_shorthand(accept)
317
+ link_paths(*@environment.stat_directory_with_dependencies(path), accept)
366
318
  end
367
319
 
368
- # Checks if Sprockets 1.x compat mode enabled
369
- def compat?
370
- @compat
320
+ # `link_tree` links all the nested files in a directory.
321
+ # Its glob equivalent is `path/**/*`.
322
+ #
323
+ # //= link_tree "./images"
324
+ #
325
+ # Use caution when linking against JS or CSS assets. Include an explicit
326
+ # extension or content type in these cases
327
+ #
328
+ # //= link_tree "./styles" .css
329
+ #
330
+ def process_link_tree_directive(path = ".", accept = nil)
331
+ path = expand_relative_dirname(:link_tree, path)
332
+ accept = expand_accept_shorthand(accept)
333
+ link_paths(*@environment.stat_sorted_tree_with_dependencies(path), accept)
371
334
  end
372
335
 
373
- # Sprockets 1.x allowed for constant interpolation if a
374
- # constants.yml was present. This is only available if
375
- # compat mode is on.
376
- def constants
377
- if compat?
378
- pathname = Pathname.new(context.root_path).join("constants.yml")
379
- stat(pathname) ? YAML.load_file(pathname) : {}
336
+ private
337
+ def expand_accept_shorthand(accept)
338
+ if accept.nil?
339
+ nil
340
+ elsif accept.include?("/")
341
+ accept
342
+ elsif accept.start_with?(".")
343
+ @environment.mime_exts[accept]
380
344
  else
381
- {}
345
+ @environment.mime_exts[".#{accept}"]
382
346
  end
383
347
  end
384
348
 
385
- # `provide` is stubbed out for Sprockets 1.x compat.
386
- # Mutating the path when an asset is being built is
387
- # not permitted.
388
- def process_provide_directive(path)
349
+ def require_paths(paths, deps)
350
+ resolve_paths(paths, deps, accept: @content_type, pipeline: :self) do |uri|
351
+ @required << uri
352
+ end
389
353
  end
390
354
 
391
- private
392
- def relative?(path)
393
- path =~ /^\.($|\.?\/)/
355
+ def link_paths(paths, deps, accept)
356
+ resolve_paths(paths, deps, accept: accept) do |uri|
357
+ @links << load(uri).uri
358
+ end
394
359
  end
395
360
 
396
- def stat(path)
397
- context.environment.stat(path)
361
+ def resolve_paths(paths, deps, options = {})
362
+ @dependencies.merge(deps)
363
+ paths.each do |subpath, stat|
364
+ next if subpath == @filename || stat.directory?
365
+ uri, deps = @environment.resolve(subpath, options.merge(compat: false))
366
+ @dependencies.merge(deps)
367
+ yield uri if uri
368
+ end
398
369
  end
399
370
 
400
- def entries(path)
401
- context.environment.entries(path)
371
+ def expand_relative_dirname(directive, path)
372
+ if @environment.relative_path?(path)
373
+ path = File.expand_path(path, @dirname)
374
+ stat = @environment.stat(path)
375
+
376
+ if stat && stat.directory?
377
+ path
378
+ else
379
+ raise ArgumentError, "#{directive} argument must be a directory"
380
+ end
381
+ else
382
+ # The path must be relative and start with a `./`.
383
+ raise ArgumentError, "#{directive} argument must be a relative path"
384
+ end
385
+ end
386
+
387
+ def load(uri)
388
+ asset = @environment.load(uri)
389
+ @dependencies.merge(asset.metadata[:dependencies])
390
+ asset
402
391
  end
403
392
 
404
- def each_entry(root, &block)
405
- context.environment.each_entry(root, &block)
393
+ def resolve(path, options = {})
394
+ # Prevent absolute paths in directives
395
+ if @environment.absolute_path?(path)
396
+ raise FileOutsidePaths, "can't require absolute file: #{path}"
397
+ end
398
+
399
+ uri, deps = @environment.resolve!(path, options.merge(base_path: @dirname))
400
+ @dependencies.merge(deps)
401
+ uri
406
402
  end
407
403
  end
408
404
  end
@@ -0,0 +1,32 @@
1
+ require 'sprockets/autoload'
2
+
3
+ module Sprockets
4
+ # Processor engine class for the Eco compiler. Depends on the `eco` gem.
5
+ #
6
+ # For more infomation see:
7
+ #
8
+ # https://github.com/sstephenson/ruby-eco
9
+ # https://github.com/sstephenson/eco
10
+ #
11
+ module EcoProcessor
12
+ VERSION = '1'
13
+
14
+ def self.cache_key
15
+ @cache_key ||= "#{name}:#{Autoload::Eco::Source::VERSION}:#{VERSION}".freeze
16
+ end
17
+
18
+ # Compile template data with Eco compiler.
19
+ #
20
+ # Returns a JS function definition String. The result should be
21
+ # assigned to a JS variable.
22
+ #
23
+ # # => "function(...) {...}"
24
+ #
25
+ def self.call(input)
26
+ data = input[:data]
27
+ input[:cache].fetch([cache_key, data]) do
28
+ Autoload::Eco.compile(data)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,38 +1,17 @@
1
- require 'tilt'
1
+ require 'sprockets/eco_processor'
2
2
 
3
3
  module Sprockets
4
- # Tilt engine class for the Eco compiler. Depends on the `eco` gem.
5
- #
6
- # For more infomation see:
7
- #
8
- # https://github.com/sstephenson/ruby-eco
9
- # https://github.com/sstephenson/eco
10
- #
11
- class EcoTemplate < Tilt::Template
12
- # Check to see if Eco is loaded
13
- def self.engine_initialized?
14
- defined? ::Eco
15
- end
16
-
17
- # Autoload eco library. If the library isn't loaded, Tilt will produce
18
- # a thread safetly warning. If you intend to use `.eco` files, you
19
- # should explicitly require it.
20
- def initialize_engine
21
- require_template_library 'eco'
22
- end
4
+ # Deprecated
5
+ module EcoTemplate
6
+ VERSION = EcoProcessor::VERSION
23
7
 
24
- def prepare
8
+ def self.cache_key
9
+ EcoProcessor.cache_key
25
10
  end
26
11
 
27
- # Compile template data with Eco compiler.
28
- #
29
- # Returns a JS function definition String. The result should be
30
- # assigned to a JS variable.
31
- #
32
- # # => "function(...) {...}"
33
- #
34
- def evaluate(scope, locals, &block)
35
- Eco.compile(data)
12
+ def self.call(*args)
13
+ Deprecation.new.warn "EcoTemplate is deprecated please use EcoProcessor instead"
14
+ EcoProcessor.call(*args)
36
15
  end
37
16
  end
38
17
  end
@@ -0,0 +1,31 @@
1
+ require 'sprockets/autoload'
2
+
3
+ module Sprockets
4
+ # Processor engine class for the EJS compiler. Depends on the `ejs` gem.
5
+ #
6
+ # For more infomation see:
7
+ #
8
+ # https://github.com/sstephenson/ruby-ejs
9
+ #
10
+ module EjsProcessor
11
+ VERSION = '1'
12
+
13
+ def self.cache_key
14
+ @cache_key ||= "#{name}:#{VERSION}".freeze
15
+ end
16
+
17
+ # Compile template data with EJS compiler.
18
+ #
19
+ # Returns a JS function definition String. The result should be
20
+ # assigned to a JS variable.
21
+ #
22
+ # # => "function(obj){...}"
23
+ #
24
+ def self.call(input)
25
+ data = input[:data]
26
+ input[:cache].fetch([cache_key, data]) do
27
+ Autoload::EJS.compile(data)
28
+ end
29
+ end
30
+ end
31
+ end