sprockets-sass 1.3.1 → 2.0.0.beta2

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/.reek +12 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +77 -0
  5. data/.travis.yml +14 -0
  6. data/Appraisals +32 -15
  7. data/Gemfile +5 -0
  8. data/README.md +41 -4
  9. data/Rakefile +15 -3
  10. data/gemfiles/compass_0.11.gemfile +1 -1
  11. data/gemfiles/sass_3.1.gemfile +1 -1
  12. data/gemfiles/sass_3.3.gemfile +8 -0
  13. data/gemfiles/sass_3.4.gemfile +8 -0
  14. data/gemfiles/sprockets_2.10.gemfile +1 -1
  15. data/gemfiles/sprockets_2.11.gemfile +1 -1
  16. data/gemfiles/sprockets_2.2.gemfile +1 -1
  17. data/gemfiles/sprockets_2.3.gemfile +1 -1
  18. data/gemfiles/sprockets_2.4.gemfile +1 -1
  19. data/gemfiles/sprockets_2.5.gemfile +1 -1
  20. data/gemfiles/sprockets_2.6.gemfile +1 -1
  21. data/gemfiles/sprockets_2.7.gemfile +1 -1
  22. data/gemfiles/sprockets_2.8.gemfile +1 -1
  23. data/gemfiles/sprockets_2.9.gemfile +1 -1
  24. data/gemfiles/sprockets_3.7.gemfile +9 -0
  25. data/gemfiles/sprockets_4.0.gemfile +10 -0
  26. data/gemfiles/sprockets_4.0_beta2.gemfile +9 -0
  27. data/lib/sprockets/sass/functions.rb +24 -159
  28. data/lib/sprockets/sass/registration.rb +126 -0
  29. data/lib/sprockets/sass/utils.rb +115 -0
  30. data/lib/sprockets/sass/v2/cache_store.rb +26 -0
  31. data/lib/sprockets/sass/v2/compressor.rb +31 -0
  32. data/lib/sprockets/sass/v2/functions.rb +142 -0
  33. data/lib/sprockets/sass/v2/importer.rb +209 -0
  34. data/lib/sprockets/sass/v2/sass_template.rb +221 -0
  35. data/lib/sprockets/sass/v2/scss_template.rb +14 -0
  36. data/lib/sprockets/sass/v3/cache_store.rb +28 -0
  37. data/lib/sprockets/sass/v3/compressor.rb +97 -0
  38. data/lib/sprockets/sass/v3/functions.rb +12 -0
  39. data/lib/sprockets/sass/v3/importer.rb +224 -0
  40. data/lib/sprockets/sass/v3/sass_template.rb +37 -0
  41. data/lib/sprockets/sass/v3/scss_template.rb +15 -0
  42. data/lib/sprockets/sass/v4/cache_store.rb +11 -0
  43. data/lib/sprockets/sass/v4/compressor.rb +11 -0
  44. data/lib/sprockets/sass/v4/functions.rb +12 -0
  45. data/lib/sprockets/sass/v4/importer.rb +109 -0
  46. data/lib/sprockets/sass/v4/sass_template.rb +27 -0
  47. data/lib/sprockets/sass/v4/scss_template.rb +16 -0
  48. data/lib/sprockets/sass/version.rb +2 -1
  49. data/lib/sprockets/sass.rb +37 -12
  50. data/lib/sprockets-sass.rb +1 -0
  51. data/spec/custom_importer_spec.rb +4 -6
  52. data/spec/importer_spec.rb +44 -0
  53. data/spec/spec_helper.rb +39 -3
  54. data/spec/sprockets-sass_spec.rb +102 -62
  55. data/spec/support/be_fresh_matcher.rb +12 -8
  56. data/spec/support/dummy_importer.rb +1 -1
  57. data/spec/support/fail_postprocessor.rb +23 -0
  58. data/spec/support/fake_engine.rb +50 -0
  59. data/spec/support/sass_template.rb +11 -0
  60. data/spec/support/test_registration.rb +11 -0
  61. data/sprockets-sass.gemspec +28 -9
  62. metadata +100 -97
  63. data/gemfiles/compass_0.12.gemfile +0 -7
  64. data/gemfiles/sass_3.2.gemfile +0 -7
  65. data/gemfiles/sprockets_2.0.gemfile +0 -7
  66. data/gemfiles/sprockets_2.1.gemfile +0 -9
  67. data/lib/sprockets/sass/cache_store.rb +0 -27
  68. data/lib/sprockets/sass/compressor.rb +0 -22
  69. data/lib/sprockets/sass/importer.rb +0 -142
  70. data/lib/sprockets/sass/sass_template.rb +0 -115
  71. data/lib/sprockets/sass/scss_template.rb +0 -12
@@ -0,0 +1,221 @@
1
+ # frozen_string_literal: true
2
+ module Sprockets
3
+ module Sass
4
+ module V2
5
+ # Preprocessor for SASS files
6
+ class SassTemplate
7
+ VERSION = '1'
8
+
9
+ def self.default_mime_type
10
+ 'text/css'
11
+ end
12
+
13
+ # Internal: Defines default sass syntax to use. Exposed so the ScssProcessor
14
+ # may override it.
15
+ def self.syntax
16
+ :sass
17
+ end
18
+
19
+ # Public: Return singleton instance with default options.
20
+ #
21
+ # Returns SassProcessor object.
22
+ def self.instance
23
+ @instance ||= new
24
+ end
25
+
26
+ def self.call(input)
27
+ instance.call(input)
28
+ end
29
+
30
+ def self.cache_key
31
+ instance.cache_key
32
+ end
33
+
34
+ attr_reader :cache_key, :filename, :source, :context, :options
35
+
36
+ def initialize(options = {}, &block)
37
+ @default_options = { default_encoding: Encoding.default_external || 'utf-8' }
38
+ initialize_engine
39
+ if options.is_a?(Hash)
40
+ instantiate_with_options(options, &block)
41
+ else
42
+ instantiate_with_filename_and_source(options, &block)
43
+ end
44
+ end
45
+
46
+ def instantiate_with_filename_and_source(options)
47
+ @filename = options
48
+ @source = block_given? ? yield : nil
49
+ @options = @default_options
50
+ @cache_version = VERSION
51
+ @cache_key = "#{self.class.name}:#{::Sass::VERSION}:#{VERSION}:#{Sprockets::Sass::Utils.digest(options)}"
52
+ @functions = Module.new do
53
+ include Sprockets::Helpers if defined?(Sprockets::Helpers)
54
+ include Sprockets::Sass::Utils.get_class_by_version('Functions')
55
+ end
56
+ end
57
+
58
+ def instantiate_with_options(options, &block)
59
+ @cache_version = options[:cache_version] || VERSION
60
+ @cache_key = "#{self.class.name}:#{::Sass::VERSION}:#{@cache_version}:#{Sprockets::Sass::Utils.digest(options)}"
61
+ @filename = options[:filename]
62
+ @source = options[:data]
63
+ @options = options.merge(@default_options)
64
+ @importer_class = options[:importer]
65
+ @sass_config = options[:sass_config] || {}
66
+ @input = options
67
+ @functions = Module.new do
68
+ include Sprockets::Helpers if defined?(Sprockets::Helpers)
69
+ include Sprockets::Sass::Utils.get_class_by_version('Functions')
70
+ include options[:functions] if options[:functions]
71
+ class_eval(&block) if block_given?
72
+ end
73
+ end
74
+
75
+ @sass_functions_initialized = false
76
+ class << self
77
+ attr_accessor :sass_functions_initialized
78
+ alias sass_functions_initialized? sass_functions_initialized
79
+ # Templates are initialized once the functions are added.
80
+ def engine_initialized?
81
+ sass_functions_initialized?
82
+ end
83
+ end
84
+
85
+ # Add the Sass functions if they haven't already been added.
86
+ def initialize_engine
87
+ return if self.class.engine_initialized?
88
+
89
+ if Sass.add_sass_functions != false
90
+ begin
91
+ require 'sprockets/helpers'
92
+ require 'sprockets/sass/functions'
93
+ self.class.sass_functions_initialized = true
94
+ rescue LoadError; end
95
+ end
96
+ end
97
+
98
+ def call(input)
99
+ @input = input
100
+ @filename = input[:filename]
101
+ @source = input[:data]
102
+ @context = input[:environment].context_class.new(input)
103
+ run
104
+ end
105
+
106
+ def render(context, _empty_hash_wtf)
107
+ @context = context
108
+ run
109
+ end
110
+
111
+ def run
112
+ data = Sprockets::Sass::Utils.read_file_binary(filename, options)
113
+
114
+ engine = ::Sass::Engine.new(data, sass_options)
115
+ css = Sprockets::Sass::Utils.module_include(::Sass::Script::Functions, @functions) do
116
+ css = engine.render
117
+ end
118
+
119
+ sass_dependencies = Set.new([filename])
120
+ if context.respond_to?(:metadata)
121
+ engine.dependencies.map do |dependency|
122
+ sass_dependencies << dependency.options[:filename]
123
+ context.metadata[:dependencies] << Sprockets::URIUtils.build_file_digest_uri(dependency.options[:filename])
124
+ end
125
+ context.metadata.merge(data: css, sass_dependencies: sass_dependencies)
126
+ else
127
+ css
128
+ end
129
+
130
+ # Tilt::SassTemplate.new(filename, sass_options(filename, context)).render(self)
131
+ rescue => e
132
+ # Annotates exception message with parse line number
133
+ # context.__LINE__ = e.sass_backtrace.first[:line]
134
+ raise [e, e.backtrace].join("\n")
135
+ end
136
+
137
+ def merge_sass_options(options, other_options)
138
+ if (load_paths = options[:load_paths]) && (other_paths = other_options[:load_paths])
139
+ other_options[:load_paths] = other_paths + load_paths
140
+ end
141
+ options = options.merge(other_options)
142
+ options[:load_paths] = options[:load_paths].is_a?(Array) ? options[:load_paths] : []
143
+ options[:load_paths] = options[:load_paths].concat(context.environment.paths)
144
+ options
145
+ end
146
+
147
+ def default_sass_config
148
+ if defined?(Compass)
149
+ merge_sass_options Compass.sass_engine_options.dup, Sprockets::Sass.options
150
+ else
151
+ Sprockets::Sass.options.dup
152
+ end
153
+ end
154
+
155
+ def default_sass_options
156
+ sass = default_sass_config
157
+ sass = merge_sass_options(sass.dup, @sass_config) if defined?(@sass_config) && @sass_config.is_a?(Hash)
158
+ sass
159
+ end
160
+
161
+ def build_cache_store(context)
162
+ return nil if context.environment.cache.nil?
163
+ if defined?(Sprockets::SassProcessor::CacheStore)
164
+ Sprockets::SassProcessor::CacheStore.new(context.environment)
165
+ else
166
+ custom_cache_store(context.environment)
167
+ end
168
+ end
169
+
170
+ def custom_cache_store(*args)
171
+ Sprockets::Sass::V2::CacheStore.new(*args)
172
+ end
173
+
174
+ # Allow the use of custom SASS importers, making sure the
175
+ # custom importer is a `Sprockets::Sass::Importer`
176
+ def fetch_importer_class
177
+ if defined?(@importer_class) && !@importer_class.nil?
178
+ @importer_class
179
+ elsif default_sass_options.key?(:importer) && default_sass_options[:importer].is_a?(Importer)
180
+ default_sass_options[:importer]
181
+ else
182
+ custom_importer_class
183
+ end
184
+ end
185
+
186
+ def custom_importer_class(*_args)
187
+ Sprockets::Sass::V2::Importer.new
188
+ end
189
+
190
+ def fetch_sprockets_options
191
+ sprockets_options = {
192
+ context: context,
193
+ environment: context.environment,
194
+ dependencies: context.respond_to?(:metadata) ? context.metadata[:dependencies] : []
195
+ }
196
+ if context.respond_to?(:metadata)
197
+ sprockets_options.merge(load_paths: context.environment.paths + default_sass_options[:load_paths])
198
+ end
199
+ sprockets_options
200
+ end
201
+
202
+ def sass_options
203
+ importer = fetch_importer_class
204
+ sprockets_options = fetch_sprockets_options
205
+
206
+ sass = merge_sass_options(default_sass_options, options).merge(
207
+ filename: filename,
208
+ line: 1,
209
+ syntax: self.class.syntax,
210
+ cache: true,
211
+ cache_store: build_cache_store(context),
212
+ importer: importer,
213
+ custom: { sprockets_context: context },
214
+ sprockets: sprockets_options
215
+ )
216
+ sass
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module Sprockets
3
+ module Sass
4
+ module V2
5
+ # Preprocessor for SCSS files
6
+ class ScssTemplate < Sprockets::Sass::V2::SassTemplate
7
+ # Define the expected syntax for the template
8
+ def self.syntax
9
+ :scss
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ module Sprockets
3
+ module Sass
4
+ module V3
5
+ # Internal: Cache wrapper for Sprockets cache adapter. (Sprockets >= 3)
6
+ class CacheStore < ::Sass::CacheStores::Base
7
+ VERSION = '1'
8
+
9
+ def initialize(cache, version)
10
+ @cache = cache
11
+ @version = "#{VERSION}/#{version}"
12
+ end
13
+
14
+ def _store(key, version, sha, contents)
15
+ @cache.set("#{@version}/#{version}/#{key}/#{sha}", contents, true)
16
+ end
17
+
18
+ def _retrieve(key, version, sha)
19
+ @cache.get("#{@version}/#{version}/#{key}/#{sha}", true)
20
+ end
21
+
22
+ def path_to(key)
23
+ key
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sprockets
4
+ module Sass
5
+ module V3
6
+ # Class used to compress CSS files
7
+ class Compressor
8
+ VERSION = '1'
9
+
10
+ def self.default_mime_type
11
+ 'text/css'
12
+ end
13
+
14
+ # Public: Return singleton instance with default options.
15
+ #
16
+ # Returns SassCompressor object.
17
+ def self.instance
18
+ @instance ||= new
19
+ end
20
+
21
+ def self.call(input)
22
+ instance.call(input)
23
+ end
24
+
25
+ def self.cache_key
26
+ instance.cache_key
27
+ end
28
+
29
+ attr_reader :cache_key, :input, :filename, :source, :options, :context
30
+
31
+ def initialize(options = {})
32
+ @default_options = {
33
+ syntax: :scss,
34
+ cache: false,
35
+ read_cache: false,
36
+ style: :compressed,
37
+ default_encoding: Encoding.default_external || 'utf-8'
38
+ }
39
+ @options = @default_options
40
+ @cache_key = "#{self.class.name}:#{::Sass::VERSION}:#{VERSION}:#{Sprockets::Sass::Utils.digest(options)}"
41
+ if options.is_a?(Hash)
42
+ @input = options
43
+ @filename = options[:filename]
44
+ @source = options[:data]
45
+ @options = @options.merge(options)
46
+ else
47
+ @filename = options
48
+ @source = block_given? ? yield : nil
49
+ end
50
+ end
51
+
52
+ def call(input)
53
+ @input = input
54
+ if input.is_a?(Hash)
55
+ @filename = input[:filename]
56
+ @source = input[:data]
57
+ @context = input[:environment].context_class.new(input)
58
+ end
59
+ data = filename || @input
60
+ run(data)
61
+ end
62
+
63
+ def render(context, _empty_hash_wtf)
64
+ @context = context
65
+ run(filename)
66
+ end
67
+
68
+ def self.compress(input)
69
+ call(input)
70
+ end
71
+
72
+ def run(string)
73
+ data = File.exist?(string.to_s) ? Sprockets::Sass::Utils.read_file_binary(string, options) : string
74
+ if data.count("\n") >= 2
75
+ engine = ::Sass::Engine.new(data, @options.merge(filename: filename))
76
+ css = engine.render
77
+ # this is defined when using sprockets environment,
78
+ # but is not defined when calling directly in tests
79
+ # unless using the manifest to compile the assets
80
+ if defined?(@context) && @context.respond_to?(:metadata)
81
+ sass_dependencies = Set.new([filename])
82
+ engine.dependencies.map do |dependency|
83
+ sass_dependencies << dependency.options[:filename]
84
+ context.metadata[:dependencies] << Sprockets::URIUtils.build_file_digest_uri(dependency.options[:filename])
85
+ end
86
+ context.metadata.merge(data: css, sass_dependencies: sass_dependencies)
87
+ else
88
+ css
89
+ end
90
+ else
91
+ data
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../v2/functions'
3
+ module Sprockets
4
+ module Sass
5
+ module V3
6
+ # Module used to inject helpers into SASS engine
7
+ module Functions
8
+ include Sprockets::Sass::V2::Functions
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../v2/importer'
3
+ module Sprockets
4
+ module Sass
5
+ module V3
6
+ # class used for importing files from SCCS and SASS files
7
+ class Importer < Sprockets::Sass::V2::Importer
8
+ GLOB = /\*|\[.+\]/
9
+
10
+ protected
11
+
12
+ def resolve_path_with_load_paths(context, path, root_path, file)
13
+ context.resolve(file.to_s, load_paths: context.environment.paths, base_path: root_path, accept: syntax_mime_type(path))
14
+ rescue
15
+ nil
16
+ end
17
+
18
+ # Finds an asset from the given path. This is where
19
+ # we make Sprockets behave like Sass, and import partial
20
+ # style paths.
21
+ def resolve(context, path, base_path)
22
+ paths, root_path = possible_files(context, path, base_path)
23
+ paths.each do |file|
24
+ found_item = resolve_path_with_load_paths(context, path, root_path, file)
25
+ return found_item if !found_item.nil? && asset_requirable?(context, found_item)
26
+ end
27
+ nil
28
+ end
29
+
30
+ def stat_of_pathname(context, _pathname, path)
31
+ context.environment.stat(path)
32
+ end
33
+
34
+ def available_content_types(path)
35
+ ['text/css', syntax_mime_type(path), "text/#{syntax(path)}+ruby"].compact.uniq
36
+ end
37
+
38
+ def check_context_content_types(context, path)
39
+ available_mimes = available_content_types(path)
40
+ path_content_type, _attributes = content_type_of_path(context, path)
41
+ context.content_type.nil? || available_mimes.include?(path_content_type) || available_mimes.include?(context.content_type)
42
+ end
43
+
44
+ def asset_requirable?(context, path)
45
+ pathname = begin
46
+ context.resolve(path)
47
+ rescue
48
+ nil
49
+ end
50
+ return false if pathname.nil?
51
+ stat = stat_of_pathname(context, pathname, path)
52
+ return false unless stat && stat.file?
53
+ check_context_content_types(context, path)
54
+ end
55
+
56
+ # Finds all of the assets using the given glob.
57
+ def resolve_glob(context, glob, base_path)
58
+ base_path = Pathname.new(base_path)
59
+ path_with_glob = base_path.dirname.join(glob).to_s
60
+
61
+ Pathname.glob(path_with_glob).sort.select do |path|
62
+ asset_requirable = asset_requirable?(context, path)
63
+ path != context.pathname && asset_requirable
64
+ end
65
+ end
66
+
67
+ # Returns all of the possible paths (including partial variations)
68
+ # to attempt to resolve with the given path.
69
+ def possible_files(context, path, base_path)
70
+ paths, root_path = super(context, path, base_path)
71
+ paths = additional_paths_for_sprockets(context, paths, path, base_path)
72
+ [paths.compact, root_path]
73
+ end
74
+
75
+ def additional_paths_for_sprockets(context, paths, path, base_path)
76
+ relatives = paths.map { |path_detected| path_detected.to_s.start_with?('.') ? Pathname.new(path_detected) : Pathname.new(path_detected.to_s.prepend('./')) }
77
+ context.environment.paths.each do |load_path|
78
+ relative_path = Pathname.new(base_path).relative_path_from(Pathname.new(load_path)).join(path)
79
+ paths.unshift(relative_path, partialize_path(relative_path))
80
+ end
81
+ paths = paths.unshift(relatives)
82
+ paths
83
+ end
84
+
85
+ def filtered_processor_classes
86
+ classes = super
87
+ classes << Sprockets::Preprocessors::DefaultSourceMap if defined?(Sprockets::Preprocessors::DefaultSourceMap)
88
+ classes << Sprockets::SourceMapProcessor if defined?(Sprockets::SourceMapProcessor)
89
+ classes
90
+ end
91
+
92
+ def content_type_of_path(context, path)
93
+ attributes = context.environment.send(:parse_path_extnames, path.to_s)
94
+ content_type = attributes[1]
95
+ [content_type, attributes]
96
+ end
97
+
98
+ def build_input_for_process(context, path, data)
99
+ content_type, _attributes = content_type_of_path(context, path)
100
+ {
101
+ environment: context.environment,
102
+ cache: context.environment.cache,
103
+ uri: path.to_s,
104
+ filename: path.to_s,
105
+ load_path: context.environment.paths,
106
+ name: File.basename(path),
107
+ content_type: content_type,
108
+ data: data,
109
+ metadata: context.metadata
110
+ }
111
+ end
112
+
113
+ def check_path_before_process(_context, path)
114
+ path
115
+ end
116
+
117
+ def call_processor_input(processor, context, input, processors)
118
+ metadata = (input[:metadata] || {}).dup
119
+ metadata[:data] = input[:data]
120
+ result = processor.call(input)
121
+ processors.delete(processor)
122
+ handle_process_result(context, result, processors, metadata)
123
+ end
124
+
125
+ def handle_complex_process_result(context, result, processors)
126
+ data = result[:data] if result.key?(:data)
127
+ context.metadata.merge!(result)
128
+ context.metadata.delete(:data)
129
+ if result.key?(:required)
130
+ result[:required].each do |file|
131
+ file_asset = context.environment.load(file)
132
+ data += process(processors, context, file_asset.filename)
133
+ end
134
+ end
135
+ data
136
+ end
137
+
138
+ def handle_process_result(context, result, processors, metadata)
139
+ data = nil
140
+ case result
141
+ when NilClass
142
+ data = metadata[:data]
143
+ when Hash
144
+ data = handle_complex_process_result(context, result, processors)
145
+ when String
146
+ data = result
147
+ else
148
+ raise Error, "invalid processor return type: #{result.class}"
149
+ end
150
+ data
151
+ end
152
+
153
+ # Internal: Run processors on filename and data.
154
+ #
155
+ # Returns Hash.
156
+ def process(processors, context, path)
157
+ path = check_path_before_process(context, path)
158
+ data = Sprockets::Sass::Utils.read_template_file(path.to_s)
159
+ input = build_input_for_process(context, path, data)
160
+ processors.each do |processor|
161
+ data = call_processor_input(processor, context, input, processors)
162
+ end
163
+
164
+ data
165
+ end
166
+
167
+ def get_context_preprocessors(context, content_type)
168
+ context.environment.preprocessors[content_type].map { |a| a.class == Class ? a : a.class }
169
+ end
170
+
171
+ def get_context_transformers(context, content_type, path)
172
+ available_transformers = context.environment.transformers[content_type]
173
+ additional_transformers = available_transformers.key?(syntax_mime_type(path)) ? available_transformers[syntax_mime_type(path)] : []
174
+ additional_transformers.is_a?(Array) ? additional_transformers : [additional_transformers]
175
+ end
176
+
177
+ def get_engines_from_attributes(context, attributes)
178
+ engines = []
179
+ attributes[2].each do |extension|
180
+ ext = ::Sprockets::Utils.normalize_extension(extension)
181
+ ext_engines = context.environment.engines[ext]
182
+ ext_engines = ext_engines.is_a?(Array) ? ext_engines : [ext_engines]
183
+ engines.concat(ext_engines)
184
+ end
185
+ engines
186
+ end
187
+
188
+ def get_all_processors_for_evaluate(context, content_type, attributes, path)
189
+ engines = get_engines_from_attributes(context, attributes)
190
+ preprocessors = get_context_preprocessors(context, content_type)
191
+ additional_transformers = get_context_transformers(context, content_type, path)
192
+ postprocessors = get_context_postprocessors(context, content_type)
193
+ engines.reverse + preprocessors + additional_transformers.reverse + postprocessors
194
+ end
195
+
196
+ def get_context_postprocessors(context, content_type)
197
+ context.environment.postprocessors[content_type].map { |a| a.class == Class ? a : a.class }
198
+ end
199
+
200
+ def filter_all_processors(processors)
201
+ processors.delete_if do |processor|
202
+ filtered_processor_classes.include?(processor) || filtered_processor_classes.any? do |filtered_processor|
203
+ !processor.is_a?(Proc) && processor < filtered_processor
204
+ end
205
+ end
206
+ end
207
+
208
+ def evaluate_path_from_context(context, path, processors)
209
+ process(processors, context, path)
210
+ end
211
+
212
+ # Returns the string to be passed to the Sass engine. We use
213
+ # Sprockets to process the file, but we remove any Sass processors
214
+ # because we need to let the Sass::Engine handle that.
215
+ def evaluate(context, path)
216
+ content_type, attributes = content_type_of_path(context, path)
217
+ processors = get_all_processors_for_evaluate(context, content_type, attributes, path)
218
+ filter_all_processors(processors)
219
+ evaluate_path_from_context(context, path, processors)
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../v2/sass_template'
3
+ module Sprockets
4
+ module Sass
5
+ module V3
6
+ # Preprocessor for SASS files
7
+ class SassTemplate < Sprockets::Sass::V2::SassTemplate
8
+ def build_cache_store(context)
9
+ return nil if context.environment.cache.nil?
10
+ cache = @input[:cache]
11
+ version = @cache_version
12
+ if defined?(Sprockets::SassProcessor::CacheStore)
13
+ Sprockets::SassProcessor::CacheStore.new(cache, version)
14
+ else
15
+ custom_cache_store(cache, version)
16
+ end
17
+ end
18
+
19
+ def custom_cache_store(*args)
20
+ Sprockets::Sass::V3::CacheStore.new(*args)
21
+ end
22
+
23
+ # Allow the use of custom SASS importers, making sure the
24
+ # custom importer is a `Sprockets::Sass::Importer`
25
+ def fetch_importer_class
26
+ if defined?(@importer_class) && !@importer_class.nil?
27
+ @importer_class
28
+ elsif default_sass_options.key?(:importer) && default_sass_options[:importer].is_a?(Importer)
29
+ default_sass_options[:importer]
30
+ else
31
+ Sprockets::Sass::V3::Importer.new
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ require_relative './sass_template'
3
+ module Sprockets
4
+ module Sass
5
+ module V3
6
+ # Preprocessor for SCSS files
7
+ class ScssTemplate < Sprockets::Sass::V3::SassTemplate
8
+ # Define the expected syntax for the template
9
+ def self.syntax
10
+ :scss
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../v3/cache_store'
3
+ module Sprockets
4
+ module Sass
5
+ module V4
6
+ # Internal: Cache wrapper for Sprockets cache adapter. (Sprockets >= 3)
7
+ class CacheStore < Sprockets::Sass::V3::CacheStore
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../v3/compressor'
3
+ module Sprockets
4
+ module Sass
5
+ module V4
6
+ # Class used to compress CSS files
7
+ class Compressor < Sprockets::Sass::V3::Compressor
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../v3/functions'
3
+ module Sprockets
4
+ module Sass
5
+ module V4
6
+ # Module used to inject helpers into SASS engine
7
+ module Functions
8
+ include Sprockets::Sass::V3::Functions
9
+ end
10
+ end
11
+ end
12
+ end