sassc-embedded 1.1.1 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -2
- data/lib/sassc/embedded/version.rb +1 -1
- data/lib/sassc/embedded.rb +192 -72
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ff232a1e9ffcdb66044bbf2bf16cb7f30e103391a59c8d77198a2c273fb23ee
|
4
|
+
data.tar.gz: b9f778ee93529d8ea8fd78e117938dbefd85effbade12914b4766f6b462516cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afe628bdf03866ce81814e6063075c7fde3b5dcd577a5f2f914feb65d71f343992f34d96b943669c10cb0ccc5c6655f9816092a347c5173d3a83abd4e2ddb3eb
|
7
|
+
data.tar.gz: df0aac452aca91d9df03785bfd61c09ac75b6fcc0506316bc5ddf800634cde576e1f0b526735a7d5ed5f61506d81db9e01b41f23dd5a938070b546f17131a16c
|
data/README.md
CHANGED
@@ -51,6 +51,4 @@ See [rubydoc.info/gems/sassc](https://rubydoc.info/gems/sassc) for full API docu
|
|
51
51
|
|
52
52
|
4. Option `:line_comments` is ignored.
|
53
53
|
|
54
|
-
5. Argument `parent_path` in `Importer#imports(path, parent_path)` is set to value of option `:filename`.
|
55
|
-
|
56
54
|
See [the dart-sass documentation](https://github.com/sass/dart-sass#behavioral-differences-from-ruby-sass) for other differences.
|
data/lib/sassc/embedded.rb
CHANGED
@@ -17,7 +17,7 @@ module SassC
|
|
17
17
|
|
18
18
|
result = ::Sass.compile_string(
|
19
19
|
@template,
|
20
|
-
importer: nil,
|
20
|
+
importer: import_handler.setup(nil),
|
21
21
|
load_paths: load_paths,
|
22
22
|
syntax: syntax,
|
23
23
|
url: file_url,
|
@@ -26,8 +26,8 @@ module SassC
|
|
26
26
|
source_map_include_sources: source_map_contents?,
|
27
27
|
style: output_style,
|
28
28
|
|
29
|
-
functions:
|
30
|
-
importers:
|
29
|
+
functions: functions_handler.setup(nil, functions: @functions),
|
30
|
+
importers: [],
|
31
31
|
|
32
32
|
alert_ascii: @options.fetch(:alert_ascii, false),
|
33
33
|
alert_color: @options.fetch(:alert_color, nil),
|
@@ -45,30 +45,25 @@ module SassC
|
|
45
45
|
rescue ::Sass::CompileError => e
|
46
46
|
line = e.span&.start&.line
|
47
47
|
line += 1 unless line.nil?
|
48
|
-
|
48
|
+
url = e.span&.url
|
49
|
+
path = url&.start_with?('file:') ? URL.file_url_to_path(url) : nil
|
49
50
|
path = relative_path(Dir.pwd, path) unless path.nil?
|
50
51
|
raise SyntaxError.new(e.message, filename: path, line: line)
|
51
52
|
end
|
52
53
|
|
53
54
|
private
|
54
55
|
|
56
|
+
def file_url
|
57
|
+
@file_url ||= URL.path_to_file_url(File.absolute_path(filename || 'stdin'))
|
58
|
+
end
|
59
|
+
|
55
60
|
def output_path
|
56
61
|
@output_path ||= @options.fetch(
|
57
62
|
:output_path,
|
58
|
-
("#{
|
63
|
+
("#{filename.delete_suffix(File.extname(filename))}.css" if filename)
|
59
64
|
)
|
60
65
|
end
|
61
66
|
|
62
|
-
def file_url
|
63
|
-
@file_url ||= URL.path_to_file_url(filename || 'stdin')
|
64
|
-
end
|
65
|
-
|
66
|
-
def syntax
|
67
|
-
syntax = @options.fetch(:syntax, :scss)
|
68
|
-
syntax = :indented if syntax.to_sym == :sass
|
69
|
-
syntax
|
70
|
-
end
|
71
|
-
|
72
67
|
def output_style
|
73
68
|
@output_style ||= begin
|
74
69
|
style = @options.fetch(:style, :sass_style_nested).to_s
|
@@ -87,8 +82,18 @@ module SassC
|
|
87
82
|
end
|
88
83
|
end
|
89
84
|
|
85
|
+
def syntax
|
86
|
+
syntax = @options.fetch(:syntax, :scss)
|
87
|
+
syntax = :indented if syntax.to_sym == :sass
|
88
|
+
syntax
|
89
|
+
end
|
90
|
+
|
90
91
|
def load_paths
|
91
|
-
@load_paths ||=
|
92
|
+
@load_paths ||= if @options[:importer].nil?
|
93
|
+
(@options[:load_paths] || []) + SassC.load_paths
|
94
|
+
else
|
95
|
+
[]
|
96
|
+
end
|
92
97
|
end
|
93
98
|
|
94
99
|
def post_process_source_map(source_map)
|
@@ -192,86 +197,196 @@ module SassC
|
|
192
197
|
|
193
198
|
class ImportHandler
|
194
199
|
def setup(_native_options)
|
195
|
-
if @importer
|
196
|
-
[FileImporter.new, Importer.new(@importer)]
|
197
|
-
else
|
198
|
-
[FileImporter.new]
|
199
|
-
end
|
200
|
+
Importer.new(@importer) if @importer
|
200
201
|
end
|
201
202
|
|
202
203
|
class FileImporter
|
203
|
-
|
204
|
-
|
204
|
+
class << self
|
205
|
+
def resolve_path(path, from_import)
|
206
|
+
ext = File.extname(path)
|
207
|
+
unless ext.empty?
|
208
|
+
if from_import
|
209
|
+
result = exactly_one(try_path("#{without_ext(path)}.import#{ext}"))
|
210
|
+
return result unless result.nil?
|
211
|
+
end
|
212
|
+
return exactly_one(try_path(path))
|
213
|
+
end
|
214
|
+
|
215
|
+
if from_import
|
216
|
+
result = exactly_one(try_path_with_ext("#{path}.import"))
|
217
|
+
return result unless result.nil?
|
218
|
+
end
|
219
|
+
|
220
|
+
result = exactly_one(try_path_with_ext(path))
|
221
|
+
return result unless result.nil?
|
222
|
+
|
223
|
+
try_path_as_dir(path, from_import)
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def try_path_with_ext(path)
|
229
|
+
result = try_path("#{path}.sass") + try_path("#{path}.scss")
|
230
|
+
result.empty? ? try_path("#{path}.css") : result
|
231
|
+
end
|
232
|
+
|
233
|
+
def try_path(path)
|
234
|
+
partial = File.join(File.dirname(path), "_#{File.basename(path)}")
|
235
|
+
result = []
|
236
|
+
result.push(partial) if file_exist?(partial)
|
237
|
+
result.push(path) if file_exist?(path)
|
238
|
+
result
|
239
|
+
end
|
240
|
+
|
241
|
+
def try_path_as_dir(path, from_import)
|
242
|
+
return unless dir_exist? path
|
243
|
+
|
244
|
+
if from_import
|
245
|
+
result = exactly_one(try_path_with_ext(File.join(path, 'index.import')))
|
246
|
+
return result unless result.nil?
|
247
|
+
end
|
248
|
+
|
249
|
+
exactly_one(try_path_with_ext(File.join(path, 'index')))
|
250
|
+
end
|
251
|
+
|
252
|
+
def exactly_one(paths)
|
253
|
+
return if paths.empty?
|
254
|
+
return paths.first if paths.length == 1
|
255
|
+
|
256
|
+
raise "It's not clear which file to import. Found:\n#{paths.map { |path| " #{path}" }.join("\n")}"
|
257
|
+
end
|
258
|
+
|
259
|
+
def file_exist?(path)
|
260
|
+
File.exist?(path) && File.file?(path)
|
261
|
+
end
|
262
|
+
|
263
|
+
def dir_exist?(path)
|
264
|
+
File.exist?(path) && File.directory?(path)
|
265
|
+
end
|
266
|
+
|
267
|
+
def without_ext(path)
|
268
|
+
ext = File.extname(path)
|
269
|
+
path.delete_suffix(ext)
|
270
|
+
end
|
205
271
|
end
|
206
272
|
end
|
207
273
|
|
208
274
|
private_constant :FileImporter
|
209
275
|
|
210
276
|
class Importer
|
277
|
+
module Protocol
|
278
|
+
FILE = 'file:'
|
279
|
+
IMPORT = 'sassc-embedded-import:'
|
280
|
+
LOAD = 'sassc-embedded-load:'
|
281
|
+
LOADED = 'sassc-embedded-loaded:'
|
282
|
+
end
|
283
|
+
|
284
|
+
private_constant :Protocol
|
285
|
+
|
211
286
|
def initialize(importer)
|
212
287
|
@importer = importer
|
213
288
|
@importer_results = {}
|
289
|
+
@base_url = URL.parse(URL.path_to_file_url("#{File.absolute_path('')}/"))
|
290
|
+
@parent_urls = [URL.parse(URL.path_to_file_url(File.absolute_path(@importer.options[:filename] || 'stdin')))]
|
214
291
|
end
|
215
292
|
|
216
|
-
def canonicalize(url,
|
217
|
-
|
218
|
-
URL.file_url_to_path(url)
|
219
|
-
else
|
220
|
-
URL.unescape(url)
|
221
|
-
end
|
222
|
-
canonical_url = URL.path_to_file_url(File.absolute_path(path))
|
293
|
+
def canonicalize(url, from_import:)
|
294
|
+
return url if url.start_with?(Protocol::IMPORT, Protocol::LOADED)
|
223
295
|
|
224
|
-
if
|
225
|
-
|
296
|
+
if url.start_with?(Protocol::LOAD)
|
297
|
+
url = url.delete_prefix(Protocol::LOAD)
|
298
|
+
return url if @importer_results.key?(url)
|
226
299
|
|
227
|
-
|
300
|
+
path = URL.parse(url).route_from(@parent_urls.last).to_s
|
301
|
+
resolved = resolve_path(path, URL.file_url_to_path(@parent_urls.last.to_s), from_import)
|
302
|
+
return resolved.nil? ? nil : URL.path_to_file_url(resolved)
|
228
303
|
end
|
229
304
|
|
230
|
-
|
305
|
+
return unless url.start_with?(Protocol::FILE)
|
231
306
|
|
232
|
-
|
233
|
-
|
234
|
-
return if imports.path == path
|
307
|
+
path = URL.parse(url).route_from(@parent_urls.last).to_s
|
308
|
+
parent_path = URL.file_url_to_path(@parent_urls.last.to_s)
|
235
309
|
|
236
|
-
|
310
|
+
imports = @importer.imports(path, parent_path)
|
311
|
+
imports = [SassC::Importer::Import.new(path)] if imports.nil?
|
312
|
+
imports = [imports] unless imports.is_a?(Array)
|
313
|
+
imports.each do |import|
|
314
|
+
import.path = File.absolute_path(import.path, File.dirname(parent_path))
|
237
315
|
end
|
238
316
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
@importer_results[import_url] = if import.source
|
243
|
-
{
|
244
|
-
contents: import.source,
|
245
|
-
syntax: case import.path
|
246
|
-
when /\.sass$/i
|
247
|
-
:indented
|
248
|
-
when /\.css$/i
|
249
|
-
:css
|
250
|
-
else
|
251
|
-
:scss
|
252
|
-
end,
|
253
|
-
source_map_url: if import.source_map_path
|
254
|
-
URL.path_to_file_url(
|
255
|
-
File.absolute_path(
|
256
|
-
import.source_map_path, dirname
|
257
|
-
)
|
258
|
-
)
|
259
|
-
end
|
260
|
-
}
|
261
|
-
end
|
262
|
-
"@import #{import_url.inspect};"
|
263
|
-
end.join("\n")
|
264
|
-
|
265
|
-
@importer_results[canonical_url] = {
|
266
|
-
contents: contents,
|
267
|
-
syntax: :scss
|
268
|
-
}
|
269
|
-
|
317
|
+
import_url = URL.path_to_file_url(File.absolute_path(path, File.dirname(parent_path)))
|
318
|
+
canonical_url = "#{Protocol::IMPORT}#{import_url}"
|
319
|
+
@importer_results[canonical_url] = imports_to_native(imports)
|
270
320
|
canonical_url
|
271
321
|
end
|
272
322
|
|
273
323
|
def load(canonical_url)
|
274
|
-
|
324
|
+
if canonical_url.start_with?(Protocol::IMPORT)
|
325
|
+
@importer_results.delete(canonical_url)
|
326
|
+
elsif canonical_url.start_with?(Protocol::FILE)
|
327
|
+
@parent_urls.push(URL.parse(canonical_url))
|
328
|
+
if @importer_results.key?(canonical_url)
|
329
|
+
@importer_results.delete(canonical_url)
|
330
|
+
else
|
331
|
+
path = URL.file_url_to_path(canonical_url)
|
332
|
+
{
|
333
|
+
contents: File.read(path),
|
334
|
+
syntax: syntax(path),
|
335
|
+
source_map_url: canonical_url
|
336
|
+
}
|
337
|
+
end
|
338
|
+
elsif canonical_url.start_with?(Protocol::LOADED)
|
339
|
+
@parent_urls.pop
|
340
|
+
{
|
341
|
+
contents: '',
|
342
|
+
syntax: 'scss'
|
343
|
+
}
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
private
|
348
|
+
|
349
|
+
def load_paths
|
350
|
+
@load_paths ||= (@importer.options[:load_paths] || []) + SassC.load_paths
|
351
|
+
end
|
352
|
+
|
353
|
+
def resolve_path(path, parent_path, from_import)
|
354
|
+
[File.dirname(parent_path)].concat(load_paths).each do |load_path|
|
355
|
+
resolved = FileImporter.resolve_path(File.absolute_path(path, load_path), from_import)
|
356
|
+
return resolved unless resolved.nil?
|
357
|
+
end
|
358
|
+
nil
|
359
|
+
end
|
360
|
+
|
361
|
+
def syntax(path)
|
362
|
+
case File.extname(path)
|
363
|
+
when '.sass'
|
364
|
+
:indented
|
365
|
+
when '.css'
|
366
|
+
:css
|
367
|
+
else
|
368
|
+
:scss
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
def imports_to_native(imports)
|
373
|
+
{
|
374
|
+
contents: imports.flat_map do |import|
|
375
|
+
file_url = URL.path_to_file_url(import.path)
|
376
|
+
if import.source
|
377
|
+
@importer_results[file_url] = {
|
378
|
+
contents: import.source,
|
379
|
+
syntax: syntax(import.path),
|
380
|
+
source_map_url: file_url
|
381
|
+
}
|
382
|
+
end
|
383
|
+
[
|
384
|
+
"@import #{"#{Protocol::LOAD}#{file_url}".inspect};",
|
385
|
+
"@import #{"#{Protocol::LOADED}#{file_url}".inspect};"
|
386
|
+
]
|
387
|
+
end.join("\n"),
|
388
|
+
syntax: :scss
|
389
|
+
}
|
275
390
|
end
|
276
391
|
end
|
277
392
|
|
@@ -402,6 +517,10 @@ module SassC
|
|
402
517
|
|
403
518
|
module_function
|
404
519
|
|
520
|
+
def parse(str)
|
521
|
+
PARSER.parse(str)
|
522
|
+
end
|
523
|
+
|
405
524
|
def escape(str)
|
406
525
|
PARSER.escape(str)
|
407
526
|
end
|
@@ -413,7 +532,7 @@ module SassC
|
|
413
532
|
def file_url_to_path(url)
|
414
533
|
return if url.nil?
|
415
534
|
|
416
|
-
path = unescape(
|
535
|
+
path = unescape(parse(url).path)
|
417
536
|
path = path[1..] if Gem.win_platform? && path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
|
418
537
|
path
|
419
538
|
end
|
@@ -421,9 +540,10 @@ module SassC
|
|
421
540
|
def path_to_file_url(path)
|
422
541
|
return if path.nil?
|
423
542
|
|
424
|
-
path = File.absolute_path(path)
|
425
543
|
path = "/#{path}" unless path.start_with?('/')
|
426
544
|
URI::File.build([nil, escape(path)]).to_s
|
427
545
|
end
|
428
546
|
end
|
547
|
+
|
548
|
+
private_constant :URL
|
429
549
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sassc-embedded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- なつき
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sassc
|
@@ -138,8 +138,8 @@ homepage: https://github.com/ntkme/sassc-embedded-polyfill-ruby
|
|
138
138
|
licenses:
|
139
139
|
- MIT
|
140
140
|
metadata:
|
141
|
-
documentation_uri: https://rubydoc.info/gems/sassc-embedded/1.
|
142
|
-
source_code_uri: https://github.com/ntkme/sassc-embedded-polyfill-ruby/tree/v1.
|
141
|
+
documentation_uri: https://rubydoc.info/gems/sassc-embedded/1.3.1
|
142
|
+
source_code_uri: https://github.com/ntkme/sassc-embedded-polyfill-ruby/tree/v1.3.1
|
143
143
|
funding_uri: https://github.com/sponsors/ntkme
|
144
144
|
post_install_message:
|
145
145
|
rdoc_options: []
|