sprockets 2.12.5 → 3.7.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,211 @@
1
+ require 'set'
2
+ require 'sprockets/http_utils'
3
+ require 'sprockets/path_dependency_utils'
4
+ require 'sprockets/uri_utils'
5
+
6
+ module Sprockets
7
+ module Resolve
8
+ include HTTPUtils, PathDependencyUtils, URIUtils
9
+
10
+ # Public: Find Asset URI for given a logical path by searching the
11
+ # environment's load paths.
12
+ #
13
+ # resolve("application.js")
14
+ # # => "file:///path/to/app/javascripts/application.js?type=application/javascript"
15
+ #
16
+ # An accept content type can be given if the logical path doesn't have a
17
+ # format extension.
18
+ #
19
+ # resolve("application", accept: "application/javascript")
20
+ # # => "file:///path/to/app/javascripts/application.coffee?type=application/javascript"
21
+ #
22
+ # The String Asset URI is returned or nil if no results are found.
23
+ def resolve(path, options = {})
24
+ path = path.to_s
25
+ paths = options[:load_paths] || config[:paths]
26
+ accept = options[:accept]
27
+
28
+ if valid_asset_uri?(path)
29
+ uri, deps = resolve_asset_uri(path)
30
+ elsif absolute_path?(path)
31
+ filename, type, deps = resolve_absolute_path(paths, path, accept)
32
+ elsif relative_path?(path)
33
+ filename, type, pipeline, deps = resolve_relative_path(paths, path, options[:base_path], accept)
34
+ else
35
+ filename, type, pipeline, deps = resolve_logical_path(paths, path, accept)
36
+ end
37
+
38
+ if filename
39
+ params = {}
40
+ params[:type] = type if type
41
+ params[:pipeline] = pipeline if pipeline
42
+ params[:pipeline] = options[:pipeline] if options[:pipeline]
43
+ uri = build_asset_uri(filename, params)
44
+ end
45
+
46
+ return uri, deps
47
+ end
48
+
49
+ # Public: Same as resolve() but raises a FileNotFound exception instead of
50
+ # nil if no assets are found.
51
+ def resolve!(path, options = {})
52
+ uri, deps = resolve(path, options.merge(compat: false))
53
+
54
+ unless uri
55
+ message = "couldn't find file '#{path}'"
56
+
57
+ if relative_path?(path) && options[:base_path]
58
+ load_path, _ = paths_split(config[:paths], options[:base_path])
59
+ message << " under '#{load_path}'"
60
+ end
61
+
62
+ message << " with type '#{options[:accept]}'" if options[:accept]
63
+ message << "\nChecked in these paths: \n #{ config[:paths].join("\n ") }"
64
+
65
+ raise FileNotFound, message
66
+ end
67
+
68
+ return uri, deps
69
+ end
70
+
71
+ protected
72
+ def resolve_asset_uri(uri)
73
+ filename, _ = parse_asset_uri(uri)
74
+ return uri, Set.new([build_file_digest_uri(filename)])
75
+ end
76
+
77
+ def resolve_absolute_path(paths, filename, accept)
78
+ deps = Set.new
79
+ filename = File.expand_path(filename)
80
+
81
+ # Ensure path is under load paths
82
+ return nil, nil, deps unless paths_split(paths, filename)
83
+
84
+ _, mime_type, _, _ = parse_path_extnames(filename)
85
+ type = resolve_transform_type(mime_type, accept)
86
+ return nil, nil, deps if accept && !type
87
+
88
+ return nil, nil, deps unless file?(filename)
89
+
90
+ deps << build_file_digest_uri(filename)
91
+ return filename, type, deps
92
+ end
93
+
94
+ def resolve_relative_path(paths, path, dirname, accept)
95
+ filename = File.expand_path(path, dirname)
96
+ load_path, _ = paths_split(paths, dirname)
97
+ if load_path && logical_path = split_subpath(load_path, filename)
98
+ resolve_logical_path([load_path], logical_path, accept)
99
+ else
100
+ return nil, nil, Set.new
101
+ end
102
+ end
103
+
104
+ def resolve_logical_path(paths, logical_path, accept)
105
+ logical_name, mime_type, _, pipeline = parse_path_extnames(logical_path)
106
+ parsed_accept = parse_accept_options(mime_type, accept)
107
+ transformed_accepts = expand_transform_accepts(parsed_accept)
108
+ filename, mime_type, deps = resolve_under_paths(paths, logical_name, transformed_accepts)
109
+
110
+ if filename
111
+ deps << build_file_digest_uri(filename)
112
+ type = resolve_transform_type(mime_type, parsed_accept)
113
+ return filename, type, pipeline, deps
114
+ else
115
+ return nil, nil, nil, deps
116
+ end
117
+ end
118
+
119
+ def resolve_under_paths(paths, logical_name, accepts)
120
+ all_deps = Set.new
121
+ return nil, nil, all_deps if accepts.empty?
122
+
123
+ logical_basename = File.basename(logical_name)
124
+ paths.each do |load_path|
125
+ candidates, deps = path_matches(load_path, logical_name, logical_basename)
126
+ all_deps.merge(deps)
127
+ candidate = find_best_q_match(accepts, candidates) do |c, matcher|
128
+ match_mime_type?(c[1] || "application/octet-stream", matcher)
129
+ end
130
+ return candidate + [all_deps] if candidate
131
+ end
132
+
133
+ return nil, nil, all_deps
134
+ end
135
+
136
+ def parse_accept_options(mime_type, types)
137
+ accepts = []
138
+ accepts += parse_q_values(types) if types
139
+
140
+ if mime_type
141
+ if accepts.empty? || accepts.any? { |accept, _| match_mime_type?(mime_type, accept) }
142
+ accepts = [[mime_type, 1.0]]
143
+ else
144
+ return []
145
+ end
146
+ end
147
+
148
+ if accepts.empty?
149
+ accepts << ['*/*', 1.0]
150
+ end
151
+
152
+ accepts
153
+ end
154
+
155
+ def path_matches(load_path, logical_name, logical_basename)
156
+ dirname = File.dirname(File.join(load_path, logical_name))
157
+ candidates = dirname_matches(dirname, logical_basename)
158
+ deps = file_digest_dependency_set(dirname)
159
+
160
+ result = resolve_alternates(load_path, logical_name)
161
+ result[0].each do |fn|
162
+ candidates << [fn, parse_path_extnames(fn)[1]]
163
+ end
164
+ deps.merge(result[1])
165
+
166
+ dirname = File.join(load_path, logical_name)
167
+ if directory? dirname
168
+ result = dirname_matches(dirname, "index")
169
+ candidates.concat(result)
170
+ end
171
+
172
+ deps.merge(file_digest_dependency_set(dirname))
173
+
174
+ return candidates.select { |fn, _| file?(fn) }, deps
175
+ end
176
+
177
+ def dirname_matches(dirname, basename)
178
+ candidates = []
179
+ entries = self.entries(dirname)
180
+ entries.each do |entry|
181
+ next unless File.basename(entry).start_with?(basename)
182
+ name, type, _, _ = parse_path_extnames(entry)
183
+ if basename == name
184
+ candidates << [File.join(dirname, entry), type]
185
+ end
186
+ end
187
+ candidates
188
+ end
189
+
190
+ def resolve_alternates(load_path, logical_name)
191
+ return [], Set.new
192
+ end
193
+
194
+ # Internal: Returns the name, mime type and `Array` of engine extensions.
195
+ #
196
+ # "foo.js.coffee.erb"
197
+ # # => ["foo", "application/javascript", [".coffee", ".erb"]]
198
+ #
199
+ def parse_path_extnames(path)
200
+ engines = []
201
+ extname, value = match_path_extname(path, extname_map)
202
+
203
+ if extname
204
+ path = path.chomp(extname)
205
+ type, engines, pipeline = value.values_at(:type, :engines, :pipeline)
206
+ end
207
+
208
+ return path, type, engines, pipeline
209
+ end
210
+ end
211
+ end
@@ -1,29 +1,34 @@
1
1
  require 'sass'
2
2
 
3
3
  module Sprockets
4
- class SassCacheStore < ::Sass::CacheStores::Base
5
- attr_reader :environment
4
+ class SassProcessor
5
+ # Internal: Cache wrapper for Sprockets cache adapter.
6
+ class CacheStore < ::Sass::CacheStores::Base
7
+ VERSION = '1'
6
8
 
7
- def initialize(environment)
8
- @environment = environment
9
- end
9
+ def initialize(cache, version)
10
+ @cache, @version = cache, "#{VERSION}/#{version}"
11
+ end
10
12
 
11
- def _store(key, version, sha, contents)
12
- environment.cache_set("sass/#{key}", {:version => version, :sha => sha, :contents => contents})
13
- end
13
+ def _store(key, version, sha, contents)
14
+ @cache.set("#{@version}/#{version}/#{key}/#{sha}", contents, true)
15
+ end
14
16
 
15
- def _retrieve(key, version, sha)
16
- if obj = environment.cache_get("sass/#{key}")
17
- return unless obj[:version] == version
18
- return unless obj[:sha] == sha
19
- obj[:contents]
20
- else
21
- nil
17
+ def _retrieve(key, version, sha)
18
+ @cache.get("#{@version}/#{version}/#{key}/#{sha}", true)
19
+ end
20
+
21
+ def path_to(key)
22
+ key
22
23
  end
23
24
  end
25
+ end
24
26
 
25
- def path_to(key)
26
- key
27
+ # Deprecated: Use Sprockets::SassProcessor::CacheStore instead.
28
+ class SassCacheStore < SassProcessor::CacheStore
29
+ def initialize(*args)
30
+ Deprecation.new.warn "SassCacheStore is deprecated please use SassProcessor::CacheStore instead"
31
+ super
27
32
  end
28
33
  end
29
34
  end
@@ -1,27 +1,51 @@
1
- require 'tilt'
1
+ require 'sprockets/autoload'
2
+ require 'sprockets/digest_utils'
2
3
 
3
4
  module Sprockets
4
- class SassCompressor < Tilt::Template
5
- self.default_mime_type = 'text/css'
5
+ # Public: Sass CSS minifier.
6
+ #
7
+ # To accept the default options
8
+ #
9
+ # environment.register_bundle_processor 'text/css',
10
+ # Sprockets::SassCompressor
11
+ #
12
+ # Or to pass options to the Sass::Engine class.
13
+ #
14
+ # environment.register_bundle_processor 'text/css',
15
+ # Sprockets::SassCompressor.new({ ... })
16
+ #
17
+ class SassCompressor
18
+ VERSION = '1'
6
19
 
7
- def self.engine_initialized?
8
- defined?(::Sass::Engine)
20
+ # Public: Return singleton instance with default options.
21
+ #
22
+ # Returns SassCompressor object.
23
+ def self.instance
24
+ @instance ||= new
9
25
  end
10
26
 
11
- def initialize_engine
12
- require_template_library 'sass'
27
+ def self.call(input)
28
+ instance.call(input)
13
29
  end
14
30
 
15
- def prepare
31
+ def self.cache_key
32
+ instance.cache_key
16
33
  end
17
34
 
18
- def evaluate(context, locals, &block)
19
- ::Sass::Engine.new(data, {
20
- :syntax => :scss,
21
- :cache => false,
22
- :read_cache => false,
23
- :style => :compressed
24
- }).render
35
+ attr_reader :cache_key
36
+
37
+ def initialize(options = {})
38
+ @options = {
39
+ syntax: :scss,
40
+ cache: false,
41
+ read_cache: false,
42
+ style: :compressed
43
+ }.merge(options).freeze
44
+ @cache_key = "#{self.class.name}:#{Autoload::Sass::VERSION}:#{VERSION}:#{DigestUtils.digest(options)}".freeze
45
+ end
46
+
47
+ def call(input)
48
+ Autoload::Sass::Engine.new(input[:data], @options).render
25
49
  end
26
50
  end
27
51
  end
@@ -1,70 +1,2 @@
1
- require 'sass'
2
-
3
- module Sprockets
4
- module SassFunctions
5
- def asset_path(path)
6
- ::Sass::Script::String.new(sprockets_context.asset_path(path.value), :string)
7
- end
8
-
9
- def asset_url(path)
10
- ::Sass::Script::String.new("url(" + sprockets_context.asset_path(path.value) + ")")
11
- end
12
-
13
- def image_path(path)
14
- ::Sass::Script::String.new(sprockets_context.image_path(path.value), :string)
15
- end
16
-
17
- def image_url(path)
18
- ::Sass::Script::String.new("url(" + sprockets_context.image_path(path.value) + ")")
19
- end
20
-
21
- def video_path(path)
22
- ::Sass::Script::String.new(sprockets_context.video_path(path.value), :string)
23
- end
24
-
25
- def video_url(path)
26
- ::Sass::Script::String.new("url(" + sprockets_context.video_path(path.value) + ")")
27
- end
28
-
29
- def audio_path(path)
30
- ::Sass::Script::String.new(sprockets_context.audio_path(path.value), :string)
31
- end
32
-
33
- def audio_url(path)
34
- ::Sass::Script::String.new("url(" + sprockets_context.audio_path(path.value) + ")")
35
- end
36
-
37
- def font_path(path)
38
- ::Sass::Script::String.new(sprockets_context.font_path(path.value), :string)
39
- end
40
-
41
- def font_url(path)
42
- ::Sass::Script::String.new("url(" + sprockets_context.font_path(path.value) + ")")
43
- end
44
-
45
- def javascript_path(path)
46
- ::Sass::Script::String.new(sprockets_context.javascript_path(path.value), :string)
47
- end
48
-
49
- def javascript_url(path)
50
- ::Sass::Script::String.new("url(" + sprockets_context.javascript_path(path.value) + ")")
51
- end
52
-
53
- def stylesheet_path(path)
54
- ::Sass::Script::String.new(sprockets_context.stylesheet_path(path.value), :string)
55
- end
56
-
57
- def stylesheet_url(path)
58
- ::Sass::Script::String.new("url(" + sprockets_context.stylesheet_path(path.value) + ")")
59
- end
60
-
61
- protected
62
- def sprockets_context
63
- options[:sprockets][:context]
64
- end
65
-
66
- def sprockets_environment
67
- options[:sprockets][:environment]
68
- end
69
- end
70
- end
1
+ # Deprecated: Require sprockets/sass_processor instead
2
+ require 'sprockets/sass_processor'
@@ -1,30 +1,2 @@
1
- require 'sass'
2
-
3
- module Sprockets
4
- # This custom importer that tracks all imported filenames during
5
- # compile.
6
- class SassImporter < ::Sass::Importers::Filesystem
7
- attr_reader :imported_filenames
8
-
9
- def initialize(*args)
10
- @imported_filenames = []
11
- super
12
- end
13
-
14
- def find_relative(*args)
15
- engine = super
16
- if engine && (filename = engine.options[:filename])
17
- @imported_filenames << filename
18
- end
19
- engine
20
- end
21
-
22
- def find(*args)
23
- engine = super
24
- if engine && (filename = engine.options[:filename])
25
- @imported_filenames << filename
26
- end
27
- engine
28
- end
29
- end
30
- end
1
+ # Deprecated: Require sprockets/sass_processor instead
2
+ require 'sprockets/sass_processor'