sprockets 3.7.5 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +2 -307
  3. data/README.md +21 -35
  4. data/bin/sprockets +11 -8
  5. data/lib/rake/sprocketstask.rb +2 -2
  6. data/lib/sprockets/asset.rb +8 -21
  7. data/lib/sprockets/autoload/babel.rb +7 -0
  8. data/lib/sprockets/autoload/jsminc.rb +7 -0
  9. data/lib/sprockets/autoload/sassc.rb +7 -0
  10. data/lib/sprockets/autoload.rb +3 -0
  11. data/lib/sprockets/babel_processor.rb +58 -0
  12. data/lib/sprockets/base.rb +8 -8
  13. data/lib/sprockets/bower.rb +4 -2
  14. data/lib/sprockets/bundle.rb +1 -1
  15. data/lib/sprockets/cache.rb +2 -4
  16. data/lib/sprockets/closure_compressor.rb +1 -2
  17. data/lib/sprockets/coffee_script_processor.rb +9 -3
  18. data/lib/sprockets/compressing.rb +2 -2
  19. data/lib/sprockets/configuration.rb +1 -7
  20. data/lib/sprockets/context.rb +10 -18
  21. data/lib/sprockets/digest_utils.rb +40 -52
  22. data/lib/sprockets/directive_processor.rb +10 -15
  23. data/lib/sprockets/erb_processor.rb +1 -13
  24. data/lib/sprockets/http_utils.rb +19 -4
  25. data/lib/sprockets/jsminc_compressor.rb +31 -0
  26. data/lib/sprockets/jst_processor.rb +10 -10
  27. data/lib/sprockets/loader.rb +34 -28
  28. data/lib/sprockets/manifest.rb +3 -35
  29. data/lib/sprockets/manifest_utils.rb +0 -2
  30. data/lib/sprockets/mime.rb +7 -62
  31. data/lib/sprockets/path_dependency_utils.rb +2 -11
  32. data/lib/sprockets/path_digest_utils.rb +1 -1
  33. data/lib/sprockets/path_utils.rb +43 -18
  34. data/lib/sprockets/preprocessors/default_source_map.rb +24 -0
  35. data/lib/sprockets/processing.rb +30 -61
  36. data/lib/sprockets/processor_utils.rb +27 -28
  37. data/lib/sprockets/resolve.rb +172 -92
  38. data/lib/sprockets/sass_cache_store.rb +1 -6
  39. data/lib/sprockets/sass_compressor.rb +14 -1
  40. data/lib/sprockets/sass_processor.rb +18 -8
  41. data/lib/sprockets/sassc_compressor.rb +30 -0
  42. data/lib/sprockets/sassc_processor.rb +68 -0
  43. data/lib/sprockets/server.rb +11 -22
  44. data/lib/sprockets/source_map_comment_processor.rb +29 -0
  45. data/lib/sprockets/source_map_processor.rb +40 -0
  46. data/lib/sprockets/source_map_utils.rb +345 -0
  47. data/lib/sprockets/transformers.rb +62 -35
  48. data/lib/sprockets/uglifier_compressor.rb +12 -5
  49. data/lib/sprockets/unloaded_asset.rb +12 -11
  50. data/lib/sprockets/uri_tar.rb +4 -2
  51. data/lib/sprockets/uri_utils.rb +9 -14
  52. data/lib/sprockets/utils.rb +30 -79
  53. data/lib/sprockets/version.rb +1 -1
  54. data/lib/sprockets.rb +80 -35
  55. metadata +70 -41
  56. data/LICENSE +0 -21
  57. data/lib/sprockets/coffee_script_template.rb +0 -17
  58. data/lib/sprockets/deprecation.rb +0 -90
  59. data/lib/sprockets/eco_template.rb +0 -17
  60. data/lib/sprockets/ejs_template.rb +0 -17
  61. data/lib/sprockets/engines.rb +0 -92
  62. data/lib/sprockets/erb_template.rb +0 -11
  63. data/lib/sprockets/legacy.rb +0 -322
  64. data/lib/sprockets/legacy_proc_processor.rb +0 -35
  65. data/lib/sprockets/legacy_tilt_processor.rb +0 -29
  66. data/lib/sprockets/sass_template.rb +0 -19
@@ -0,0 +1,58 @@
1
+ require 'sprockets/autoload'
2
+ require 'sprockets/path_utils'
3
+ require 'sprockets/source_map_utils'
4
+ require 'json'
5
+
6
+ module Sprockets
7
+ class BabelProcessor
8
+ VERSION = '1'
9
+
10
+ def self.instance
11
+ @instance ||= new
12
+ end
13
+
14
+ def self.call(input)
15
+ instance.call(input)
16
+ end
17
+
18
+ def initialize(options = {})
19
+ @options = options.merge({
20
+ 'blacklist' => (options['blacklist'] || []) + ['useStrict'],
21
+ 'sourceMap' => true
22
+ }).freeze
23
+
24
+ @cache_key = [
25
+ self.class.name,
26
+ Autoload::Babel::Transpiler::VERSION,
27
+ Autoload::Babel::Source::VERSION,
28
+ VERSION,
29
+ @options
30
+ ].freeze
31
+ end
32
+
33
+ def call(input)
34
+ data = input[:data]
35
+
36
+ result = input[:cache].fetch(@cache_key + [input[:filename]] + [data]) do
37
+ opts = {
38
+ 'sourceRoot' => input[:load_path],
39
+ 'moduleRoot' => nil,
40
+ 'filename' => input[:filename],
41
+ 'filenameRelative' => PathUtils.split_subpath(input[:load_path], input[:filename])
42
+ }.merge(@options)
43
+
44
+ if opts['moduleIds'] && opts['moduleRoot']
45
+ opts['moduleId'] ||= File.join(opts['moduleRoot'], input[:name])
46
+ elsif opts['moduleIds']
47
+ opts['moduleId'] ||= input[:name]
48
+ end
49
+ Autoload::Babel::Transpiler.transform(data, opts)
50
+ end
51
+
52
+ map = SourceMapUtils.decode_json_source_map(JSON.generate(result['map']))
53
+ map = SourceMapUtils.combine_source_maps(input[:metadata][:map], map["mappings"])
54
+
55
+ { data: result['code'], map: map }
56
+ end
57
+ end
58
+ end
@@ -5,18 +5,18 @@ require 'sprockets/configuration'
5
5
  require 'sprockets/digest_utils'
6
6
  require 'sprockets/errors'
7
7
  require 'sprockets/loader'
8
- require 'sprockets/path_digest_utils'
9
8
  require 'sprockets/path_dependency_utils'
9
+ require 'sprockets/path_digest_utils'
10
10
  require 'sprockets/path_utils'
11
11
  require 'sprockets/resolve'
12
12
  require 'sprockets/server'
13
- require 'sprockets/loader'
13
+ require 'sprockets/source_map_utils'
14
14
  require 'sprockets/uri_tar'
15
15
 
16
16
  module Sprockets
17
17
  # `Base` class for `Environment` and `Cached`.
18
18
  class Base
19
- include PathUtils, PathDependencyUtils, PathDigestUtils, DigestUtils
19
+ include PathUtils, PathDependencyUtils, PathDigestUtils, DigestUtils, SourceMapUtils
20
20
  include Configuration
21
21
  include Server
22
22
  include Resolve, Loader
@@ -60,17 +60,17 @@ module Sprockets
60
60
  end
61
61
 
62
62
  # Find asset by logical path or expanded path.
63
- def find_asset(path, options = {})
64
- uri, _ = resolve(path, options.merge(compat: false))
63
+ def find_asset(*args)
64
+ uri, _ = resolve(*args)
65
65
  if uri
66
66
  load(uri)
67
67
  end
68
68
  end
69
69
 
70
- def find_all_linked_assets(path, options = {})
71
- return to_enum(__method__, path, options) unless block_given?
70
+ def find_all_linked_assets(*args)
71
+ return to_enum(__method__, *args) unless block_given?
72
72
 
73
- asset = find_asset(path, options)
73
+ asset = find_asset(*args)
74
74
  return unless asset
75
75
 
76
76
  yield asset
@@ -17,7 +17,7 @@ module Sprockets
17
17
  candidates, deps = super
18
18
 
19
19
  # bower.json can only be nested one level deep
20
- if !logical_path.index('/')
20
+ if !logical_path.index('/'.freeze)
21
21
  dirname = File.join(load_path, logical_path)
22
22
 
23
23
  if directory?(dirname)
@@ -27,7 +27,9 @@ module Sprockets
27
27
  if filename
28
28
  deps << build_file_digest_uri(filename)
29
29
  read_bower_main(dirname, filename) do |path|
30
- candidates << path
30
+ if file?(path)
31
+ candidates << path
32
+ end
31
33
  end
32
34
  end
33
35
  end
@@ -17,7 +17,7 @@ module Sprockets
17
17
  type = input[:content_type]
18
18
  dependencies = Set.new(input[:metadata][:dependencies])
19
19
 
20
- processed_uri, deps = env.resolve(input[:filename], accept: type, pipeline: :self, compat: false)
20
+ processed_uri, deps = env.resolve(input[:filename], accept: type, pipeline: :self)
21
21
  dependencies.merge(deps)
22
22
 
23
23
  find_required = proc { |uri| env.load(uri).metadata[:required] }
@@ -44,7 +44,7 @@ module Sprockets
44
44
  # Internal: Cache key version for this class. Rarely should have to change
45
45
  # unless the cache format radically changes. Will be bump on major version
46
46
  # releases though.
47
- VERSION = '3.0'
47
+ VERSION = '4.0'
48
48
 
49
49
  def self.default_logger
50
50
  logger = Logger.new($stderr)
@@ -153,9 +153,7 @@ module Sprockets
153
153
  #
154
154
  # Returns a String with a length less than 250 characters.
155
155
  def expand_key(key)
156
- digest_key = DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))
157
- namespace = digest_key[0, 2]
158
- "sprockets/v#{VERSION}/#{namespace}/#{digest_key}"
156
+ "sprockets/v#{VERSION}/#{DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))}"
159
157
  end
160
158
 
161
159
  PEEK_SIZE = 100
@@ -35,12 +35,11 @@ module Sprockets
35
35
  attr_reader :cache_key
36
36
 
37
37
  def initialize(options = {})
38
- @options = options
38
+ @compiler = Autoload::Closure::Compiler.new(options)
39
39
  @cache_key = "#{self.class.name}:#{Autoload::Closure::VERSION}:#{Autoload::Closure::COMPILER_VERSION}:#{VERSION}:#{DigestUtils.digest(options)}".freeze
40
40
  end
41
41
 
42
42
  def call(input)
43
- @compiler ||= Autoload::Closure::Compiler.new(@options)
44
43
  @compiler.compile(input[:data])
45
44
  end
46
45
  end
@@ -1,4 +1,5 @@
1
1
  require 'sprockets/autoload'
2
+ require 'sprockets/source_map_utils'
2
3
 
3
4
  module Sprockets
4
5
  # Processor engine class for the CoffeeScript compiler.
@@ -9,7 +10,7 @@ module Sprockets
9
10
  # https://github.com/josh/ruby-coffee-script
10
11
  #
11
12
  module CoffeeScriptProcessor
12
- VERSION = '1'
13
+ VERSION = '2'
13
14
 
14
15
  def self.cache_key
15
16
  @cache_key ||= "#{name}:#{Autoload::CoffeeScript::Source.version}:#{VERSION}".freeze
@@ -17,9 +18,14 @@ module Sprockets
17
18
 
18
19
  def self.call(input)
19
20
  data = input[:data]
20
- input[:cache].fetch([self.cache_key, data]) do
21
- Autoload::CoffeeScript.compile(data)
21
+
22
+ js, map = input[:cache].fetch([self.cache_key, data]) do
23
+ result = Autoload::CoffeeScript.compile(data, sourceMap: true, sourceFiles: [input[:source_path]])
24
+ [result['js'], SourceMapUtils.decode_json_source_map(result['v3SourceMap'])['mappings']]
22
25
  end
26
+
27
+ map = SourceMapUtils.combine_source_maps(input[:metadata][:map], map)
28
+ { data: js, map: map }
23
29
  end
24
30
  end
25
31
  end
@@ -35,7 +35,7 @@ module Sprockets
35
35
  if compressor.is_a?(Symbol)
36
36
  @css_compressor = klass = config[:compressors]['text/css'][compressor] || raise(Error, "unknown compressor: #{compressor}")
37
37
  elsif compressor.respond_to?(:compress)
38
- klass = LegacyProcProcessor.new(:css_compressor, proc { |context, data| compressor.compress(data) })
38
+ klass = proc { |input| compressor.compress(input[:data]) }
39
39
  @css_compressor = :css_compressor
40
40
  else
41
41
  @css_compressor = klass = compressor
@@ -62,7 +62,7 @@ module Sprockets
62
62
  if compressor.is_a?(Symbol)
63
63
  @js_compressor = klass = config[:compressors]['application/javascript'][compressor] || raise(Error, "unknown compressor: #{compressor}")
64
64
  elsif compressor.respond_to?(:compress)
65
- klass = LegacyProcProcessor.new(:js_compressor, proc { |context, data| compressor.compress(data) })
65
+ klass = proc { |input| compressor.compress(input[:data]) }
66
66
  @js_compressor = :js_compressor
67
67
  else
68
68
  @js_compressor = klass = compressor
@@ -1,6 +1,5 @@
1
1
  require 'sprockets/compressing'
2
2
  require 'sprockets/dependencies'
3
- require 'sprockets/engines'
4
3
  require 'sprockets/mime'
5
4
  require 'sprockets/paths'
6
5
  require 'sprockets/processing'
@@ -9,19 +8,16 @@ require 'sprockets/utils'
9
8
 
10
9
  module Sprockets
11
10
  module Configuration
12
- include Paths, Mime, Engines, Transformers, Processing, Compressing, Dependencies, Utils
11
+ include Paths, Mime, Transformers, Processing, Compressing, Dependencies, Utils
13
12
 
14
13
  def initialize_configuration(parent)
15
14
  @config = parent.config
16
- @computed_config = parent.computed_config
17
15
  @logger = parent.logger
18
16
  @context_class = Class.new(parent.context_class)
19
17
  end
20
18
 
21
19
  attr_reader :config
22
20
 
23
- attr_accessor :computed_config
24
-
25
21
  def config=(config)
26
22
  raise TypeError, "can't assign mutable config" unless config.frozen?
27
23
  @config = config
@@ -69,8 +65,6 @@ module Sprockets
69
65
  self.config = config.merge(digest_class: klass).freeze
70
66
  end
71
67
 
72
- # Deprecated: Get `Context` class.
73
- #
74
68
  # This class maybe mutated and mixed in with custom helpers.
75
69
  #
76
70
  # environment.context_class.instance_eval do
@@ -1,10 +1,8 @@
1
- require 'pathname'
2
1
  require 'rack/utils'
3
2
  require 'set'
4
3
  require 'sprockets/errors'
5
4
 
6
5
  module Sprockets
7
- # Deprecated: `Context` provides helper methods to all processors.
8
6
  # They are typically accessed by ERB templates. You can mix in custom helpers
9
7
  # by injecting them into `Environment#context_class`. Do not mix them into
10
8
  # `Context` directly.
@@ -19,10 +17,7 @@ module Sprockets
19
17
  # The `Context` also collects dependencies declared by
20
18
  # assets. See `DirectiveProcessor` for an example of this.
21
19
  class Context
22
- attr_reader :environment, :filename, :pathname
23
-
24
- # Deprecated
25
- attr_accessor :__LINE__
20
+ attr_reader :environment, :filename
26
21
 
27
22
  def initialize(input)
28
23
  @environment = input[:environment]
@@ -31,7 +26,6 @@ module Sprockets
31
26
  @logical_path = input[:name]
32
27
  @filename = input[:filename]
33
28
  @dirname = File.dirname(@filename)
34
- @pathname = Pathname.new(@filename)
35
29
  @content_type = input[:content_type]
36
30
 
37
31
  @required = Set.new(@metadata[:required])
@@ -79,13 +73,13 @@ module Sprockets
79
73
  # resolve("./bar.js")
80
74
  # # => "file:///path/to/app/javascripts/bar.js?type=application/javascript"
81
75
  #
82
- # path - String logical or absolute path
83
- # options
84
- # accept - String content accept type
76
+ # path - String logical or absolute path
77
+ # accept - String content accept type
85
78
  #
86
79
  # Returns an Asset URI String.
87
- def resolve(path, options = {})
88
- uri, deps = environment.resolve!(path, options.merge(base_path: @dirname))
80
+ def resolve(path, **kargs)
81
+ kargs[:base_path] = @dirname
82
+ uri, deps = environment.resolve!(path, **kargs)
89
83
  @dependencies.merge(deps)
90
84
  uri
91
85
  end
@@ -108,12 +102,10 @@ module Sprockets
108
102
  # the dependency file with invalidate the cache of the
109
103
  # source file.
110
104
  def depend_on(path)
111
- path = path.to_s if path.is_a?(Pathname)
112
-
113
105
  if environment.absolute_path?(path) && environment.stat(path)
114
106
  @dependencies << environment.build_file_digest_uri(path)
115
107
  else
116
- resolve(path, compat: false)
108
+ resolve(path)
117
109
  end
118
110
  nil
119
111
  end
@@ -126,7 +118,7 @@ module Sprockets
126
118
  # file. Unlike `depend_on`, this will include recursively include
127
119
  # the target asset's dependencies.
128
120
  def depend_on_asset(path)
129
- load(resolve(path, compat: false))
121
+ load(resolve(path))
130
122
  end
131
123
 
132
124
  # `require_asset` declares `path` as a dependency of the file. The
@@ -139,7 +131,7 @@ module Sprockets
139
131
  # <%= require_asset "#{framework}.js" %>
140
132
  #
141
133
  def require_asset(path)
142
- @required << resolve(path, accept: @content_type, pipeline: :self, compat: false)
134
+ @required << resolve(path, accept: @content_type, pipeline: :self)
143
135
  nil
144
136
  end
145
137
 
@@ -147,7 +139,7 @@ module Sprockets
147
139
  # `path` must be an asset which may or may not already be included
148
140
  # in the bundle.
149
141
  def stub_asset(path)
150
- @stubbed << resolve(path, accept: @content_type, pipeline: :self, compat: false)
142
+ @stubbed << resolve(path, accept: @content_type, pipeline: :self)
151
143
  nil
152
144
  end
153
145
 
@@ -34,56 +34,6 @@ module Sprockets
34
34
  DIGEST_SIZES[bytes.bytesize]
35
35
  end
36
36
 
37
- ADD_VALUE_TO_DIGEST = {
38
- String => ->(val, digest) { digest << val },
39
- FalseClass => ->(val, digest) { digest << 'FalseClass'.freeze },
40
- TrueClass => ->(val, digest) { digest << 'TrueClass'.freeze },
41
- NilClass => ->(val, digest) { digest << 'NilClass'.freeze },
42
-
43
- Symbol => ->(val, digest) {
44
- digest << 'Symbol'.freeze
45
- digest << val.to_s
46
- },
47
- Integer => ->(val, digest) {
48
- digest << 'Integer'.freeze
49
- digest << val.to_s
50
- },
51
- Array => ->(val, digest) {
52
- digest << 'Array'.freeze
53
- val.each do |element|
54
- ADD_VALUE_TO_DIGEST[element.class].call(element, digest)
55
- end
56
- },
57
- Hash => ->(val, digest) {
58
- digest << 'Hash'.freeze
59
- val.sort.each do |array|
60
- ADD_VALUE_TO_DIGEST[Array].call(array, digest)
61
- end
62
- },
63
- Set => ->(val, digest) {
64
- digest << 'Set'.freeze
65
- ADD_VALUE_TO_DIGEST[Array].call(val.to_a, digest)
66
- },
67
- Encoding => ->(val, digest) {
68
- digest << 'Encoding'.freeze
69
- digest << val.name
70
- },
71
- }
72
- if 0.class != Integer # Ruby < 2.4
73
- ADD_VALUE_TO_DIGEST[Fixnum] = ->(val, digest) {
74
- digest << 'Integer'.freeze
75
- digest << val.to_s
76
- }
77
- ADD_VALUE_TO_DIGEST[Bignum] = ->(val, digest) {
78
- digest << 'Integer'.freeze
79
- digest << val.to_s
80
- }
81
- end
82
- ADD_VALUE_TO_DIGEST.default_proc = ->(_, val) {
83
- raise TypeError, "couldn't digest #{ val }"
84
- }
85
- private_constant :ADD_VALUE_TO_DIGEST
86
-
87
37
  # Internal: Generate a hexdigest for a nested JSON serializable object.
88
38
  #
89
39
  # This is used for generating cache keys, so its pretty important its
@@ -94,8 +44,46 @@ module Sprockets
94
44
  # Returns a String digest of the object.
95
45
  def digest(obj)
96
46
  digest = digest_class.new
47
+ queue = [obj]
48
+
49
+ while queue.length > 0
50
+ obj = queue.shift
51
+ klass = obj.class
52
+
53
+ if klass == String
54
+ digest << obj
55
+ elsif klass == Symbol
56
+ digest << 'Symbol'
57
+ digest << obj.to_s
58
+ elsif klass == Fixnum
59
+ digest << 'Fixnum'
60
+ digest << obj.to_s
61
+ elsif klass == Bignum
62
+ digest << 'Bignum'
63
+ digest << obj.to_s
64
+ elsif klass == TrueClass
65
+ digest << 'TrueClass'
66
+ elsif klass == FalseClass
67
+ digest << 'FalseClass'
68
+ elsif klass == NilClass
69
+ digest << 'NilClass'.freeze
70
+ elsif klass == Array
71
+ digest << 'Array'
72
+ queue.concat(obj)
73
+ elsif klass == Hash
74
+ digest << 'Hash'
75
+ queue.concat(obj.sort)
76
+ elsif klass == Set
77
+ digest << 'Set'
78
+ queue.concat(obj.to_a)
79
+ elsif klass == Encoding
80
+ digest << 'Encoding'
81
+ digest << obj.name
82
+ else
83
+ raise TypeError, "couldn't digest #{klass}"
84
+ end
85
+ end
97
86
 
98
- ADD_VALUE_TO_DIGEST[obj.class].call(obj, digest)
99
87
  digest.digest
100
88
  end
101
89
 
@@ -105,7 +93,7 @@ module Sprockets
105
93
  #
106
94
  # Returns hex String.
107
95
  def pack_hexdigest(bin)
108
- bin.unpack('H*').first
96
+ bin.unpack('H*'.freeze).first
109
97
  end
110
98
 
111
99
  # Internal: Unpack a hex encoded digest string into binary bytes.
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: false
2
-
3
1
  require 'set'
4
2
  require 'shellwords'
5
3
 
@@ -36,8 +34,6 @@ module Sprockets
36
34
  # env.register_processor('text/css', MyProcessor)
37
35
  #
38
36
  class DirectiveProcessor
39
- VERSION = '1'
40
-
41
37
  # Directives are denoted by a `=` followed by the name, then
42
38
  # argument list.
43
39
  #
@@ -52,18 +48,16 @@ module Sprockets
52
48
  /x
53
49
 
54
50
  def self.instance
55
- @instance ||= new(
56
- # Deprecated: Default to C and Ruby comment styles
57
- comments: ["//", ["/*", "*/"]] + ["#", ["###", "###"]]
58
- )
51
+ # Default to C omment styles
52
+ @instance ||= new(comments: ["//", ["/*", "*/"]])
59
53
  end
60
54
 
61
55
  def self.call(input)
62
56
  instance.call(input)
63
57
  end
64
58
 
65
- def initialize(options = {})
66
- @header_pattern = compile_header_pattern(Array(options[:comments]))
59
+ def initialize(comments: [])
60
+ @header_pattern = compile_header_pattern(Array(comments))
67
61
  end
68
62
 
69
63
  def call(input)
@@ -164,7 +158,7 @@ module Sprockets
164
158
  # `process_require_glob_directive`.
165
159
  #
166
160
  # class DirectiveProcessor < Sprockets::DirectiveProcessor
167
- # def process_require_glob_directive
161
+ # def process_require_glob_directive(glob)
168
162
  # Dir["#{dirname}/#{glob}"].sort.each do |filename|
169
163
  # require(filename)
170
164
  # end
@@ -360,11 +354,11 @@ module Sprockets
360
354
  end
361
355
  end
362
356
 
363
- def resolve_paths(paths, deps, options = {})
357
+ def resolve_paths(paths, deps, **kargs)
364
358
  @dependencies.merge(deps)
365
359
  paths.each do |subpath, stat|
366
360
  next if subpath == @filename || stat.directory?
367
- uri, deps = @environment.resolve(subpath, options.merge(compat: false))
361
+ uri, deps = @environment.resolve(subpath, **kargs)
368
362
  @dependencies.merge(deps)
369
363
  yield uri if uri
370
364
  end
@@ -392,13 +386,14 @@ module Sprockets
392
386
  asset
393
387
  end
394
388
 
395
- def resolve(path, options = {})
389
+ def resolve(path, **kargs)
396
390
  # Prevent absolute paths in directives
397
391
  if @environment.absolute_path?(path)
398
392
  raise FileOutsidePaths, "can't require absolute file: #{path}"
399
393
  end
400
394
 
401
- uri, deps = @environment.resolve!(path, options.merge(base_path: @dirname))
395
+ kargs[:base_path] = @dirname
396
+ uri, deps = @environment.resolve!(path, **kargs)
402
397
  @dependencies.merge(deps)
403
398
  uri
404
399
  end
@@ -18,12 +18,7 @@ module Sprockets
18
18
  end
19
19
 
20
20
  def call(input)
21
- if keyword_constructor? # Ruby 2.6+
22
- engine = ::ERB.new(input[:data], trim_mode: '<>')
23
- else
24
- engine = ::ERB.new(input[:data], nil, '<>')
25
- end
26
-
21
+ engine = ::ERB.new(input[:data], nil, '<>')
27
22
  context = input[:environment].context_class.new(input)
28
23
  klass = (class << context; self; end)
29
24
  klass.class_eval(&@block) if @block
@@ -31,12 +26,5 @@ module Sprockets
31
26
  data = context._evaluate_template
32
27
  context.metadata.merge(data: data)
33
28
  end
34
-
35
- private
36
-
37
- def keyword_constructor?
38
- return @keyword_constructor if defined? @keyword_constructor
39
- @keyword_constructor = ::ERB.instance_method(:initialize).parameters.include?([:key, :trim_mode])
40
- end
41
29
  end
42
30
  end
@@ -13,9 +13,9 @@ module Sprockets
13
13
  # Returns true if the given value is a mime match for the given mime match
14
14
  # specification, false otherwise.
15
15
  def match_mime_type?(value, matcher)
16
- v1, v2 = value.split('/', 2)
17
- m1, m2 = matcher.split('/', 2)
18
- (m1 == '*' || v1 == m1) && (m2.nil? || m2 == '*' || m2 == v2)
16
+ v1, v2 = value.split('/'.freeze, 2)
17
+ m1, m2 = matcher.split('/'.freeze, 2)
18
+ (m1 == '*'.freeze || v1 == m1) && (m2.nil? || m2 == '*'.freeze || m2 == v2)
19
19
  end
20
20
 
21
21
  # Public: Return values from Hash where the key matches the mime type.
@@ -36,7 +36,22 @@ module Sprockets
36
36
 
37
37
  # Internal: Parse Accept header quality values.
38
38
  #
39
- # Adapted from Rack::Utils#q_values.
39
+ # values - String e.g. "application/javascript"
40
+ #
41
+ # Adapted from Rack::Utils#q_values. Quality values are
42
+ # described in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
43
+ #
44
+ # parse_q_values("application/javascript")
45
+ # # => [["application/javascript", 1.0]]
46
+ #
47
+ # parse_q_values("*/*")
48
+ # # => [["*/*", 1.0]]
49
+ #
50
+ # parse_q_values("text/plain; q=0.5, image/*")
51
+ # # => [["text/plain", 0.5], ["image/*", 1.0]]
52
+ #
53
+ # parse_q_values("application/javascript, text/css")
54
+ # # => [["application/javascript", 1.0], ["text/css", 1.0]]
40
55
  #
41
56
  # Returns an Array of [String, Float].
42
57
  def parse_q_values(values)
@@ -0,0 +1,31 @@
1
+ require 'sprockets/autoload'
2
+ require 'sprockets/digest_utils'
3
+
4
+ module Sprockets
5
+ class JSMincCompressor
6
+ VERSION = '1'
7
+
8
+ def self.instance
9
+ @instance ||= new
10
+ end
11
+
12
+ def self.call(input)
13
+ instance.call(input)
14
+ end
15
+
16
+ def self.cache_key
17
+ instance.cache_key
18
+ end
19
+
20
+ attr_reader :cache_key
21
+
22
+ def initialize(options = {})
23
+ @compressor_class = Autoload::JSMinC
24
+ @cache_key = "#{self.class.name}:#{Autoload::JSMinC::VERSION}:#{VERSION}:#{DigestUtils.digest(options)}".freeze
25
+ end
26
+
27
+ def call(input)
28
+ @compressor_class.minify(input[:data])
29
+ end
30
+ end
31
+ end
@@ -1,21 +1,21 @@
1
1
  module Sprockets
2
- # Public: .jst engine.
2
+ # Public: JST transformer.
3
3
  #
4
4
  # Exports server side compiled templates to an object.
5
5
  #
6
- # Name your template "users/show.jst.ejs", "users/new.jst.eco", etc.
6
+ # Name your template "users/show.ejs", "users/new.eco", etc.
7
7
  #
8
8
  # To accept the default options
9
9
  #
10
- # environment.register_engine '.jst',
11
- # JstProcessor,
12
- # mime_type: 'application/javascript'
10
+ # environment.register_transformer
11
+ # 'application/javascript+function',
12
+ # 'application/javascript', JstProcessor
13
13
  #
14
14
  # Change the default namespace.
15
15
  #
16
- # environment.register_engine '.jst',
17
- # JstProcessor.new(namespace: 'App.templates'),
18
- # mime_type: 'application/javascript'
16
+ # environment.register_transformer
17
+ # 'application/javascript+function',
18
+ # 'application/javascript', JstProcessor.new(namespace: 'App.templates')
19
19
  #
20
20
  class JstProcessor
21
21
  def self.default_namespace
@@ -33,8 +33,8 @@ module Sprockets
33
33
  instance.call(input)
34
34
  end
35
35
 
36
- def initialize(options = {})
37
- @namespace = options[:namespace] || self.class.default_namespace
36
+ def initialize(namespace: self.class.default_namespace)
37
+ @namespace = namespace
38
38
  end
39
39
 
40
40
  def call(input)