sassc-embedded 1.63.0 → 1.78.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +89 -23
- data/lib/sassc/embedded/version.rb +1 -1
- data/lib/sassc/embedded.rb +266 -188
- data/vendor/github.com/sass/sassc-ruby/LICENSE.txt +22 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/dependency.rb +17 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/engine.rb +141 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/error.rb +37 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/functions_handler.rb +73 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/import_handler.rb +50 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/importer.rb +31 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/native_context_api.rb +147 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/native_functions_api.rb +159 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass2scss_api.rb +10 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass_input_style.rb +13 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass_output_style.rb +12 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/sass_value.rb +97 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native/string_list.rb +10 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/native.rb +64 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/sass_2_scss.rb +9 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/functions.rb +8 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/bool.rb +32 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/color.rb +95 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/list.rb +136 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/map.rb +69 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/number.rb +389 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value/string.rb +96 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value.rb +137 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/base.rb +13 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/color.rb +18 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/list.rb +25 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/map.rb +21 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/number.rb +13 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion/string.rb +17 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script/value_conversion.rb +69 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/script.rb +17 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/util/normalized_map.rb +117 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/util.rb +231 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc/version.rb +5 -0
- data/vendor/github.com/sass/sassc-ruby/lib/sassc.rb +64 -0
- metadata +49 -23
data/lib/sassc/embedded.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'sassc'
|
4
4
|
require 'sass-embedded'
|
5
5
|
|
6
|
-
require 'base64'
|
7
6
|
require 'json'
|
8
7
|
require 'uri'
|
9
8
|
|
@@ -11,14 +10,16 @@ require_relative 'embedded/version'
|
|
11
10
|
|
12
11
|
module SassC
|
13
12
|
class Engine
|
13
|
+
remove_method(:render) if public_method_defined?(:render, false)
|
14
|
+
|
14
15
|
def render
|
15
16
|
return @template.dup if @template.empty?
|
16
17
|
|
17
18
|
result = ::Sass.compile_string(
|
18
19
|
@template,
|
19
|
-
importer:
|
20
|
-
load_paths
|
21
|
-
syntax
|
20
|
+
importer: (NoopImporter unless @options[:importer].nil?),
|
21
|
+
load_paths:,
|
22
|
+
syntax:,
|
22
23
|
url: file_url,
|
23
24
|
|
24
25
|
charset: @options.fetch(:charset, true),
|
@@ -27,28 +28,28 @@ module SassC
|
|
27
28
|
style: output_style,
|
28
29
|
|
29
30
|
functions: functions_handler.setup(nil, functions: @functions),
|
30
|
-
importers: @options.fetch(:importers, []),
|
31
|
+
importers: import_handler.setup(nil).concat(@options.fetch(:importers, [])),
|
31
32
|
|
32
33
|
alert_ascii: @options.fetch(:alert_ascii, false),
|
33
34
|
alert_color: @options.fetch(:alert_color, nil),
|
34
|
-
|
35
|
+
fatal_deprecations: @options.fetch(:fatal_deprecations, []),
|
36
|
+
future_deprecations: @options.fetch(:future_deprecations, []),
|
37
|
+
logger: quiet? ? ::Sass::Logger.silent : @options.fetch(:logger, nil),
|
35
38
|
quiet_deps: @options.fetch(:quiet_deps, false),
|
39
|
+
silence_deprecations: @options.fetch(:silence_deprecations, []),
|
36
40
|
verbose: @options.fetch(:verbose, false)
|
37
41
|
)
|
38
42
|
|
39
43
|
@loaded_urls = result.loaded_urls
|
40
44
|
@source_map = result.source_map
|
41
45
|
|
42
|
-
return if quiet?
|
43
|
-
|
44
46
|
css = result.css
|
45
47
|
css += "\n" unless css.empty?
|
46
48
|
unless @source_map.nil? || omit_source_map_url?
|
47
|
-
url = URL.parse(output_url || file_url)
|
48
49
|
source_mapping_url = if source_map_embed?
|
49
|
-
"data:application/json;base64,#{
|
50
|
+
"data:application/json;base64,#{[@source_map].pack('m0')}"
|
50
51
|
else
|
51
|
-
|
52
|
+
Uri.file_urls_to_relative_url(source_map_file_url, file_url)
|
52
53
|
end
|
53
54
|
css += "\n/*# sourceMappingURL=#{source_mapping_url} */"
|
54
55
|
end
|
@@ -59,27 +60,30 @@ module SassC
|
|
59
60
|
line = e.span&.start&.line
|
60
61
|
line += 1 unless line.nil?
|
61
62
|
url = e.span&.url
|
62
|
-
path = (
|
63
|
-
raise SyntaxError.new(e.full_message, filename: path, line:
|
63
|
+
path = (Uri.file_urls_to_relative_path(url, Uri.path_to_file_url("#{Dir.pwd}/")) if url&.start_with?('file:'))
|
64
|
+
raise SyntaxError.new(e.full_message, filename: path, line:)
|
64
65
|
end
|
65
66
|
|
67
|
+
remove_method(:dependencies) if public_method_defined?(:dependencies, false)
|
68
|
+
|
66
69
|
def dependencies
|
67
70
|
raise NotRenderedError unless @loaded_urls
|
68
71
|
|
69
|
-
Dependency.from_filenames(@loaded_urls
|
70
|
-
.
|
71
|
-
|
72
|
+
Dependency.from_filenames(@loaded_urls.filter_map do |url|
|
73
|
+
Uri.file_url_to_path(url) if url.start_with?('file:') && !url.include?('?') && url != file_url
|
74
|
+
end)
|
72
75
|
end
|
73
76
|
|
77
|
+
remove_method(:source_map) if public_method_defined?(:source_map, false)
|
78
|
+
|
74
79
|
def source_map
|
75
80
|
raise NotRenderedError unless @source_map
|
76
81
|
|
77
|
-
url =
|
82
|
+
url = Uri.parse(source_map_file_url || file_url)
|
78
83
|
data = JSON.parse(@source_map)
|
79
|
-
data['file'] = URL.parse(output_url).route_from(url).to_s if output_url
|
80
84
|
data['sources'].map! do |source|
|
81
|
-
if source.start_with?(
|
82
|
-
|
85
|
+
if source.start_with?('file:')
|
86
|
+
Uri.file_urls_to_relative_url(source, url)
|
83
87
|
else
|
84
88
|
source
|
85
89
|
end
|
@@ -91,35 +95,29 @@ module SassC
|
|
91
95
|
private
|
92
96
|
|
93
97
|
def file_url
|
94
|
-
@file_url ||=
|
95
|
-
end
|
96
|
-
|
97
|
-
def output_path
|
98
|
-
@output_path ||= @options.fetch(:output_path) do
|
99
|
-
"#{filename.delete_suffix(File.extname(filename))}.css" if filename
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def output_url
|
104
|
-
@output_url ||= (URL.path_to_file_url(File.absolute_path(output_path)) if output_path)
|
98
|
+
@file_url ||= Uri.path_to_file_url(File.absolute_path(filename || 'stdin'))
|
105
99
|
end
|
106
100
|
|
107
101
|
def source_map_file_url
|
108
|
-
@source_map_file_url ||=
|
102
|
+
@source_map_file_url ||= if source_map_file
|
103
|
+
Uri.path_to_file_url(File.absolute_path(source_map_file))
|
104
|
+
.gsub('%3F', '?') # https://github.com/sass-contrib/sassc-embedded-shim-ruby/pull/69
|
105
|
+
end
|
109
106
|
end
|
110
107
|
|
108
|
+
remove_method(:output_style) if private_method_defined?(:output_style, false)
|
109
|
+
|
111
110
|
def output_style
|
112
111
|
@output_style ||= begin
|
113
|
-
style = @options.fetch(:style, :sass_style_nested).to_s
|
114
|
-
style = "sass_style_#{style}" unless style.start_with?('sass_style_')
|
115
|
-
raise InvalidStyleError unless OUTPUT_STYLES.include?(style.to_sym)
|
112
|
+
style = @options.fetch(:style, :sass_style_nested).to_s.delete_prefix('sass_style_').to_sym
|
116
113
|
|
117
|
-
style = style.delete_prefix('sass_style_').to_sym
|
118
114
|
case style
|
119
|
-
when :nested, :compact
|
115
|
+
when :nested, :compact, :expanded
|
120
116
|
:expanded
|
117
|
+
when :compressed
|
118
|
+
:compressed
|
121
119
|
else
|
122
|
-
|
120
|
+
raise InvalidStyleError
|
123
121
|
end
|
124
122
|
end
|
125
123
|
end
|
@@ -130,16 +128,16 @@ module SassC
|
|
130
128
|
syntax
|
131
129
|
end
|
132
130
|
|
131
|
+
remove_method(:load_paths) if private_method_defined?(:load_paths, false)
|
132
|
+
|
133
133
|
def load_paths
|
134
|
-
@load_paths ||=
|
135
|
-
(@options[:load_paths] || []) + SassC.load_paths
|
136
|
-
else
|
137
|
-
[]
|
138
|
-
end
|
134
|
+
@load_paths ||= (@options[:load_paths] || []) + SassC.load_paths
|
139
135
|
end
|
140
136
|
end
|
141
137
|
|
142
138
|
class FunctionsHandler
|
139
|
+
remove_method(:setup) if public_method_defined?(:setup, false)
|
140
|
+
|
143
141
|
def setup(_native_options, functions: Script::Functions)
|
144
142
|
@callbacks = {}
|
145
143
|
|
@@ -150,7 +148,7 @@ module SassC
|
|
150
148
|
end.new
|
151
149
|
functions_wrapper.options = @options
|
152
150
|
|
153
|
-
Script.custom_functions(functions:
|
151
|
+
Script.custom_functions(functions:).each do |custom_function|
|
154
152
|
callback = lambda do |native_argument_list|
|
155
153
|
function_arguments = arguments_from_native_list(native_argument_list)
|
156
154
|
begin
|
@@ -164,7 +162,7 @@ module SassC
|
|
164
162
|
raise e
|
165
163
|
end
|
166
164
|
|
167
|
-
@callbacks[Script.formatted_function_name(custom_function, functions:
|
165
|
+
@callbacks[Script.formatted_function_name(custom_function, functions:)] = callback
|
168
166
|
end
|
169
167
|
|
170
168
|
@callbacks
|
@@ -172,40 +170,66 @@ module SassC
|
|
172
170
|
|
173
171
|
private
|
174
172
|
|
173
|
+
remove_method(:arguments_from_native_list) if private_method_defined?(:arguments_from_native_list, false)
|
174
|
+
|
175
175
|
def arguments_from_native_list(native_argument_list)
|
176
176
|
native_argument_list.filter_map do |native_value|
|
177
177
|
Script::ValueConversion.from_native(native_value, @options)
|
178
178
|
end
|
179
179
|
end
|
180
|
+
end
|
180
181
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
rescue StandardError => e
|
188
|
-
unless e.full_message.include?(e.cause.full_message)
|
189
|
-
::Sass::ScriptError.class_eval do
|
190
|
-
def full_message(...)
|
191
|
-
full_message = super(...)
|
192
|
-
if cause
|
193
|
-
"#{full_message}\n#{cause.full_message(...)}"
|
194
|
-
else
|
195
|
-
full_message
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
182
|
+
module NoopImporter
|
183
|
+
module_function
|
184
|
+
|
185
|
+
def canonicalize(...); end
|
186
|
+
|
187
|
+
def load(...); end
|
201
188
|
end
|
202
189
|
|
190
|
+
private_constant :NoopImporter
|
191
|
+
|
203
192
|
class ImportHandler
|
193
|
+
remove_method(:setup) if public_method_defined?(:setup, false)
|
194
|
+
|
204
195
|
def setup(_native_options)
|
205
|
-
|
196
|
+
if @importer
|
197
|
+
import_cache = ImportCache.new(@importer)
|
198
|
+
[Importer.new(import_cache), FileImporter.new(import_cache)]
|
199
|
+
else
|
200
|
+
[]
|
201
|
+
end
|
206
202
|
end
|
207
203
|
|
204
|
+
class Importer
|
205
|
+
def initialize(import_cache)
|
206
|
+
@import_cache = import_cache
|
207
|
+
end
|
208
|
+
|
209
|
+
def canonicalize(...)
|
210
|
+
@import_cache.canonicalize(...)
|
211
|
+
end
|
212
|
+
|
213
|
+
def load(...)
|
214
|
+
@import_cache.load(...)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
private_constant :Importer
|
219
|
+
|
208
220
|
class FileImporter
|
221
|
+
def initialize(import_cache)
|
222
|
+
@import_cache = import_cache
|
223
|
+
end
|
224
|
+
|
225
|
+
def find_file_url(...)
|
226
|
+
@import_cache.find_file_url(...)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
private_constant :FileImporter
|
231
|
+
|
232
|
+
module FileSystemImporter
|
209
233
|
class << self
|
210
234
|
def resolve_path(path, from_import)
|
211
235
|
ext = File.extname(path)
|
@@ -217,15 +241,6 @@ module SassC
|
|
217
241
|
return exactly_one(try_path(path))
|
218
242
|
end
|
219
243
|
|
220
|
-
unless ext.empty?
|
221
|
-
if from_import
|
222
|
-
result = exactly_one(try_path("#{without_ext(path)}.import#{ext}"))
|
223
|
-
return result unless result.nil?
|
224
|
-
end
|
225
|
-
result = exactly_one(try_path(path))
|
226
|
-
return result unless result.nil?
|
227
|
-
end
|
228
|
-
|
229
244
|
if from_import
|
230
245
|
result = exactly_one(try_path_with_ext("#{path}.import"))
|
231
246
|
return result unless result.nil?
|
@@ -253,7 +268,7 @@ module SassC
|
|
253
268
|
end
|
254
269
|
|
255
270
|
def try_path_as_dir(path, from_import)
|
256
|
-
return unless dir_exist?
|
271
|
+
return unless dir_exist?(path)
|
257
272
|
|
258
273
|
if from_import
|
259
274
|
result = exactly_one(try_path_with_ext(File.join(path, 'index.import')))
|
@@ -265,7 +280,7 @@ module SassC
|
|
265
280
|
|
266
281
|
def exactly_one(paths)
|
267
282
|
return if paths.empty?
|
268
|
-
return paths.first if paths.
|
283
|
+
return paths.first if paths.one?
|
269
284
|
|
270
285
|
raise "It's not clear which file to import. Found:\n#{paths.map { |path| " #{path}" }.join("\n")}"
|
271
286
|
end
|
@@ -285,79 +300,63 @@ module SassC
|
|
285
300
|
end
|
286
301
|
end
|
287
302
|
|
288
|
-
private_constant :
|
303
|
+
private_constant :FileSystemImporter
|
289
304
|
|
290
|
-
class
|
305
|
+
class ImportCache
|
291
306
|
def initialize(importer)
|
292
307
|
@importer = importer
|
293
|
-
|
294
|
-
@canonical_urls = {}
|
295
|
-
@id = 0
|
296
308
|
@importer_results = {}
|
297
|
-
@
|
309
|
+
@importer_result = nil
|
310
|
+
@file_url = nil
|
298
311
|
end
|
299
312
|
|
300
|
-
def canonicalize(url,
|
301
|
-
|
302
|
-
|
313
|
+
def canonicalize(url, context)
|
314
|
+
return unless context.containing_url&.start_with?('file:')
|
315
|
+
|
316
|
+
containing_url = context.containing_url
|
317
|
+
|
318
|
+
path = Uri.decode_uri_component(url)
|
319
|
+
parent_path = Uri.file_url_to_path(containing_url)
|
320
|
+
parent_dir = File.dirname(parent_path)
|
321
|
+
|
322
|
+
if containing_url.include?('?')
|
323
|
+
canonical_url = Uri.path_to_file_url(File.absolute_path(path, parent_dir))
|
303
324
|
unless @importer_results.key?(canonical_url)
|
304
|
-
|
325
|
+
@file_url = resolve_file_url(path, parent_dir, context.from_import)
|
326
|
+
return
|
305
327
|
end
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
imports = @importer.imports(path, parent_path)
|
313
|
-
imports = [SassC::Importer::Import.new(path)] if imports.nil?
|
314
|
-
imports = [imports] unless imports.is_a?(Array)
|
315
|
-
imports.each do |import|
|
316
|
-
import.path = File.absolute_path(import.path, File.dirname(parent_path))
|
328
|
+
else
|
329
|
+
imports = [*@importer.imports(path, parent_path)]
|
330
|
+
canonical_url = imports_to_native(imports, parent_dir, context.from_import, url, containing_url)
|
331
|
+
unless @importer_results.key?(canonical_url)
|
332
|
+
@file_url = canonical_url
|
333
|
+
return
|
317
334
|
end
|
318
|
-
|
319
|
-
canonical_url = "#{Protocol::IMPORT}#{next_id}"
|
320
|
-
@importer_results[canonical_url] = imports_to_native(imports)
|
321
|
-
canonical_url
|
322
|
-
elsif url.start_with?(Protocol::LOADED)
|
323
|
-
canonical_url = Protocol::LOADED
|
324
|
-
@parent_urls.pop
|
325
|
-
canonical_url
|
326
335
|
end
|
336
|
+
|
337
|
+
@importer_result = @importer_results.delete(canonical_url)
|
338
|
+
canonical_url
|
327
339
|
end
|
328
340
|
|
329
|
-
def load(
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
path = URL.file_url_to_path(canonical_url)
|
334
|
-
{
|
335
|
-
contents: File.read(path),
|
336
|
-
syntax: syntax(path),
|
337
|
-
source_map_url: canonical_url
|
338
|
-
}
|
339
|
-
elsif canonical_url.start_with?(Protocol::LOADED)
|
340
|
-
{
|
341
|
-
contents: '',
|
342
|
-
syntax: :scss
|
343
|
-
}
|
344
|
-
end
|
341
|
+
def load(_canonical_url)
|
342
|
+
importer_result = @importer_result
|
343
|
+
@importer_result = nil
|
344
|
+
importer_result
|
345
345
|
end
|
346
346
|
|
347
|
-
|
347
|
+
def find_file_url(_url, context)
|
348
|
+
return if context.containing_url.nil? || @file_url.nil?
|
348
349
|
|
349
|
-
|
350
|
-
@
|
350
|
+
canonical_url = @file_url
|
351
|
+
@file_url = nil
|
352
|
+
canonical_url
|
351
353
|
end
|
352
354
|
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
return URL.path_to_file_url(resolved) unless resolved.nil?
|
359
|
-
end
|
360
|
-
nil
|
355
|
+
private
|
356
|
+
|
357
|
+
def resolve_file_url(path, parent_dir, from_import)
|
358
|
+
resolved = FileSystemImporter.resolve_path(File.absolute_path(path, parent_dir), from_import)
|
359
|
+
Uri.path_to_file_url(resolved) unless resolved.nil?
|
361
360
|
end
|
362
361
|
|
363
362
|
def syntax(path)
|
@@ -371,47 +370,55 @@ module SassC
|
|
371
370
|
end
|
372
371
|
end
|
373
372
|
|
374
|
-
def
|
375
|
-
|
373
|
+
def import_to_native(import, parent_dir, from_import, canonicalize)
|
374
|
+
if import.source
|
375
|
+
canonical_url = Uri.path_to_file_url(File.absolute_path(import.path, parent_dir))
|
376
|
+
@importer_results[canonical_url] = if import.source.is_a?(Hash)
|
377
|
+
{
|
378
|
+
contents: import.source[:contents],
|
379
|
+
syntax: import.source[:syntax],
|
380
|
+
source_map_url: canonical_url
|
381
|
+
}
|
382
|
+
else
|
383
|
+
{
|
384
|
+
contents: import.source,
|
385
|
+
syntax: syntax(import.path),
|
386
|
+
source_map_url: canonical_url
|
387
|
+
}
|
388
|
+
end
|
389
|
+
return canonical_url if canonicalize
|
390
|
+
elsif canonicalize
|
391
|
+
return resolve_file_url(import.path, parent_dir, from_import)
|
392
|
+
end
|
393
|
+
|
394
|
+
Uri.encode_uri_path_component(import.path)
|
395
|
+
end
|
396
|
+
|
397
|
+
def imports_to_native(imports, parent_dir, from_import, url, containing_url)
|
398
|
+
return import_to_native(imports.first, parent_dir, from_import, true) if imports.one?
|
399
|
+
|
400
|
+
canonical_url = "#{containing_url}?url=#{Uri.encode_uri_query_component(url)}&from_import=#{from_import}"
|
401
|
+
@importer_results[canonical_url] = {
|
376
402
|
contents: imports.flat_map do |import|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
if import.source
|
381
|
-
@importer_results[canonical_url] = if import.source.is_a?(Hash)
|
382
|
-
{
|
383
|
-
contents: import.source[:contents],
|
384
|
-
syntax: import.source[:syntax],
|
385
|
-
source_map_url: canonical_url
|
386
|
-
}
|
387
|
-
else
|
388
|
-
{
|
389
|
-
contents: import.source,
|
390
|
-
syntax: syntax(import.path),
|
391
|
-
source_map_url: canonical_url
|
392
|
-
}
|
393
|
-
end
|
394
|
-
end
|
395
|
-
[
|
396
|
-
"@import \"#{Protocol::IMPORT}#{id}\";",
|
397
|
-
"@import \"#{Protocol::LOADED}#{id}\";"
|
398
|
-
]
|
403
|
+
at_rule = from_import ? '@import' : '@forward'
|
404
|
+
url = import_to_native(import, parent_dir, from_import, false)
|
405
|
+
"#{at_rule} #{Script::Value::String.quote(url)};"
|
399
406
|
end.join("\n"),
|
400
407
|
syntax: :scss
|
401
408
|
}
|
402
|
-
end
|
403
409
|
|
404
|
-
|
405
|
-
id = @id
|
406
|
-
@id = id.next
|
407
|
-
id.to_s
|
410
|
+
canonical_url
|
408
411
|
end
|
409
412
|
end
|
410
413
|
|
411
|
-
private_constant :
|
414
|
+
private_constant :ImportCache
|
412
415
|
end
|
413
416
|
|
414
417
|
class Sass2Scss
|
418
|
+
class << self
|
419
|
+
remove_method(:convert) if public_method_defined?(:convert, false)
|
420
|
+
end
|
421
|
+
|
415
422
|
def self.convert(sass)
|
416
423
|
{
|
417
424
|
contents: sass,
|
@@ -421,7 +428,38 @@ module SassC
|
|
421
428
|
end
|
422
429
|
|
423
430
|
module Script
|
431
|
+
class Value
|
432
|
+
class String
|
433
|
+
class << self
|
434
|
+
remove_method(:quote) if public_method_defined?(:quote, false)
|
435
|
+
end
|
436
|
+
|
437
|
+
# Returns the quoted string representation of `contents`.
|
438
|
+
#
|
439
|
+
# @options opts :quote [String]
|
440
|
+
# The preferred quote style for quoted strings. If `:none`, strings are
|
441
|
+
# always emitted unquoted. If `nil`, quoting is determined automatically.
|
442
|
+
# @options opts :sass [String]
|
443
|
+
# Whether to quote strings for Sass source, as opposed to CSS. Defaults to `false`.
|
444
|
+
def self.quote(contents, opts = {})
|
445
|
+
contents = ::Sass::Value::String.new(contents, quoted: opts[:quote] != :none).to_s
|
446
|
+
opts[:sass] ? contents.gsub('#', '\#') : contents
|
447
|
+
end
|
448
|
+
|
449
|
+
remove_method(:to_s) if public_method_defined?(:to_s, false)
|
450
|
+
|
451
|
+
def to_s(opts = {})
|
452
|
+
opts = { quote: :none }.merge!(opts) if @type == :identifier
|
453
|
+
self.class.quote(@value, opts)
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
424
458
|
module ValueConversion
|
459
|
+
class << self
|
460
|
+
remove_method(:from_native) if public_method_defined?(:from_native, false)
|
461
|
+
end
|
462
|
+
|
425
463
|
def self.from_native(value, options)
|
426
464
|
case value
|
427
465
|
when ::Sass::Value::Null::NULL
|
@@ -477,6 +515,10 @@ module SassC
|
|
477
515
|
end
|
478
516
|
end
|
479
517
|
|
518
|
+
class << self
|
519
|
+
remove_method(:to_native) if public_method_defined?(:to_native, false)
|
520
|
+
end
|
521
|
+
|
480
522
|
def self.to_native(value)
|
481
523
|
case value
|
482
524
|
when nil
|
@@ -537,48 +579,84 @@ module SassC
|
|
537
579
|
end
|
538
580
|
end
|
539
581
|
|
540
|
-
module
|
541
|
-
|
542
|
-
IMPORT = 'sassc-embedded-import:'
|
543
|
-
LOADED = 'sassc-embedded-loaded:'
|
544
|
-
end
|
582
|
+
module Uri
|
583
|
+
module_function
|
545
584
|
|
546
|
-
|
585
|
+
def parse(...)
|
586
|
+
::URI::RFC3986_PARSER.parse(...)
|
587
|
+
end
|
547
588
|
|
548
|
-
|
549
|
-
|
589
|
+
encode_uri_hash = {}
|
590
|
+
decode_uri_hash = {}
|
591
|
+
256.times do |i|
|
592
|
+
c = -[i].pack('C')
|
593
|
+
h = c.unpack1('H')
|
594
|
+
l = c.unpack1('h')
|
595
|
+
pdd = -"%#{h}#{l}"
|
596
|
+
pdu = -"%#{h}#{l.upcase}"
|
597
|
+
pud = -"%#{h.upcase}#{l}"
|
598
|
+
puu = -pdd.upcase
|
599
|
+
encode_uri_hash[c] = puu
|
600
|
+
decode_uri_hash[pdd] = c
|
601
|
+
decode_uri_hash[pdu] = c
|
602
|
+
decode_uri_hash[pud] = c
|
603
|
+
decode_uri_hash[puu] = c
|
604
|
+
end.freeze
|
605
|
+
encode_uri_hash.freeze
|
606
|
+
decode_uri_hash.freeze
|
607
|
+
|
608
|
+
{
|
609
|
+
uri_path_component: "!$&'()*+,;=:/@",
|
610
|
+
uri_query_component: "!$&'()*+,;=:/?@",
|
611
|
+
uri_component: nil,
|
612
|
+
uri: "!$&'()*+,;=:/?#[]@"
|
613
|
+
}
|
614
|
+
.each do |symbol, unescaped|
|
615
|
+
encode_regexp = Regexp.new("[^0-9A-Za-z#{Regexp.escape("-._~#{unescaped}")}]", Regexp::NOENCODING)
|
616
|
+
|
617
|
+
define_method(:"encode_#{symbol}") do |str|
|
618
|
+
str.b.gsub(encode_regexp, encode_uri_hash).force_encoding(str.encoding)
|
619
|
+
end
|
550
620
|
|
551
|
-
|
621
|
+
next if symbol.match?(/_.+_/o)
|
552
622
|
|
553
|
-
|
623
|
+
decode_regexp = /%[0-9A-Fa-f]{2}/o
|
624
|
+
decode_uri_hash_with_preserve_escaped = if unescaped.nil? || unescaped.empty?
|
625
|
+
decode_uri_hash
|
626
|
+
else
|
627
|
+
decode_uri_hash.to_h do |key, value|
|
628
|
+
[key, unescaped.include?(value) ? key : value]
|
629
|
+
end.freeze
|
630
|
+
end
|
554
631
|
|
555
|
-
|
556
|
-
|
557
|
-
|
632
|
+
define_method(:"decode_#{symbol}") do |str|
|
633
|
+
str.gsub(decode_regexp, decode_uri_hash_with_preserve_escaped).force_encoding(str.encoding)
|
634
|
+
end
|
635
|
+
end
|
558
636
|
|
559
|
-
def
|
560
|
-
|
637
|
+
def file_urls_to_relative_url(url, from_url)
|
638
|
+
parse(url).route_from(from_url).to_s
|
561
639
|
end
|
562
640
|
|
563
|
-
def
|
564
|
-
|
641
|
+
def file_urls_to_relative_path(url, from_url)
|
642
|
+
decode_uri_component(file_urls_to_relative_url(url, from_url))
|
565
643
|
end
|
566
644
|
|
567
645
|
def file_url_to_path(url)
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
646
|
+
path = decode_uri_component(parse(url).path)
|
647
|
+
if path.start_with?('/')
|
648
|
+
windows_path = path[1..]
|
649
|
+
path = windows_path if File.absolute_path?(windows_path)
|
650
|
+
end
|
572
651
|
path
|
573
652
|
end
|
574
653
|
|
575
654
|
def path_to_file_url(path)
|
576
|
-
return if path.nil?
|
577
|
-
|
578
655
|
path = "/#{path}" unless path.start_with?('/')
|
579
|
-
|
656
|
+
|
657
|
+
"file://#{encode_uri_path_component(path)}"
|
580
658
|
end
|
581
659
|
end
|
582
660
|
|
583
|
-
private_constant :
|
661
|
+
private_constant :Uri
|
584
662
|
end
|