sass-embedded 1.6.2 → 1.83.1

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -3
  3. data/exe/sass +13 -0
  4. data/ext/sass/Rakefile +352 -76
  5. data/ext/sass/embedded_sass_pb.rb +61 -0
  6. data/ext/sass/expand-archive.ps1 +1 -0
  7. data/ext/sass/package.json +1 -1
  8. data/lib/sass/calculation_value/calculation_operation.rb +49 -0
  9. data/lib/sass/calculation_value.rb +22 -0
  10. data/lib/sass/canonicalize_context.rb +25 -0
  11. data/lib/sass/compile_result.rb +3 -2
  12. data/lib/sass/compiler/channel.rb +68 -0
  13. data/lib/sass/compiler/connection.rb +89 -0
  14. data/lib/sass/compiler/dispatcher.rb +116 -0
  15. data/lib/sass/{embedded → compiler}/host/function_registry.rb +31 -34
  16. data/lib/sass/compiler/host/importer_registry.rb +141 -0
  17. data/lib/sass/compiler/host/logger_registry.rb +80 -0
  18. data/lib/sass/compiler/host/protofier.rb +360 -0
  19. data/lib/sass/compiler/host/structifier.rb +37 -0
  20. data/lib/sass/compiler/host.rb +226 -0
  21. data/lib/sass/{embedded → compiler}/varint.rb +9 -5
  22. data/lib/sass/compiler.rb +212 -0
  23. data/lib/sass/elf.rb +222 -0
  24. data/lib/sass/embedded/version.rb +2 -2
  25. data/lib/sass/embedded.rb +76 -204
  26. data/lib/sass/embedded_protocol.rb +10 -0
  27. data/lib/sass/exception.rb +74 -0
  28. data/lib/sass/fork_tracker.rb +51 -0
  29. data/lib/sass/logger/silent.rb +5 -3
  30. data/lib/sass/logger/source_location.rb +6 -5
  31. data/lib/sass/logger/source_span.rb +8 -7
  32. data/lib/sass/node_package_importer.rb +17 -0
  33. data/lib/sass/serializer.rb +30 -0
  34. data/lib/sass/value/argument_list.rb +13 -6
  35. data/lib/sass/value/boolean.rb +1 -1
  36. data/lib/sass/value/calculation.rb +90 -0
  37. data/lib/sass/value/color/channel.rb +79 -0
  38. data/lib/sass/value/color/conversions.rb +473 -0
  39. data/lib/sass/value/color/gamut_map_method/clip.rb +45 -0
  40. data/lib/sass/value/color/gamut_map_method/local_minde.rb +94 -0
  41. data/lib/sass/value/color/gamut_map_method.rb +45 -0
  42. data/lib/sass/value/color/interpolation_method.rb +51 -0
  43. data/lib/sass/value/color/space/a98_rgb.rb +57 -0
  44. data/lib/sass/value/color/space/display_p3.rb +57 -0
  45. data/lib/sass/value/color/space/hsl.rb +65 -0
  46. data/lib/sass/value/color/space/hwb.rb +70 -0
  47. data/lib/sass/value/color/space/lab.rb +77 -0
  48. data/lib/sass/value/color/space/lch.rb +53 -0
  49. data/lib/sass/value/color/space/lms.rb +129 -0
  50. data/lib/sass/value/color/space/oklab.rb +66 -0
  51. data/lib/sass/value/color/space/oklch.rb +54 -0
  52. data/lib/sass/value/color/space/prophoto_rgb.rb +59 -0
  53. data/lib/sass/value/color/space/rec2020.rb +69 -0
  54. data/lib/sass/value/color/space/rgb.rb +52 -0
  55. data/lib/sass/value/color/space/srgb.rb +140 -0
  56. data/lib/sass/value/color/space/srgb_linear.rb +72 -0
  57. data/lib/sass/value/color/space/utils.rb +86 -0
  58. data/lib/sass/value/color/space/xyz_d50.rb +100 -0
  59. data/lib/sass/value/color/space/xyz_d65.rb +57 -0
  60. data/lib/sass/value/color/space.rb +198 -0
  61. data/lib/sass/value/color.rb +538 -163
  62. data/lib/sass/value/function.rb +11 -16
  63. data/lib/sass/value/fuzzy_math.rb +24 -21
  64. data/lib/sass/value/list.rb +7 -7
  65. data/lib/sass/value/map.rb +6 -6
  66. data/lib/sass/value/mixin.rb +34 -0
  67. data/lib/sass/value/null.rb +1 -1
  68. data/lib/sass/value/number/unit.rb +7 -6
  69. data/lib/sass/value/number.rb +34 -26
  70. data/lib/sass/value/string.rb +9 -3
  71. data/lib/sass/value.rb +20 -16
  72. metadata +67 -103
  73. data/ext/sass/unzip.vbs +0 -13
  74. data/lib/sass/compile_error.rb +0 -28
  75. data/lib/sass/embedded/async.rb +0 -65
  76. data/lib/sass/embedded/channel.rb +0 -61
  77. data/lib/sass/embedded/compiler.rb +0 -60
  78. data/lib/sass/embedded/dispatcher.rb +0 -90
  79. data/lib/sass/embedded/host/importer_registry.rb +0 -107
  80. data/lib/sass/embedded/host/logger_registry.rb +0 -50
  81. data/lib/sass/embedded/host/value_protofier.rb +0 -241
  82. data/lib/sass/embedded/host.rb +0 -139
  83. data/lib/sass/embedded/protofier.rb +0 -78
  84. data/lib/sass/embedded/structifier.rb +0 -36
  85. data/lib/sass/script_error.rb +0 -6
data/lib/sass/embedded.rb CHANGED
@@ -1,22 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../ext/sass/embedded'
4
- require_relative '../../ext/sass/embedded_sass_pb'
5
- require_relative 'compile_error'
6
- require_relative 'compile_result'
7
- require_relative 'embedded/async'
8
- require_relative 'embedded/channel'
9
- require_relative 'embedded/compiler'
10
- require_relative 'embedded/dispatcher'
11
- require_relative 'embedded/host'
12
- require_relative 'embedded/protofier'
13
- require_relative 'embedded/structifier'
14
- require_relative 'embedded/varint'
15
- require_relative 'embedded/version'
16
- require_relative 'logger/silent'
17
- require_relative 'logger/source_location'
18
- require_relative 'logger/source_span'
19
- require_relative 'value'
3
+ require_relative 'compiler'
20
4
 
21
5
  # The Sass module.
22
6
  #
@@ -28,208 +12,96 @@ require_relative 'value'
28
12
  # @example
29
13
  # Sass.compile_string('h1 { font-size: 40px; }')
30
14
  module Sass
15
+ @compiler = nil
16
+ @mutex = Mutex.new
17
+
18
+ # rubocop:disable Layout/LineLength
31
19
  class << self
32
20
  # Compiles the Sass file at +path+ to CSS.
33
- # @param (see Embedded#compile)
34
- # @return (see Embedded#compile)
35
- # @raise (see Embedded#compile)
36
- # @see Embedded#compile
37
- def compile(path, **kwargs)
38
- instance.compile(path, **kwargs)
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(...)
39
28
  end
40
29
 
41
30
  # Compiles a stylesheet whose contents is +source+ to CSS.
42
- # @param (see Embedded#compile_string)
43
- # @return (see Embedded#compile_string)
44
- # @raise (see Embedded#compile_string)
45
- # @see Embedded#compile_string
46
- def compile_string(source, **kwargs)
47
- instance.compile_string(source, **kwargs)
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(...)
48
38
  end
49
39
 
50
- # @param (see Embedded#info)
51
- # @return (see Embedded#info)
52
- # @raise (see Embedded#info)
53
- # @see Embedded#info
40
+ # @param (see Compiler#info)
41
+ # @return (see Compiler#info)
42
+ # @raise (see Compiler#info)
43
+ # @see Compiler#info
54
44
  def info
55
- instance.info
45
+ compiler.info
56
46
  end
57
47
 
58
48
  private
59
49
 
60
- def instance
61
- if defined? @instance
62
- @instance = Embedded.new if @instance.closed?
63
- else
64
- @instance = Embedded.new
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-connection-reaper-#{@connection.id}"
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
+
65
98
  at_exit do
66
- @instance.close
99
+ compiler.close
67
100
  end
68
- end
69
- @instance
70
- end
71
- end
72
-
73
- # The {Embedded} host for using dart-sass-embedded. Each instance creates
74
- # its own communication {Channel} with a dedicated compiler process.
75
- #
76
- # @example
77
- # embedded = Sass::Embedded.new
78
- # result = embedded.compile_string('h1 { font-size: 40px; }')
79
- # result = embedded.compile('style.scss')
80
- # embedded.close
81
- class Embedded
82
- def initialize
83
- @channel = Channel.new
84
- end
85
-
86
- # Compiles the Sass file at +path+ to CSS.
87
- # @param path [String]
88
- # @param load_paths [Array<String>] Paths in which to look for stylesheets loaded by rules like
89
- # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
90
- # @param source_map [Boolean] Whether or not Sass should generate a source map.
91
- # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map.
92
- # @param style [String, Symbol] The OutputStyle of the compiled CSS.
93
- # @param functions [Hash<String, Proc>] Additional built-in Sass functions that are available in all stylesheets.
94
- # @param importers [Array<Object>] Custom importers that control how Sass resolves loads from rules like
95
- # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
96
- # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error
97
- # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well.
98
- # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and
99
- # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or
100
- # not to use colors depending on whether the user is using an interactive terminal.
101
- # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass.
102
- # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by
103
- # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+.
104
- # Stylesheets that are imported relative to the entrypoint are not considered dependencies.
105
- # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per
106
- # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every
107
- # deprecation warning it encounters.
108
- # @return [CompileResult]
109
- # @raise [CompileError]
110
- # @see https://sass-lang.com/documentation/js-api/modules#compile
111
- def compile(path,
112
- load_paths: [],
113
-
114
- source_map: false,
115
- source_map_include_sources: false,
116
- style: :expanded,
117
-
118
- functions: {},
119
- importers: [],
120
-
121
- alert_ascii: false,
122
- alert_color: nil,
123
- logger: nil,
124
- quiet_deps: false,
125
- verbose: false)
126
- raise ArgumentError, 'path must be set' if path.nil?
127
-
128
- Protofier.from_proto_compile_response(
129
- Host.new(@channel).compile_request(
130
- path: path,
131
- source: nil,
132
- importer: nil,
133
- load_paths: load_paths,
134
- syntax: nil,
135
- url: nil,
136
- source_map: source_map,
137
- source_map_include_sources: source_map_include_sources,
138
- style: style,
139
- functions: functions,
140
- importers: importers,
141
- alert_color: alert_color,
142
- alert_ascii: alert_ascii,
143
- logger: logger,
144
- quiet_deps: quiet_deps,
145
- verbose: verbose
146
- )
147
- )
148
- end
149
101
 
150
- # Compiles a stylesheet whose contents is +source+ to CSS.
151
- # @param source [String]
152
- # @param importer [Object] The importer to use to handle loads that are relative to the entrypoint stylesheet.
153
- # @param load_paths [Array<String>] Paths in which to look for stylesheets loaded by rules like
154
- # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
155
- # @param syntax [String, Symbol] The Syntax to use to parse the entrypoint stylesheet.
156
- # @param url [String] The canonical URL of the entrypoint stylesheet. If this is passed along with +importer+, it's
157
- # used to resolve relative loads in the entrypoint stylesheet.
158
- # @param source_map [Boolean] Whether or not Sass should generate a source map.
159
- # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map.
160
- # @param style [String, Symbol] The OutputStyle of the compiled CSS.
161
- # @param functions [Hash<String, Proc>] Additional built-in Sass functions that are available in all stylesheets.
162
- # @param importers [Array<Object>] Custom importers that control how Sass resolves loads from rules like
163
- # {@use}[https://sass-lang.com/documentation/at-rules/use] and {@import}[https://sass-lang.com/documentation/at-rules/import].
164
- # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error
165
- # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well.
166
- # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and
167
- # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or
168
- # not to use colors depending on whether the user is using an interactive terminal.
169
- # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass.
170
- # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by
171
- # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+.
172
- # Stylesheets that are imported relative to the entrypoint are not considered dependencies.
173
- # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per
174
- # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every
175
- # deprecation warning it encounters.
176
- # @return [CompileResult]
177
- # @raise [CompileError]
178
- # @see https://sass-lang.com/documentation/js-api/modules#compileString
179
- def compile_string(source,
180
- importer: nil,
181
- load_paths: [],
182
- syntax: :scss,
183
- url: nil,
184
-
185
- source_map: false,
186
- source_map_include_sources: false,
187
- style: :expanded,
188
-
189
- functions: {},
190
- importers: [],
191
-
192
- alert_ascii: false,
193
- alert_color: nil,
194
- logger: nil,
195
- quiet_deps: false,
196
- verbose: false)
197
- raise ArgumentError, 'source must be set' if source.nil?
198
-
199
- Protofier.from_proto_compile_response(
200
- Host.new(@channel).compile_request(
201
- path: nil,
202
- source: source,
203
- importer: importer,
204
- load_paths: load_paths,
205
- syntax: syntax,
206
- url: url,
207
- source_map: source_map,
208
- source_map_include_sources: source_map_include_sources,
209
- style: style,
210
- functions: functions,
211
- importers: importers,
212
- alert_color: alert_color,
213
- alert_ascii: alert_ascii,
214
- logger: logger,
215
- quiet_deps: quiet_deps,
216
- verbose: verbose
217
- )
218
- )
219
- end
220
-
221
- # @return [String] Information about the Sass implementation.
222
- # @see https://sass-lang.com/documentation/js-api/modules#info
223
- def info
224
- @info ||= "sass-embedded\t#{Host.new(@channel).version_request.implementation_version}"
225
- end
226
-
227
- def close
228
- @channel.close
229
- end
230
-
231
- def closed?
232
- @channel.closed?
102
+ @compiler = compiler
103
+ end
233
104
  end
234
105
  end
106
+ # rubocop:enable Layout/LineLength
235
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,74 @@
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.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
+ ordinal = match.ord
55
+ replacement = "\\#{ordinal.to_s(16)}"
56
+ if match.length > 1
57
+ replacement << ' ' if ordinal < 0x100000
58
+ replacement << match[1]
59
+ end
60
+ replacement
61
+ end};
62
+ }
63
+ CSS
64
+ end
65
+ end
66
+
67
+ # An exception thrown by Sass Script.
68
+ class ScriptError < StandardError
69
+ # @!visibility private
70
+ def initialize(message, name = nil)
71
+ super(name.nil? ? message : "$#{name}: #{message}")
72
+ end
73
+ end
74
+ 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
@@ -3,11 +3,13 @@
3
3
  module Sass
4
4
  # A namespace for built-in Loggers.
5
5
  #
6
- # @see https://sass-lang.com/documentation/js-api/modules/Logger
6
+ # @see https://sass-lang.com/documentation/js-api/modules/logger/
7
7
  module Logger
8
8
  module_function
9
9
 
10
10
  # A Logger that silently ignores all warnings and debug messages.
11
+ #
12
+ # @see https://sass-lang.com/documentation/js-api/variables/logger.silent/
11
13
  def silent
12
14
  Silent
13
15
  end
@@ -16,9 +18,9 @@ module Sass
16
18
  module Silent
17
19
  module_function
18
20
 
19
- def warn(message, deprecation: false, span: nil, stack: nil); end
21
+ def warn(message, options); end
20
22
 
21
- def debug(message, span: nil); end
23
+ def debug(message, options); end
22
24
  end
23
25
 
24
26
  private_constant :Silent
@@ -6,15 +6,16 @@ module Sass
6
6
  #
7
7
  # This is always associated with a {SourceSpan} which indicates which file it refers to.
8
8
  #
9
- # @see https://sass-lang.com/documentation/js-api/interfaces/SourceLocation
9
+ # @see https://sass-lang.com/documentation/js-api/interfaces/sourcelocation/
10
10
  class SourceLocation
11
11
  # @return [Integer]
12
12
  attr_reader :offset, :line, :column
13
13
 
14
- def initialize(offset, line, column)
15
- @offset = offset
16
- @line = line
17
- @column = column
14
+ # @!visibility private
15
+ def initialize(source_location)
16
+ @offset = source_location.offset
17
+ @line = source_location.line
18
+ @column = source_location.column
18
19
  end
19
20
  end
20
21
  end
@@ -4,7 +4,7 @@ module Sass
4
4
  module Logger
5
5
  # A span of text within a source file.
6
6
  #
7
- # @see https://sass-lang.com/documentation/js-api/interfaces/SourceSpan
7
+ # @see https://sass-lang.com/documentation/js-api/interfaces/sourcespan/
8
8
  class SourceSpan
9
9
  # @return [SourceLocation]
10
10
  attr_reader :start, :end
@@ -15,12 +15,13 @@ module Sass
15
15
  # @return [String, nil]
16
16
  attr_reader :url, :context
17
17
 
18
- def initialize(start, end_, text, url, context)
19
- @start = start
20
- @end = end_
21
- @text = text
22
- @url = url == '' ? nil : url
23
- @context = context == '' ? nil : context
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
24
25
  end
25
26
  end
26
27
  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,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {Serializer} module.
5
+ module Serializer
6
+ module_function
7
+
8
+ CSS_ESCAPE = [*"\x01".."\x08", *"\x0A".."\x1F", "\x7F"]
9
+ .product([*'0'..'9', *'a'..'f', *'A'..'F', "\t", ' ', nil])
10
+ .each_with_object({ "\0" => "\uFFFD", '\\' => '\\\\', '"' => '\\"', "'" => "\\'" }) do |(c, x), h|
11
+ h["#{c}#{x}".freeze] = "\\#{c.ord.to_s(16)}#{" #{x}" if x}".freeze
12
+ end.freeze
13
+
14
+ private_constant :CSS_ESCAPE
15
+
16
+ def serialize_quoted_string(string)
17
+ if !string.include?('"') || string.include?("'")
18
+ %("#{string.gsub(/[\0\\"]|[\x01-\x08\x0A-\x1F\x7F][\h\t ]?/, CSS_ESCAPE)}")
19
+ else
20
+ %('#{string.gsub(/[\0\\']|[\x01-\x08\x0A-\x1F\x7F][\h\t ]?/, CSS_ESCAPE)}')
21
+ end
22
+ end
23
+
24
+ def serialize_unquoted_string(string)
25
+ string.tr("\0", "\uFFFD").gsub(/\n */, ' ')
26
+ end
27
+ end
28
+
29
+ private_constant :Serializer
30
+ end
@@ -7,24 +7,31 @@ module Sass
7
7
  # An argument list comes from a rest argument. It's distinct from a normal {List} in that it may contain a keyword
8
8
  # map as well as the positional arguments.
9
9
  #
10
- # @see https://sass-lang.com/documentation/js-api/classes/SassArgumentList
11
- class ArgumentList < Value::List
10
+ # @see https://sass-lang.com/documentation/js-api/classes/sassargumentlist/
11
+ class ArgumentList < List
12
12
  # @param contents [Array<Value>]
13
- # @param keywords [Hash<::String, Value>]
13
+ # @param keywords [Hash<Symbol, Value>]
14
14
  # @param separator [::String]
15
15
  def initialize(contents = [], keywords = {}, separator = ',')
16
- super(contents, separator: separator)
16
+ super(contents, separator:)
17
17
 
18
18
  @id = 0
19
19
  @keywords_accessed = false
20
- @keywords = keywords.transform_keys(&:to_s).freeze
20
+ @keywords = keywords.freeze
21
21
  end
22
22
 
23
- # @return [Hash<::String, Value>]
23
+ # @return [Hash<Symbol, Value>]
24
24
  def keywords
25
25
  @keywords_accessed = true
26
26
  @keywords
27
27
  end
28
+
29
+ private
30
+
31
+ def initialize_dup(orig)
32
+ @id = 0
33
+ super
34
+ end
28
35
  end
29
36
  end
30
37
  end
@@ -4,7 +4,7 @@ module Sass
4
4
  module Value
5
5
  # Sass's boolean type.
6
6
  #
7
- # @see https://sass-lang.com/documentation/js-api/classes/SassBoolean
7
+ # @see https://sass-lang.com/documentation/js-api/classes/sassboolean/
8
8
  class Boolean
9
9
  include Value
10
10