sprockets 3.7.5 → 4.0.0.beta1
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +2 -307
- data/README.md +21 -35
- data/bin/sprockets +11 -8
- data/lib/rake/sprocketstask.rb +2 -2
- data/lib/sprockets/asset.rb +8 -21
- data/lib/sprockets/autoload/babel.rb +7 -0
- data/lib/sprockets/autoload/jsminc.rb +7 -0
- data/lib/sprockets/autoload/sassc.rb +7 -0
- data/lib/sprockets/autoload.rb +3 -0
- data/lib/sprockets/babel_processor.rb +58 -0
- data/lib/sprockets/base.rb +8 -8
- data/lib/sprockets/bower.rb +4 -2
- data/lib/sprockets/bundle.rb +1 -1
- data/lib/sprockets/cache.rb +2 -4
- data/lib/sprockets/closure_compressor.rb +1 -2
- data/lib/sprockets/coffee_script_processor.rb +9 -3
- data/lib/sprockets/compressing.rb +2 -2
- data/lib/sprockets/configuration.rb +1 -7
- data/lib/sprockets/context.rb +10 -18
- data/lib/sprockets/digest_utils.rb +40 -52
- data/lib/sprockets/directive_processor.rb +10 -15
- data/lib/sprockets/erb_processor.rb +1 -13
- data/lib/sprockets/http_utils.rb +19 -4
- data/lib/sprockets/jsminc_compressor.rb +31 -0
- data/lib/sprockets/jst_processor.rb +10 -10
- data/lib/sprockets/loader.rb +34 -28
- data/lib/sprockets/manifest.rb +3 -35
- data/lib/sprockets/manifest_utils.rb +0 -2
- data/lib/sprockets/mime.rb +7 -62
- data/lib/sprockets/path_dependency_utils.rb +2 -11
- data/lib/sprockets/path_digest_utils.rb +1 -1
- data/lib/sprockets/path_utils.rb +43 -18
- data/lib/sprockets/preprocessors/default_source_map.rb +24 -0
- data/lib/sprockets/processing.rb +30 -61
- data/lib/sprockets/processor_utils.rb +27 -28
- data/lib/sprockets/resolve.rb +172 -92
- data/lib/sprockets/sass_cache_store.rb +1 -6
- data/lib/sprockets/sass_compressor.rb +14 -1
- data/lib/sprockets/sass_processor.rb +18 -8
- data/lib/sprockets/sassc_compressor.rb +30 -0
- data/lib/sprockets/sassc_processor.rb +68 -0
- data/lib/sprockets/server.rb +11 -22
- data/lib/sprockets/source_map_comment_processor.rb +29 -0
- data/lib/sprockets/source_map_processor.rb +40 -0
- data/lib/sprockets/source_map_utils.rb +345 -0
- data/lib/sprockets/transformers.rb +62 -35
- data/lib/sprockets/uglifier_compressor.rb +12 -5
- data/lib/sprockets/unloaded_asset.rb +12 -11
- data/lib/sprockets/uri_tar.rb +4 -2
- data/lib/sprockets/uri_utils.rb +9 -14
- data/lib/sprockets/utils.rb +30 -79
- data/lib/sprockets/version.rb +1 -1
- data/lib/sprockets.rb +80 -35
- metadata +70 -41
- data/LICENSE +0 -21
- data/lib/sprockets/coffee_script_template.rb +0 -17
- data/lib/sprockets/deprecation.rb +0 -90
- data/lib/sprockets/eco_template.rb +0 -17
- data/lib/sprockets/ejs_template.rb +0 -17
- data/lib/sprockets/engines.rb +0 -92
- data/lib/sprockets/erb_template.rb +0 -11
- data/lib/sprockets/legacy.rb +0 -322
- data/lib/sprockets/legacy_proc_processor.rb +0 -35
- data/lib/sprockets/legacy_tilt_processor.rb +0 -29
- data/lib/sprockets/sass_template.rb +0 -19
@@ -18,6 +18,8 @@ module Sprockets
|
|
18
18
|
config[:transformers]
|
19
19
|
end
|
20
20
|
|
21
|
+
Transformer = Struct.new :from, :to, :proc
|
22
|
+
|
21
23
|
# Public: Register a transformer from and to a mime type.
|
22
24
|
#
|
23
25
|
# from - String mime type
|
@@ -33,10 +35,30 @@ module Sprockets
|
|
33
35
|
#
|
34
36
|
# Returns nothing.
|
35
37
|
def register_transformer(from, to, proc)
|
36
|
-
self.config = hash_reassoc(config, :registered_transformers
|
37
|
-
transformers.
|
38
|
+
self.config = hash_reassoc(config, :registered_transformers) do |transformers|
|
39
|
+
transformers << Transformer.new(from, to, proc)
|
40
|
+
end
|
41
|
+
compute_transformers!(self.config[:registered_transformers])
|
42
|
+
end
|
43
|
+
|
44
|
+
# Internal: Register transformer for existing type adding a suffix.
|
45
|
+
#
|
46
|
+
# types - Array of existing mime type Strings
|
47
|
+
# type_format - String suffix formatting string
|
48
|
+
# extname - String extension to append
|
49
|
+
# processor - Callable block that accepts an input Hash.
|
50
|
+
#
|
51
|
+
# Returns nothing.
|
52
|
+
def register_transformer_suffix(types, type_format, extname, processor)
|
53
|
+
Array(types).each do |type|
|
54
|
+
extensions, charset = mime_types[type].values_at(:extensions, :charset)
|
55
|
+
parts = type.split('/')
|
56
|
+
suffix_type = type_format.sub('\1', parts[0]).sub('\2', parts[1])
|
57
|
+
extensions = extensions.map { |ext| "#{ext}#{extname}" }
|
58
|
+
|
59
|
+
register_mime_type(suffix_type, extensions: extensions, charset: charset)
|
60
|
+
register_transformer(suffix_type, type, processor)
|
38
61
|
end
|
39
|
-
compute_transformers!
|
40
62
|
end
|
41
63
|
|
42
64
|
# Internal: Resolve target mime type that the source type should be
|
@@ -89,53 +111,58 @@ module Sprockets
|
|
89
111
|
# types - Array of mime type steps
|
90
112
|
#
|
91
113
|
# Returns Processor.
|
92
|
-
def compose_transformers(transformers, types)
|
114
|
+
def compose_transformers(transformers, types, preprocessors, postprocessors)
|
93
115
|
if types.length < 2
|
94
116
|
raise ArgumentError, "too few transform types: #{types.inspect}"
|
95
117
|
end
|
96
118
|
|
97
|
-
|
98
|
-
processors = []
|
99
|
-
|
100
|
-
loop do
|
101
|
-
src = types[i]
|
102
|
-
dst = types[i+1]
|
103
|
-
break unless src && dst
|
104
|
-
|
119
|
+
processors = types.each_cons(2).map { |src, dst|
|
105
120
|
unless processor = transformers[src][dst]
|
106
121
|
raise ArgumentError, "missing transformer for type: #{src} to #{dst}"
|
107
122
|
end
|
108
|
-
|
109
|
-
|
110
|
-
processors.concat config[:preprocessors][dst]
|
123
|
+
processor
|
124
|
+
}
|
111
125
|
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
if processors.size > 1
|
116
|
-
compose_processors(*processors.reverse)
|
117
|
-
elsif processors.size == 1
|
118
|
-
processors.first
|
119
|
-
end
|
126
|
+
compose_transformer_list processors, preprocessors, postprocessors
|
120
127
|
end
|
121
128
|
|
122
129
|
private
|
123
|
-
def
|
124
|
-
|
125
|
-
|
130
|
+
def compose_transformer_list(transformers, preprocessors, postprocessors)
|
131
|
+
processors = []
|
132
|
+
|
133
|
+
transformers.each do |processor|
|
134
|
+
processors.concat postprocessors[processor.from]
|
135
|
+
processors << processor.proc
|
136
|
+
processors.concat preprocessors[processor.to]
|
137
|
+
end
|
138
|
+
|
139
|
+
if processors.size > 1
|
140
|
+
compose_processors(*processors.reverse)
|
141
|
+
elsif processors.size == 1
|
142
|
+
processors.first
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def compute_transformers!(registered_transformers)
|
147
|
+
preprocessors = self.config[:preprocessors]
|
148
|
+
postprocessors = self.config[:postprocessors]
|
149
|
+
transformers = Hash.new { {} }
|
126
150
|
inverted_transformers = Hash.new { Set.new }
|
151
|
+
incoming_edges = registered_transformers.group_by(&:from)
|
152
|
+
|
153
|
+
registered_transformers.each do |t|
|
154
|
+
traversals = dfs_paths([t]) { |k| incoming_edges.fetch(k.to, []) }
|
127
155
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
src, dst = types.first, types.last
|
132
|
-
processor = compose_transformers(registered_transformers, types)
|
156
|
+
traversals.each do |nodes|
|
157
|
+
src, dst = nodes.first.from, nodes.last.to
|
158
|
+
processor = compose_transformer_list nodes, preprocessors, postprocessors
|
133
159
|
|
134
|
-
|
135
|
-
|
160
|
+
transformers[src] = {} unless transformers.key?(src)
|
161
|
+
transformers[src][dst] = processor
|
136
162
|
|
137
|
-
|
138
|
-
|
163
|
+
inverted_transformers[dst] = Set.new unless inverted_transformers.key?(dst)
|
164
|
+
inverted_transformers[dst] << src
|
165
|
+
end
|
139
166
|
end
|
140
167
|
|
141
168
|
self.config = hash_reassoc(config, :transformers) { transformers }
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sprockets/autoload'
|
2
2
|
require 'sprockets/digest_utils'
|
3
|
+
require 'sprockets/source_map_utils'
|
3
4
|
|
4
5
|
module Sprockets
|
5
6
|
# Public: Uglifier/Uglify compressor.
|
@@ -15,7 +16,7 @@ module Sprockets
|
|
15
16
|
# Sprockets::UglifierCompressor.new(comments: :copyright)
|
16
17
|
#
|
17
18
|
class UglifierCompressor
|
18
|
-
VERSION = '
|
19
|
+
VERSION = '2'
|
19
20
|
|
20
21
|
# Public: Return singleton instance with default options.
|
21
22
|
#
|
@@ -41,16 +42,22 @@ module Sprockets
|
|
41
42
|
options[:copyright] ||= false
|
42
43
|
else
|
43
44
|
# Uglifier >= 2.x
|
44
|
-
options[:
|
45
|
+
options[:copyright] ||= :none
|
45
46
|
end
|
46
47
|
|
47
|
-
@
|
48
|
+
@uglifier = Autoload::Uglifier.new(options)
|
48
49
|
@cache_key = "#{self.class.name}:#{Autoload::Uglifier::VERSION}:#{VERSION}:#{DigestUtils.digest(options)}".freeze
|
49
50
|
end
|
50
51
|
|
51
52
|
def call(input)
|
52
|
-
@uglifier
|
53
|
-
|
53
|
+
js, map = @uglifier.compile_with_map(input[:data])
|
54
|
+
|
55
|
+
map = SourceMapUtils.combine_source_maps(
|
56
|
+
input[:metadata][:map],
|
57
|
+
SourceMapUtils.decode_json_source_map(map)["mappings"]
|
58
|
+
)
|
59
|
+
|
60
|
+
{ data: js, map: map }
|
54
61
|
end
|
55
62
|
end
|
56
63
|
end
|
@@ -12,8 +12,8 @@ module Sprockets
|
|
12
12
|
# and full path such as
|
13
13
|
# "file:///Path/app/assets/js/app.js?type=application/javascript"
|
14
14
|
# env - The current "environment" that assets are being loaded into.
|
15
|
-
# We need it so we know where the +root+ (directory where
|
16
|
-
# is being invoked). We also need for the `file_digest` method,
|
15
|
+
# We need it so we know where the +root+ (directory where Sprockets
|
16
|
+
# is being invoked). We also need it for the `file_digest` method,
|
17
17
|
# since, for some strange reason, memoization is provided by
|
18
18
|
# overriding methods such as `stat` in the `PathUtils` module.
|
19
19
|
#
|
@@ -30,7 +30,7 @@ module Sprockets
|
|
30
30
|
# Internal: Full file path without schema
|
31
31
|
#
|
32
32
|
# This returns a string containing the full path to the asset without the schema.
|
33
|
-
# Information is loaded
|
33
|
+
# Information is loaded lazily since we want `UnloadedAsset.new(dep, self).relative_path`
|
34
34
|
# to be fast. Calling this method the first time allocates an array and a hash.
|
35
35
|
#
|
36
36
|
# Example
|
@@ -48,8 +48,8 @@ module Sprockets
|
|
48
48
|
|
49
49
|
# Internal: Hash of param values
|
50
50
|
#
|
51
|
-
# This information is generated and used internally by
|
52
|
-
# Known keys include `:type` which
|
51
|
+
# This information is generated and used internally by Sprockets.
|
52
|
+
# Known keys include `:type` which stores the asset's mime-type, `:id` which is a fully resolved
|
53
53
|
# digest for the asset (includes dependency digest as opposed to a digest of only file contents)
|
54
54
|
# and `:pipeline`. Hash may be empty.
|
55
55
|
#
|
@@ -79,12 +79,12 @@ module Sprockets
|
|
79
79
|
|
80
80
|
# Public: Dependency History key
|
81
81
|
#
|
82
|
-
# Used to retrieve an array of "histories" each of which
|
82
|
+
# Used to retrieve an array of "histories" each of which contains a set of stored dependencies
|
83
83
|
# for a given asset path and filename digest.
|
84
84
|
#
|
85
|
-
# A dependency can refer to either an asset
|
85
|
+
# A dependency can refer to either an asset e.g. index.js
|
86
86
|
# may rely on jquery.js (so jquery.js is a dependency), or other factors that may affect
|
87
|
-
# compilation, such as the VERSION of
|
87
|
+
# compilation, such as the VERSION of Sprockets (i.e. the environment) and what "processors"
|
88
88
|
# are used.
|
89
89
|
#
|
90
90
|
# For example a history array with one Set of dependencies may look like:
|
@@ -97,7 +97,7 @@ module Sprockets
|
|
97
97
|
# This method of asset lookup is used to ensure that none of the dependencies have been modified
|
98
98
|
# since last lookup. If one of them has, the key will be different and a new entry must be stored.
|
99
99
|
#
|
100
|
-
# URI
|
100
|
+
# URI dependencies are later converted to "compressed" paths
|
101
101
|
#
|
102
102
|
# Returns a String.
|
103
103
|
def dependency_history_key
|
@@ -108,8 +108,9 @@ module Sprockets
|
|
108
108
|
#
|
109
109
|
# Used to retrieve a string containing the "compressed" path to an asset based on
|
110
110
|
# a digest. The digest is generated from dependencies stored via information stored in
|
111
|
-
# the `dependency_history_key` after each of the "dependencies" is "resolved"
|
112
|
-
# "environment-version" may be resolved to "environment-1.0-3.2.0"
|
111
|
+
# the `dependency_history_key` after each of the "dependencies" is "resolved".
|
112
|
+
# For example "environment-version" may be resolved to "environment-1.0-3.2.0"
|
113
|
+
# for version "3.2.0" of Sprockets
|
113
114
|
#
|
114
115
|
# Returns a String.
|
115
116
|
def digest_key(digest)
|
data/lib/sprockets/uri_tar.rb
CHANGED
@@ -14,8 +14,10 @@ module Sprockets
|
|
14
14
|
@env = env
|
15
15
|
uri = uri.to_s
|
16
16
|
if uri.include?("://".freeze)
|
17
|
-
|
18
|
-
@scheme
|
17
|
+
uri_array = uri.split("://".freeze)
|
18
|
+
@scheme = uri_array.shift
|
19
|
+
@scheme << "://".freeze
|
20
|
+
@path = uri_array.join("".freeze)
|
19
21
|
else
|
20
22
|
@scheme = "".freeze
|
21
23
|
@path = uri
|
data/lib/sprockets/uri_utils.rb
CHANGED
@@ -20,8 +20,6 @@ module Sprockets
|
|
20
20
|
module URIUtils
|
21
21
|
extend self
|
22
22
|
|
23
|
-
URI_PARSER = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::RFC2396_Parser.new
|
24
|
-
|
25
23
|
# Internal: Parse URI into component parts.
|
26
24
|
#
|
27
25
|
# uri - String uri
|
@@ -46,15 +44,12 @@ module Sprockets
|
|
46
44
|
def split_file_uri(uri)
|
47
45
|
scheme, _, host, _, _, path, _, query, _ = URI.split(uri)
|
48
46
|
|
49
|
-
path =
|
47
|
+
path = URI::Generic::DEFAULT_PARSER.unescape(path)
|
50
48
|
path.force_encoding(Encoding::UTF_8)
|
51
49
|
|
52
50
|
# Hack for parsing Windows "file:///C:/Users/IEUser" paths
|
53
51
|
path.gsub!(/^\/([a-zA-Z]:)/, '\1'.freeze)
|
54
52
|
|
55
|
-
host = nil if host && host.empty?
|
56
|
-
query = nil if query && query.empty?
|
57
|
-
|
58
53
|
[scheme, host, path, query]
|
59
54
|
end
|
60
55
|
|
@@ -64,8 +59,8 @@ module Sprockets
|
|
64
59
|
def join_file_uri(scheme, host, path, query)
|
65
60
|
str = "#{scheme}://"
|
66
61
|
str << host if host
|
67
|
-
path = "/#{path}" unless path.start_with?("/")
|
68
|
-
str <<
|
62
|
+
path = "/#{path}" unless path.start_with?("/".freeze)
|
63
|
+
str << URI::Generic::DEFAULT_PARSER.escape(path)
|
69
64
|
str << "?#{query}" if query
|
70
65
|
str
|
71
66
|
end
|
@@ -77,7 +72,7 @@ module Sprockets
|
|
77
72
|
# Returns true or false.
|
78
73
|
def valid_asset_uri?(str)
|
79
74
|
# Quick prefix check before attempting a full parse
|
80
|
-
str.start_with?("file://") && parse_asset_uri(str) ? true : false
|
75
|
+
str.start_with?("file://".freeze) && parse_asset_uri(str) ? true : false
|
81
76
|
rescue URI::InvalidURIError
|
82
77
|
false
|
83
78
|
end
|
@@ -164,7 +159,7 @@ module Sprockets
|
|
164
159
|
when Integer
|
165
160
|
query << "#{key}=#{value}"
|
166
161
|
when String, Symbol
|
167
|
-
query << "#{key}=#{
|
162
|
+
query << "#{key}=#{URI::Generic::DEFAULT_PARSER.escape(value.to_s)}"
|
168
163
|
when TrueClass
|
169
164
|
query << "#{key}"
|
170
165
|
when FalseClass, NilClass
|
@@ -173,7 +168,7 @@ module Sprockets
|
|
173
168
|
end
|
174
169
|
end
|
175
170
|
|
176
|
-
"#{query.join('&')}" if query.any?
|
171
|
+
"#{query.join('&'.freeze)}" if query.any?
|
177
172
|
end
|
178
173
|
|
179
174
|
# Internal: Parse query string into hash of params
|
@@ -182,9 +177,9 @@ module Sprockets
|
|
182
177
|
#
|
183
178
|
# Return Hash of params.
|
184
179
|
def parse_uri_query_params(query)
|
185
|
-
query.to_s.split('&').reduce({}) do |h, p|
|
186
|
-
k, v = p.split('=', 2)
|
187
|
-
v =
|
180
|
+
query.to_s.split('&'.freeze).reduce({}) do |h, p|
|
181
|
+
k, v = p.split('='.freeze, 2)
|
182
|
+
v = URI::Generic::DEFAULT_PARSER.unescape(v) if v
|
188
183
|
h[k.to_sym] = v || true
|
189
184
|
h
|
190
185
|
end
|
data/lib/sprockets/utils.rb
CHANGED
@@ -14,15 +14,11 @@ module Sprockets
|
|
14
14
|
#
|
15
15
|
# Returns false if .dup would raise a TypeError, otherwise true.
|
16
16
|
def duplicable?(obj)
|
17
|
-
|
18
|
-
|
17
|
+
case obj
|
18
|
+
when NilClass, FalseClass, TrueClass, Symbol, Numeric
|
19
|
+
false
|
19
20
|
else
|
20
|
-
|
21
|
-
when NilClass, FalseClass, TrueClass, Symbol, Numeric
|
22
|
-
false
|
23
|
-
else
|
24
|
-
true
|
25
|
-
end
|
21
|
+
true
|
26
22
|
end
|
27
23
|
end
|
28
24
|
|
@@ -49,7 +45,8 @@ module Sprockets
|
|
49
45
|
# Similar to Hash#store for nested frozen hashes.
|
50
46
|
#
|
51
47
|
# hash - Hash
|
52
|
-
#
|
48
|
+
# key_a - Object key. Use multiple keys for nested hashes.
|
49
|
+
# key_b - Object key. Use multiple keys for nested hashes.
|
53
50
|
# block - Receives current value at key.
|
54
51
|
#
|
55
52
|
# Examples
|
@@ -60,13 +57,13 @@ module Sprockets
|
|
60
57
|
# end
|
61
58
|
#
|
62
59
|
# Returns duplicated frozen Hash.
|
63
|
-
def hash_reassoc(hash,
|
64
|
-
if
|
65
|
-
hash_reassoc1(hash,
|
66
|
-
|
67
|
-
hash_reassoc1(hash, keys[0]) do |value|
|
68
|
-
hash_reassoc(value, *keys[1..-1], &block)
|
60
|
+
def hash_reassoc(hash, key_a, key_b = nil, &block)
|
61
|
+
if key_b
|
62
|
+
hash_reassoc1(hash, key_a) do |value|
|
63
|
+
hash_reassoc(value, key_b, &block)
|
69
64
|
end
|
65
|
+
else
|
66
|
+
hash_reassoc1(hash, key_a, &block)
|
70
67
|
end
|
71
68
|
end
|
72
69
|
|
@@ -78,19 +75,16 @@ module Sprockets
|
|
78
75
|
def string_end_with_semicolon?(str)
|
79
76
|
i = str.size - 1
|
80
77
|
while i >= 0
|
81
|
-
c = str[i]
|
78
|
+
c = str[i]
|
82
79
|
i -= 1
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
unless c == 0x0A || c == 0x20 || c == 0x09
|
90
|
-
return c === 0x3B
|
80
|
+
if c == "\n" || c == " " || c == "\t"
|
81
|
+
next
|
82
|
+
elsif c != ";"
|
83
|
+
return false
|
84
|
+
else
|
85
|
+
return true
|
91
86
|
end
|
92
87
|
end
|
93
|
-
|
94
88
|
true
|
95
89
|
end
|
96
90
|
|
@@ -102,50 +96,11 @@ module Sprockets
|
|
102
96
|
#
|
103
97
|
# Returns buf String.
|
104
98
|
def concat_javascript_sources(buf, source)
|
105
|
-
buf
|
106
|
-
|
107
|
-
buf <<
|
108
|
-
|
109
|
-
# If the source contains non-ASCII characters, indexing on it becomes O(N).
|
110
|
-
# This will lead to O(N^2) performance in string_end_with_semicolon?, so we should use 32 bit encoding to make sure indexing stays O(1)
|
111
|
-
source = source.encode(Encoding::UTF_32LE) unless source.ascii_only?
|
112
|
-
|
113
|
-
if !string_end_with_semicolon?(source)
|
114
|
-
buf << ";\n"
|
115
|
-
elsif source[source.size - 1].ord != 0x0A
|
116
|
-
buf << "\n"
|
117
|
-
end
|
99
|
+
if buf.bytesize > 0
|
100
|
+
buf << ";" unless string_end_with_semicolon?(buf)
|
101
|
+
buf << "\n" unless buf.end_with?("\n")
|
118
102
|
end
|
119
|
-
|
120
|
-
buf
|
121
|
-
end
|
122
|
-
|
123
|
-
# Internal: Prepends a leading "." to an extension if its missing.
|
124
|
-
#
|
125
|
-
# normalize_extension("js")
|
126
|
-
# # => ".js"
|
127
|
-
#
|
128
|
-
# normalize_extension(".css")
|
129
|
-
# # => ".css"
|
130
|
-
#
|
131
|
-
def normalize_extension(extension)
|
132
|
-
extension = extension.to_s
|
133
|
-
if extension[/^\./]
|
134
|
-
extension
|
135
|
-
else
|
136
|
-
".#{extension}"
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Internal: Feature detect if UnboundMethods can #bind to any Object or
|
141
|
-
# just Objects that share the same super class.
|
142
|
-
# Basically if RUBY_VERSION >= 2.
|
143
|
-
UNBOUND_METHODS_BIND_TO_ANY_OBJECT = begin
|
144
|
-
foo = Module.new { def bar; end }
|
145
|
-
foo.instance_method(:bar).bind(Object.new)
|
146
|
-
true
|
147
|
-
rescue TypeError
|
148
|
-
false
|
103
|
+
buf << source
|
149
104
|
end
|
150
105
|
|
151
106
|
# Internal: Inject into target module for the duration of the block.
|
@@ -160,10 +115,6 @@ module Sprockets
|
|
160
115
|
old_methods[sym] = base.instance_method(sym) if base.method_defined?(sym)
|
161
116
|
end
|
162
117
|
|
163
|
-
unless UNBOUND_METHODS_BIND_TO_ANY_OBJECT
|
164
|
-
base.send(:include, mod) unless base < mod
|
165
|
-
end
|
166
|
-
|
167
118
|
mod.instance_methods.each do |sym|
|
168
119
|
method = mod.instance_method(sym)
|
169
120
|
base.send(:define_method, sym, method)
|
@@ -217,16 +168,16 @@ module Sprockets
|
|
217
168
|
# Returns an Array of node Arrays.
|
218
169
|
def dfs_paths(path)
|
219
170
|
paths = []
|
220
|
-
stack
|
171
|
+
stack = [path]
|
172
|
+
seen = Set.new
|
221
173
|
|
222
174
|
while path = stack.pop
|
223
|
-
|
224
|
-
|
225
|
-
paths << path if path.size > 1
|
175
|
+
seen.add(path.last)
|
176
|
+
paths << path
|
226
177
|
|
227
|
-
|
228
|
-
|
229
|
-
|
178
|
+
children = yield path.last
|
179
|
+
children.reverse_each do |node|
|
180
|
+
stack.push(path + [node]) unless seen.include?(node)
|
230
181
|
end
|
231
182
|
end
|
232
183
|
|
data/lib/sprockets/version.rb
CHANGED