sass-embedded 1.74.1-riscv64-linux-android

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +48 -0
  4. data/exe/sass +21 -0
  5. data/ext/sass/cli.rb +12 -0
  6. data/ext/sass/dart-sass/sass +20 -0
  7. data/ext/sass/dart-sass/src/LICENSE +1687 -0
  8. data/ext/sass/dart-sass/src/dart +0 -0
  9. data/ext/sass/dart-sass/src/sass.snapshot +0 -0
  10. data/ext/sass/embedded_sass_pb.rb +63 -0
  11. data/lib/sass/calculation_value/calculation_operation.rb +49 -0
  12. data/lib/sass/calculation_value.rb +22 -0
  13. data/lib/sass/canonicalize_context.rb +21 -0
  14. data/lib/sass/compile_result.rb +24 -0
  15. data/lib/sass/compiler/channel.rb +68 -0
  16. data/lib/sass/compiler/connection.rb +92 -0
  17. data/lib/sass/compiler/dispatcher.rb +115 -0
  18. data/lib/sass/compiler/host/function_registry.rb +87 -0
  19. data/lib/sass/compiler/host/importer_registry.rb +137 -0
  20. data/lib/sass/compiler/host/logger_registry.rb +55 -0
  21. data/lib/sass/compiler/host/protofier.rb +390 -0
  22. data/lib/sass/compiler/host/structifier.rb +37 -0
  23. data/lib/sass/compiler/host.rb +226 -0
  24. data/lib/sass/compiler/varint.rb +39 -0
  25. data/lib/sass/compiler.rb +212 -0
  26. data/lib/sass/elf.rb +276 -0
  27. data/lib/sass/embedded/version.rb +7 -0
  28. data/lib/sass/embedded.rb +107 -0
  29. data/lib/sass/embedded_protocol.rb +10 -0
  30. data/lib/sass/exception.rb +69 -0
  31. data/lib/sass/fork_tracker.rb +51 -0
  32. data/lib/sass/logger/silent.rb +28 -0
  33. data/lib/sass/logger/source_location.rb +22 -0
  34. data/lib/sass/logger/source_span.rb +28 -0
  35. data/lib/sass/node_package_importer.rb +17 -0
  36. data/lib/sass/serializer.rb +36 -0
  37. data/lib/sass/value/argument_list.rb +37 -0
  38. data/lib/sass/value/boolean.rb +52 -0
  39. data/lib/sass/value/calculation.rb +90 -0
  40. data/lib/sass/value/color.rb +253 -0
  41. data/lib/sass/value/function.rb +51 -0
  42. data/lib/sass/value/fuzzy_math.rb +80 -0
  43. data/lib/sass/value/list.rb +79 -0
  44. data/lib/sass/value/map.rb +71 -0
  45. data/lib/sass/value/mixin.rb +36 -0
  46. data/lib/sass/value/null.rb +48 -0
  47. data/lib/sass/value/number/unit.rb +186 -0
  48. data/lib/sass/value/number.rb +366 -0
  49. data/lib/sass/value/string.rb +61 -0
  50. data/lib/sass/value.rb +136 -0
  51. data/lib/sass-embedded.rb +4 -0
  52. metadata +120 -0
data/lib/sass/elf.rb ADDED
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {ELF} class.
5
+ #
6
+ # It parses ELF header to extract interpreter.
7
+ # @see https://github.com/torvalds/linux/blob/HEAD/include/uapi/linux/elf.h
8
+ # @see https://github.com/torvalds/linux/blob/HEAD/kernel/kexec_elf.c
9
+ class ELF
10
+ # rubocop:disable Naming/ConstantName
11
+
12
+ # 32-bit ELF base types.
13
+ Elf32_Addr = :__u32
14
+ Elf32_Half = :__u16
15
+ Elf32_Off = :__u32
16
+ Elf32_Sword = :__s32
17
+ Elf32_Word = :__u32
18
+
19
+ # 64-bit ELF base types.
20
+ Elf64_Addr = :__u64
21
+ Elf64_Half = :__u16
22
+ Elf64_SHalf = :__s16
23
+ Elf64_Off = :__u64
24
+ Elf64_Sword = :__s32
25
+ Elf64_Word = :__u32
26
+ Elf64_Xword = :__u64
27
+ Elf64_Sxword = :__s64
28
+
29
+ # rubocop:enable Naming/ConstantName
30
+
31
+ # These constants are for the segment types stored in the image headers
32
+ PT_NULL = 0
33
+ PT_LOAD = 1
34
+ PT_DYNAMIC = 2
35
+ PT_INTERP = 3
36
+ PT_NOTE = 4
37
+ PT_SHLIB = 5
38
+ PT_PHDR = 6
39
+ PT_TLS = 7
40
+ PT_LOOS = 0x60000000
41
+ PT_HIOS = 0x6fffffff
42
+ PT_LOPROC = 0x70000000
43
+ PT_HIPROC = 0x7fffffff
44
+ PT_GNU_EH_FRAME = (PT_LOOS + 0x474e550)
45
+ PT_GNU_STACK = (PT_LOOS + 0x474e551)
46
+ PT_GNU_RELRO = (PT_LOOS + 0x474e552)
47
+ PT_GNU_PROPERTY = (PT_LOOS + 0x474e553)
48
+
49
+ # These constants define the different elf file types
50
+ ET_NONE = 0
51
+ ET_REL = 1
52
+ ET_EXEC = 2
53
+ ET_DYN = 3
54
+ ET_CORE = 4
55
+ ET_LOPROC = 0xff00
56
+ ET_HIPROC = 0xffff
57
+
58
+ EI_NIDENT = 16
59
+
60
+ # rubocop:disable Naming/ConstantName
61
+
62
+ Elf32_Ehdr = [
63
+ [:unsigned_char, :e_ident, EI_NIDENT],
64
+ [Elf32_Half, :e_type],
65
+ [Elf32_Half, :e_machine],
66
+ [Elf32_Word, :e_version],
67
+ [Elf32_Addr, :e_entry],
68
+ [Elf32_Off, :e_phoff],
69
+ [Elf32_Off, :e_shoff],
70
+ [Elf32_Word, :e_flags],
71
+ [Elf32_Half, :e_ehsize],
72
+ [Elf32_Half, :e_phentsize],
73
+ [Elf32_Half, :e_phnum],
74
+ [Elf32_Half, :e_shentsize],
75
+ [Elf32_Half, :e_shnum],
76
+ [Elf32_Half, :e_shstrndx]
77
+ ].freeze
78
+
79
+ Elf64_Ehdr = [
80
+ [:unsigned_char, :e_ident, EI_NIDENT],
81
+ [Elf64_Half, :e_type],
82
+ [Elf64_Half, :e_machine],
83
+ [Elf64_Word, :e_version],
84
+ [Elf64_Addr, :e_entry],
85
+ [Elf64_Off, :e_phoff],
86
+ [Elf64_Off, :e_shoff],
87
+ [Elf64_Word, :e_flags],
88
+ [Elf64_Half, :e_ehsize],
89
+ [Elf64_Half, :e_phentsize],
90
+ [Elf64_Half, :e_phnum],
91
+ [Elf64_Half, :e_shentsize],
92
+ [Elf64_Half, :e_shnum],
93
+ [Elf64_Half, :e_shstrndx]
94
+ ].freeze
95
+
96
+ Elf32_Phdr = [
97
+ [Elf32_Word, :p_type],
98
+ [Elf32_Off, :p_offset],
99
+ [Elf32_Addr, :p_vaddr],
100
+ [Elf32_Addr, :p_paddr],
101
+ [Elf32_Word, :p_filesz],
102
+ [Elf32_Word, :p_memsz],
103
+ [Elf32_Word, :p_flags],
104
+ [Elf32_Word, :p_align]
105
+ ].freeze
106
+
107
+ Elf64_Phdr = [
108
+ [Elf64_Word, :p_type],
109
+ [Elf64_Word, :p_flags],
110
+ [Elf64_Off, :p_offset],
111
+ [Elf64_Addr, :p_vaddr],
112
+ [Elf64_Addr, :p_paddr],
113
+ [Elf64_Xword, :p_filesz],
114
+ [Elf64_Xword, :p_memsz],
115
+ [Elf64_Xword, :p_align]
116
+ ].freeze
117
+
118
+ # rubocop:enable Naming/ConstantName
119
+
120
+ # e_ident[] indexes
121
+ EI_MAG0 = 0
122
+ EI_MAG1 = 1
123
+ EI_MAG2 = 2
124
+ EI_MAG3 = 3
125
+ EI_CLASS = 4
126
+ EI_DATA = 5
127
+ EI_VERSION = 6
128
+ EI_OSABI = 7
129
+ EI_PAD = 8
130
+
131
+ # EI_MAG
132
+ ELFMAG0 = 0x7f
133
+ ELFMAG1 = 'E'.ord
134
+ ELFMAG2 = 'L'.ord
135
+ ELFMAG3 = 'F'.ord
136
+ ELFMAG = [ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3].pack('C*')
137
+ SELFMAG = 4
138
+
139
+ # e_ident[EI_CLASS]
140
+ ELFCLASSNONE = 0
141
+ ELFCLASS32 = 1
142
+ ELFCLASS64 = 2
143
+ ELFCLASSNUM = 3
144
+
145
+ # e_ident[EI_DATA]
146
+ ELFDATANONE = 0
147
+ ELFDATA2LSB = 1
148
+ ELFDATA2MSB = 2
149
+
150
+ def initialize(buffer)
151
+ @buffer = buffer
152
+ @ehdr = read_ehdr
153
+ @buffer.seek(@ehdr[:e_phoff], IO::SEEK_SET)
154
+ @proghdrs = Array.new(@ehdr[:e_phnum]) do
155
+ read_phdr
156
+ end
157
+ end
158
+
159
+ def relocatable?
160
+ @ehdr[:e_type] == ET_REL
161
+ end
162
+
163
+ def executable?
164
+ @ehdr[:e_type] == ET_EXEC
165
+ end
166
+
167
+ def shared_object?
168
+ @ehdr[:e_type] == ET_DYN
169
+ end
170
+
171
+ def core?
172
+ @ehdr[:e_type] == ET_CORE
173
+ end
174
+
175
+ def interpreter
176
+ phdr = @proghdrs.find { |p| p[:p_type] == PT_INTERP }
177
+ return if phdr.nil?
178
+
179
+ @buffer.seek(phdr[:p_offset], IO::SEEK_SET)
180
+ interpreter = @buffer.read(phdr[:p_filesz])
181
+ raise ArgumentError unless interpreter.end_with?("\0")
182
+
183
+ interpreter.chomp!("\0")
184
+ end
185
+
186
+ private
187
+
188
+ def file_class
189
+ @ehdr[:e_ident][EI_CLASS]
190
+ end
191
+
192
+ def data_encoding
193
+ @ehdr[:e_ident][EI_DATA]
194
+ end
195
+
196
+ def read_ehdr
197
+ @ehdr = { e_ident: @buffer.read(EI_NIDENT).unpack('C*') }
198
+ raise ArgumentError unless @ehdr[:e_ident].slice(EI_MAG0, SELFMAG).pack('C*') == ELFMAG
199
+
200
+ case file_class
201
+ when ELFCLASS32
202
+ Elf32_Ehdr
203
+ when ELFCLASS64
204
+ Elf64_Ehdr
205
+ else
206
+ raise ArgumentError
207
+ end.drop(1).to_h do |field|
208
+ [field[1], read1(field[0])]
209
+ end.merge!(@ehdr)
210
+ end
211
+
212
+ def read_phdr
213
+ case file_class
214
+ when ELFCLASS32
215
+ Elf32_Phdr
216
+ when ELFCLASS64
217
+ Elf64_Phdr
218
+ else
219
+ raise ArgumentError
220
+ end.to_h do |field|
221
+ [field[1], read1(field[0])]
222
+ end
223
+ end
224
+
225
+ def explicit_endian
226
+ case data_encoding
227
+ when ELFDATA2LSB
228
+ '<'
229
+ when ELFDATA2MSB
230
+ '>'
231
+ else
232
+ raise ArgumentError
233
+ end
234
+ end
235
+
236
+ def read1(type)
237
+ case type
238
+ when :__u8
239
+ @buffer.read(1).unpack1('C')
240
+ when :__u16
241
+ @buffer.read(2).unpack1("S#{explicit_endian}")
242
+ when :__u32
243
+ @buffer.read(4).unpack1("L#{explicit_endian}")
244
+ when :__u64
245
+ @buffer.read(8).unpack1("Q#{explicit_endian}")
246
+ when :__s8
247
+ @buffer.read(1).unpack1('c')
248
+ when :__s16
249
+ @buffer.read(2).unpack1("s#{explicit_endian}")
250
+ when :__s32
251
+ @buffer.read(4).unpack1("l#{explicit_endian}")
252
+ when :__s64
253
+ @buffer.read(8).unpack1("q#{explicit_endian}")
254
+ else
255
+ raise ArgumentError
256
+ end
257
+ end
258
+
259
+ INTERPRETER = begin
260
+ proc_self_exe = '/proc/self/exe'
261
+ if File.exist?(proc_self_exe)
262
+ File.open(proc_self_exe, 'rb') do |file|
263
+ elf = ELF.new(file)
264
+ interpreter = elf.interpreter
265
+ if interpreter.nil? && elf.shared_object?
266
+ File.readlink(proc_self_exe)
267
+ else
268
+ interpreter
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+
275
+ private_constant :ELF
276
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Embedded
5
+ VERSION = '1.74.1'
6
+ end
7
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'compiler'
4
+
5
+ # The Sass module.
6
+ #
7
+ # This communicates with Embedded Dart Sass using the Embedded Sass protocol.
8
+ #
9
+ # @example
10
+ # Sass.compile('style.scss')
11
+ #
12
+ # @example
13
+ # Sass.compile_string('h1 { font-size: 40px; }')
14
+ module Sass
15
+ @compiler = nil
16
+ @mutex = Mutex.new
17
+
18
+ # rubocop:disable Layout/LineLength
19
+ class << self
20
+ # Compiles the Sass file at +path+ to CSS.
21
+ # @overload compile(path, load_paths: [], charset: true, source_map: false, source_map_include_sources: false, style: :expanded, functions: {}, importers: [], alert_ascii: false, alert_color: nil, fatal_deprecations: [], future_deprecations: [], logger: nil, quiet_deps: false, silence_deprecations: [], verbose: false)
22
+ # @param (see Compiler#compile)
23
+ # @return (see Compiler#compile)
24
+ # @raise (see Compiler#compile)
25
+ # @see Compiler#compile
26
+ def compile(...)
27
+ compiler.compile(...)
28
+ end
29
+
30
+ # Compiles a stylesheet whose contents is +source+ to CSS.
31
+ # @overload compile_string(source, importer: nil, load_paths: [], syntax: :scss, url: nil, charset: true, source_map: false, source_map_include_sources: false, style: :expanded, functions: {}, importers: [], alert_ascii: false, alert_color: nil, fatal_deprecations: [], future_deprecations: [], logger: nil, quiet_deps: false, silence_deprecations: [], verbose: false)
32
+ # @param (see Compiler#compile_string)
33
+ # @return (see Compiler#compile_string)
34
+ # @raise (see Compiler#compile_string)
35
+ # @see Compiler#compile_string
36
+ def compile_string(...)
37
+ compiler.compile_string(...)
38
+ end
39
+
40
+ # @param (see Compiler#info)
41
+ # @return (see Compiler#info)
42
+ # @raise (see Compiler#info)
43
+ # @see Compiler#info
44
+ def info
45
+ compiler.info
46
+ end
47
+
48
+ private
49
+
50
+ def compiler
51
+ return @compiler if @compiler
52
+
53
+ @mutex.synchronize do
54
+ return @compiler if @compiler
55
+
56
+ compiler = Class.new(Compiler) do
57
+ def initialize
58
+ @channel = Compiler.const_get(:Channel).new(Class.new(Compiler.const_get(:Dispatcher)) do
59
+ def initialize
60
+ super
61
+
62
+ idle_timeout = 10
63
+ @last_accessed_time = current_time
64
+
65
+ Thread.new do
66
+ Thread.current.name = 'sass-embedded-process-reaper'
67
+ duration = idle_timeout
68
+ loop do
69
+ sleep(duration.negative? ? idle_timeout : duration)
70
+ break if @mutex.synchronize do
71
+ raise Errno::EBUSY if _closed?
72
+
73
+ duration = idle_timeout - (current_time - @last_accessed_time)
74
+ duration.negative? && _idle? && _close
75
+ end
76
+ end
77
+ close
78
+ rescue Errno::EBUSY
79
+ # do nothing
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def _idle
86
+ super
87
+
88
+ @last_accessed_time = current_time
89
+ end
90
+
91
+ def current_time
92
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
93
+ end
94
+ end)
95
+ end
96
+ end.new
97
+
98
+ at_exit do
99
+ compiler.close
100
+ end
101
+
102
+ @compiler = compiler
103
+ end
104
+ end
105
+ end
106
+ # rubocop:enable Layout/LineLength
107
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # @see https://github.com/sass/sass/blob/HEAD/spec/embedded-protocol.md
5
+ module EmbeddedProtocol
6
+ require_relative '../../ext/sass/embedded_sass_pb'
7
+ end
8
+
9
+ private_constant :EmbeddedProtocol
10
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # An exception thrown because a Sass compilation failed.
5
+ class CompileError < StandardError
6
+ # @return [String, nil]
7
+ attr_reader :sass_stack
8
+
9
+ # @return [Logger::SourceSpan, nil]
10
+ attr_reader :span
11
+
12
+ # @return [Array<String>]
13
+ attr_reader :loaded_urls
14
+
15
+ # @!visibility private
16
+ def initialize(message, full_message, sass_stack, span, loaded_urls)
17
+ super(message)
18
+
19
+ @full_message = full_message
20
+ @sass_stack = sass_stack
21
+ @span = span
22
+ @loaded_urls = loaded_urls
23
+ end
24
+
25
+ # @return [String]
26
+ def full_message(highlight: nil, order: nil, **)
27
+ return super if @full_message.nil?
28
+
29
+ highlight = Exception.respond_to?(:to_tty?) && Exception.to_tty? if highlight.nil?
30
+ if highlight
31
+ @full_message.dup
32
+ else
33
+ @full_message.gsub(/\e\[[0-9;]*m/, '')
34
+ end
35
+ end
36
+
37
+ # @return [String]
38
+ def to_css
39
+ content = full_message(highlight: false, order: :top)
40
+
41
+ <<~CSS.freeze
42
+ /* #{content.gsub('*/', "*\u2060/").gsub("\r\n", "\n").split("\n").join("\n * ")} */
43
+
44
+ body::before {
45
+ position: static;
46
+ display: block;
47
+ padding: 1em;
48
+ margin: 0 0 1em;
49
+ border-width: 0 0 2px;
50
+ border-bottom-style: solid;
51
+ font-family: monospace, monospace;
52
+ white-space: pre;
53
+ content: #{Serializer.serialize_quoted_string(content).gsub(/[^[:ascii:]][\h\t ]?/) do |match|
54
+ replacement = "\\#{match.ord.to_s(16)}"
55
+ replacement << " #{match[1]}" if match.length > 1
56
+ replacement
57
+ end};
58
+ }
59
+ CSS
60
+ end
61
+ end
62
+
63
+ # An exception thrown by Sass Script.
64
+ class ScriptError < StandardError
65
+ def initialize(message, name = nil)
66
+ super(name.nil? ? message : "$#{name}: #{message}")
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {ForkTracker} module.
5
+ #
6
+ # It tracks objects that need to be closed after `Process.fork`.
7
+ module ForkTracker
8
+ HASH = {}.compare_by_identity
9
+
10
+ MUTEX = Mutex.new
11
+
12
+ private_constant :HASH, :MUTEX
13
+
14
+ module_function
15
+
16
+ def add(obj)
17
+ MUTEX.synchronize do
18
+ HASH[obj] = true
19
+ end
20
+ end
21
+
22
+ def delete(obj)
23
+ MUTEX.synchronize do
24
+ HASH.delete(obj)
25
+ end
26
+ end
27
+
28
+ def each(...)
29
+ MUTEX.synchronize do
30
+ HASH.keys
31
+ end.each(...)
32
+ end
33
+
34
+ # The {CoreExt} module.
35
+ #
36
+ # It closes objects after `Process.fork`.
37
+ module CoreExt
38
+ def _fork
39
+ pid = super
40
+ ForkTracker.each(&:close) if pid.zero?
41
+ pid
42
+ end
43
+ end
44
+
45
+ private_constant :CoreExt
46
+
47
+ Process.singleton_class.prepend(CoreExt) if Process.respond_to?(:_fork)
48
+ end
49
+
50
+ private_constant :ForkTracker
51
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # A namespace for built-in Loggers.
5
+ #
6
+ # @see https://sass-lang.com/documentation/js-api/modules/logger/
7
+ module Logger
8
+ module_function
9
+
10
+ # A Logger that silently ignores all warnings and debug messages.
11
+ #
12
+ # @see https://sass-lang.com/documentation/js-api/variables/logger.silent/
13
+ def silent
14
+ Silent
15
+ end
16
+
17
+ # A Logger that silently ignores all warnings and debug messages.
18
+ module Silent
19
+ module_function
20
+
21
+ def warn(message, deprecation: false, span: nil, stack: nil); end
22
+
23
+ def debug(message, span: nil); end
24
+ end
25
+
26
+ private_constant :Silent
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Logger
5
+ # A specific location within a source file.
6
+ #
7
+ # This is always associated with a {SourceSpan} which indicates which file it refers to.
8
+ #
9
+ # @see https://sass-lang.com/documentation/js-api/interfaces/sourcelocation/
10
+ class SourceLocation
11
+ # @return [Integer]
12
+ attr_reader :offset, :line, :column
13
+
14
+ # @!visibility private
15
+ def initialize(source_location)
16
+ @offset = source_location.offset
17
+ @line = source_location.line
18
+ @column = source_location.column
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Logger
5
+ # A span of text within a source file.
6
+ #
7
+ # @see https://sass-lang.com/documentation/js-api/interfaces/sourcespan/
8
+ class SourceSpan
9
+ # @return [SourceLocation]
10
+ attr_reader :start, :end
11
+
12
+ # @return [String]
13
+ attr_reader :text
14
+
15
+ # @return [String, nil]
16
+ attr_reader :url, :context
17
+
18
+ # @!visibility private
19
+ def initialize(source_span)
20
+ @start = source_span.start.nil? ? nil : Logger::SourceLocation.new(source_span.start)
21
+ @end = source_span.end.nil? ? nil : Logger::SourceLocation.new(source_span.end)
22
+ @text = source_span.text
23
+ @url = source_span.url == '' ? nil : source_span.url
24
+ @context = source_span.context == '' ? nil : source_span.context
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The built-in Node.js package importer. This loads pkg: URLs from node_modules
5
+ # according to the standard Node.js resolution algorithm.
6
+ #
7
+ # @see https://sass-lang.com/documentation/js-api/classes/nodepackageimporter/
8
+ class NodePackageImporter
9
+ # @param entry_point_directory [String] The directory where the {NodePackageImporter} should start when resolving
10
+ # `pkg:` URLs in sources other than files on disk.
11
+ def initialize(entry_point_directory)
12
+ raise ArgumentError, 'entry_point_directory must be set' if entry_point_directory.nil?
13
+
14
+ @entry_point_directory = File.absolute_path(entry_point_directory)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {Serializer} module.
5
+ module Serializer
6
+ module_function
7
+
8
+ CSS_ESCAPE = {
9
+ "\0" => "\uFFFD",
10
+ '\\' => '\\\\',
11
+ '"' => '\\"',
12
+ "'" => "\\'",
13
+ **[*"\x01".."\x08", *"\x0A".."\x1F", "\x7F"].product(
14
+ [*'0'..'9', *'a'..'f', *'A'..'F', "\t", ' ', nil]
15
+ ).to_h do |c, x|
16
+ ["#{c}#{x}".freeze, "\\#{c.ord.to_s(16)}#{" #{x}" if x}".freeze]
17
+ end
18
+ }.freeze
19
+
20
+ private_constant :CSS_ESCAPE
21
+
22
+ def serialize_quoted_string(string)
23
+ if !string.include?('"') || string.include?("'")
24
+ %("#{string.gsub(/[\0\\"]|[\x01-\x08\x0A-\x1F\x7F][\h\t ]?/, CSS_ESCAPE)}")
25
+ else
26
+ %('#{string.gsub(/[\0\\']|[\x01-\x08\x0A-\x1F\x7F][\h\t ]?/, CSS_ESCAPE)}')
27
+ end
28
+ end
29
+
30
+ def serialize_unquoted_string(string)
31
+ string.tr("\0", "\uFFFD").gsub(/\n */, ' ')
32
+ end
33
+ end
34
+
35
+ private_constant :Serializer
36
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Value
5
+ # Sass's argument list type.
6
+ #
7
+ # An argument list comes from a rest argument. It's distinct from a normal {List} in that it may contain a keyword
8
+ # map as well as the positional arguments.
9
+ #
10
+ # @see https://sass-lang.com/documentation/js-api/classes/sassargumentlist/
11
+ class ArgumentList < List
12
+ # @param contents [Array<Value>]
13
+ # @param keywords [Hash<Symbol, Value>]
14
+ # @param separator [::String]
15
+ def initialize(contents = [], keywords = {}, separator = ',')
16
+ super(contents, separator:)
17
+
18
+ @id = 0
19
+ @keywords_accessed = false
20
+ @keywords = keywords.freeze
21
+ end
22
+
23
+ # @return [Hash<Symbol, Value>]
24
+ def keywords
25
+ @keywords_accessed = true
26
+ @keywords
27
+ end
28
+
29
+ private
30
+
31
+ def initialize_dup(orig)
32
+ @id = 0
33
+ super
34
+ end
35
+ end
36
+ end
37
+ end