sass-embedded 0.14.0 → 0.16.2

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sass/compile_error.rb +1 -10
  3. data/lib/sass/compile_result.rb +1 -5
  4. data/lib/sass/embedded/channel.rb +2 -2
  5. data/lib/sass/embedded/compile_context/function_registry.rb +85 -0
  6. data/lib/sass/embedded/compile_context/importer_registry.rb +99 -0
  7. data/lib/sass/embedded/compile_context/logger_registry.rb +45 -0
  8. data/lib/sass/embedded/compile_context/value_protofier.rb +237 -0
  9. data/lib/sass/embedded/compile_context.rb +31 -238
  10. data/lib/sass/embedded/compiler/requirements.rb +1 -1
  11. data/lib/sass/embedded/compiler.rb +10 -43
  12. data/lib/sass/embedded/{render.rb → legacy.rb} +79 -3
  13. data/lib/sass/embedded/observer.rb +2 -0
  14. data/lib/sass/embedded/protofier.rb +91 -0
  15. data/lib/sass/embedded/structifier.rb +30 -0
  16. data/lib/sass/embedded/varint.rb +33 -0
  17. data/lib/sass/embedded/version.rb +1 -1
  18. data/lib/sass/embedded/version_context.rb +2 -3
  19. data/lib/sass/embedded.rb +39 -54
  20. data/lib/sass/embedded_protocol.rb +0 -6
  21. data/lib/sass/logger/source_location.rb +3 -9
  22. data/lib/sass/logger/source_span.rb +1 -13
  23. data/lib/sass/logger.rb +3 -3
  24. data/lib/sass/script_error.rb +5 -0
  25. data/lib/sass/value/argument_list.rb +24 -0
  26. data/lib/sass/value/boolean.rb +42 -0
  27. data/lib/sass/value/color.rb +213 -0
  28. data/lib/sass/value/function.rb +35 -0
  29. data/lib/sass/value/fuzzy_math.rb +81 -0
  30. data/lib/sass/value/list.rb +60 -0
  31. data/lib/sass/value/map.rb +57 -0
  32. data/lib/sass/value/null.rb +39 -0
  33. data/lib/sass/value/number/unit.rb +186 -0
  34. data/lib/sass/value/number.rb +272 -0
  35. data/lib/sass/value/string.rb +43 -0
  36. data/lib/sass/value.rb +92 -0
  37. data/lib/sass.rb +51 -48
  38. metadata +30 -56
  39. data/lib/sass/embedded/url.rb +0 -35
  40. data/lib/sass/file_importer.rb +0 -10
  41. data/lib/sass/importer.rb +0 -14
  42. data/lib/sass/importer_result.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c998b528ffddfc218f32dbefa09559dbdf519cf8a430f8dc9a58d4cae8a7b2a
4
- data.tar.gz: 84bb150040b3e01d68b7673f00ab08041deb98e357cb653a01ca99e40569f553
3
+ metadata.gz: bc4a584b02baef5fc270ec2ce84d7843c01f3656e64aa0c30e303a1d4c123313
4
+ data.tar.gz: d2230700daf1964f727ca1e5d5c695244cdb1d304700ad15997526ccb62ad31c
5
5
  SHA512:
6
- metadata.gz: cb4dd021d2dfd85b652dcf88c523e106c84a8ebcfa8e158c02f5a8b43aa4fc852b506dd39b33cf83766253be59bb084b7612a49165883eca4062c9c17b5f1a25
7
- data.tar.gz: d804392b2bc53fccba57c2d68c86f9118ffe80c24c854cea62b462738185634d59af4e41fc8ea86fabe0db120e16133d15bb3f2822ad3064c1c4e7c467796871
6
+ metadata.gz: 9fc031920618a3bc5b40a5c146b7ef8fc56b9d048b5c481b214425f3e17b72d05651ef1645b29ac08a15c5504d0c48b4f6605e6e5c13224560a9b26d212b13e9
7
+ data.tar.gz: e2a1e112ab8241f2a5393d01b237d1a9d41dcca7f386fdaa42a287c5a9cd82d4a6ec909775598a4235a373573ff76381df302f07f16861399ecad35734ea9913
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'logger/source_span'
4
-
5
3
  module Sass
6
- # The {CompileError} raised by {Embedded#compile} or {Embedded#compile_string}.
4
+ # An exception thrown because a Sass compilation failed.
7
5
  class CompileError < StandardError
8
6
  attr_accessor :sass_message, :sass_stack, :span
9
7
 
@@ -13,12 +11,5 @@ module Sass
13
11
  @sass_stack = sass_stack
14
12
  @span = span
15
13
  end
16
-
17
- def self.from_proto(compile_failure)
18
- CompileError.new(compile_failure.formatted,
19
- compile_failure.message,
20
- compile_failure.stack_trace,
21
- Logger::SourceSpan.from_proto(compile_failure.span))
22
- end
23
14
  end
24
15
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- # The {CompileResult} of {Embedded#compile} or {Embedded#compile_string}.
4
+ # The result of compiling Sass to CSS. Returned by {Sass.compile} and {Sass.compile_string}.
5
5
  class CompileResult
6
6
  attr_reader :css, :source_map, :loaded_urls
7
7
 
@@ -10,9 +10,5 @@ module Sass
10
10
  @source_map = source_map == '' ? nil : source_map
11
11
  @loaded_urls = loaded_urls
12
12
  end
13
-
14
- def self.from_proto(compile_success)
15
- CompileResult.new(compile_success.css, compile_success.source_map, compile_success.loaded_urls)
16
- end
17
13
  end
18
14
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'compiler'
4
-
5
3
  module Sass
6
4
  class Embedded
7
5
  # The {Channel} for {Compiler} calls. Each instance creates its own
@@ -58,5 +56,7 @@ module Sass
58
56
 
59
57
  private_constant :Subscription
60
58
  end
59
+
60
+ private_constant :Channel
61
61
  end
62
62
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ class CompileContext
6
+ # The {FunctionRegistry} for {CompileContext}.
7
+ class FunctionRegistry
8
+ attr_reader :global_functions
9
+
10
+ def initialize(functions)
11
+ functions = functions.transform_keys(&:to_s)
12
+
13
+ @global_functions = functions.keys
14
+ @functions_by_name = functions.transform_keys do |signature|
15
+ signature = signature.chomp
16
+ index = signature.index('(')
17
+ if index
18
+ signature.slice(0, index)
19
+ else
20
+ signature
21
+ end
22
+ end
23
+ @functions_by_id = {}
24
+ @ids_by_function = {}
25
+ @id = 0
26
+ end
27
+
28
+ def register(function)
29
+ return if @ids_by_function.key?(function)
30
+
31
+ id = @id
32
+ @id = @id.next
33
+
34
+ @ids_by_function[function] = id
35
+ @functions_by_id[id] = function
36
+
37
+ id
38
+ end
39
+
40
+ def function_call(function_call_request)
41
+ arguments = function_call_request.arguments.map do |argument|
42
+ value_protofier.from_proto(argument)
43
+ end
44
+
45
+ success = value_protofier.to_proto(get(function_call_request).call(arguments))
46
+ accessed_argument_lists = arguments
47
+ .filter do |argument|
48
+ argument.is_a?(Sass::Value::ArgumentList) && argument.instance_eval do
49
+ @keywords_accessed
50
+ end
51
+ end
52
+ .map { |argument| argument.instance_eval { @id } }
53
+
54
+ EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
55
+ id: function_call_request.id,
56
+ success: success,
57
+ accessed_argument_lists: accessed_argument_lists
58
+ )
59
+ rescue StandardError => e
60
+ EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
61
+ id: function_call_request.id,
62
+ error: e.message
63
+ )
64
+ end
65
+
66
+ private
67
+
68
+ def get(function_call_request)
69
+ case function_call_request.identifier
70
+ when :name
71
+ @functions_by_name[function_call_request.name]
72
+ when :function_id
73
+ @functions_by_id[function_call_request.function_id]
74
+ end
75
+ end
76
+
77
+ def value_protofier
78
+ @value_protofier ||= ValueProtofier.new(self)
79
+ end
80
+ end
81
+
82
+ private_constant :FunctionRegistry
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ class CompileContext
6
+ # The {ImporterRegistry} for {CompileContext}.
7
+ class ImporterRegistry
8
+ attr_reader :importers
9
+
10
+ def initialize(importers, load_paths)
11
+ @id = 0
12
+ @importers_by_id = {}
13
+ @importers = importers
14
+ .map { |importer| register(importer) }
15
+ .concat(load_paths.map do |load_path|
16
+ EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
17
+ path: File.absolute_path(load_path)
18
+ )
19
+ end)
20
+ end
21
+
22
+ def register(importer)
23
+ importer = Structifier.to_struct(importer)
24
+
25
+ is_importer = importer.respond_to?(:canonicalize) && importer.respond_to?(:load)
26
+ is_file_importer = importer.respond_to?(:find_file_url)
27
+
28
+ raise ArgumentError, 'importer must be an Importer or a FileImporter' if is_importer == is_file_importer
29
+
30
+ proto = if is_importer
31
+ EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
32
+ importer_id: @id
33
+ )
34
+ else
35
+ EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
36
+ file_importer_id: @id
37
+ )
38
+ end
39
+ @importers_by_id[@id] = importer
40
+ @id = @id.next
41
+ proto
42
+ end
43
+
44
+ def canonicalize(canonicalize_request)
45
+ importer = @importers_by_id[canonicalize_request.importer_id]
46
+ url = importer.canonicalize(canonicalize_request.url, from_import: canonicalize_request.from_import)&.to_s
47
+
48
+ EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
49
+ id: canonicalize_request.id,
50
+ url: url
51
+ )
52
+ rescue StandardError => e
53
+ EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
54
+ id: canonicalize_request.id,
55
+ error: e.message
56
+ )
57
+ end
58
+
59
+ def import(import_request)
60
+ importer = @importers_by_id[import_request.importer_id]
61
+ importer_result = Structifier.to_struct importer.load(import_request.url)
62
+
63
+ EmbeddedProtocol::InboundMessage::ImportResponse.new(
64
+ id: import_request.id,
65
+ success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
66
+ contents: importer_result.contents,
67
+ syntax: Protofier.to_proto_syntax(importer_result.syntax),
68
+ source_map_url: importer_result.respond_to?(:source_map_url) ? importer_result.source_map_url&.to_s : nil
69
+ )
70
+ )
71
+ rescue StandardError => e
72
+ EmbeddedProtocol::InboundMessage::ImportResponse.new(
73
+ id: import_request.id,
74
+ error: e.message
75
+ )
76
+ end
77
+
78
+ def file_import(file_import_request)
79
+ importer = @importers_by_id[file_import_request.importer_id]
80
+ file_url = importer.find_file_url(file_import_request.url, from_import: file_import_request.from_import)&.to_s
81
+
82
+ raise "file_url must be a file: URL, was \"#{file_url}\"" if !file_url.nil? && !file_url.start_with?('file:')
83
+
84
+ EmbeddedProtocol::InboundMessage::FileImportResponse.new(
85
+ id: file_import_request.id,
86
+ file_url: file_url
87
+ )
88
+ rescue StandardError => e
89
+ EmbeddedProtocol::InboundMessage::FileImportResponse.new(
90
+ id: file_import_request.id,
91
+ error: e.message
92
+ )
93
+ end
94
+ end
95
+
96
+ private_constant :ImporterRegistry
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ class CompileContext
6
+ # The {LoggerRegistry} for {CompileContext}.
7
+ class LoggerRegistry
8
+ attr_reader :logger
9
+
10
+ def initialize(logger)
11
+ @logger = Structifier.to_struct(logger)
12
+ end
13
+
14
+ def log(event)
15
+ case event.type
16
+ when :DEBUG
17
+ if logger.respond_to? :debug
18
+ logger.debug(event.message, span: Protofier.from_proto_source_span(event.span))
19
+ else
20
+ warn(event.formatted)
21
+ end
22
+ when :DEPRECATION_WARNING
23
+ if logger.respond_to? :warn
24
+ logger.warn(event.message, deprecation: true,
25
+ span: Protofier.from_proto_source_span(event.span),
26
+ stack: event.stack_trace)
27
+ else
28
+ warn(event.formatted)
29
+ end
30
+ when :WARNING
31
+ if logger.respond_to? :warn
32
+ logger.warn(event.message, deprecation: false,
33
+ span: Protofier.from_proto_source_span(event.span),
34
+ stack: event.stack_trace)
35
+ else
36
+ warn(event.formatted)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ private_constant :LoggerRegistry
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ class CompileContext
6
+ # The {ValueProtofier} between Pure Ruby types and Protobuf Ruby types.
7
+ class ValueProtofier
8
+ def initialize(function_registry)
9
+ @function_registry = function_registry
10
+ end
11
+
12
+ def to_proto(obj)
13
+ case obj
14
+ when Sass::Value::String
15
+ Sass::EmbeddedProtocol::Value.new(
16
+ string: Sass::EmbeddedProtocol::Value::String.new(
17
+ text: obj.text,
18
+ quoted: obj.quoted?
19
+ )
20
+ )
21
+ when Sass::Value::Number
22
+ Sass::EmbeddedProtocol::Value.new(
23
+ number: Sass::EmbeddedProtocol::Value::Number.new(
24
+ value: obj.value.to_f,
25
+ numerators: obj.numerator_units,
26
+ denominators: obj.denominator_units
27
+ )
28
+ )
29
+ when Sass::Value::Color
30
+ if obj.instance_eval { @hue.nil? }
31
+ Sass::EmbeddedProtocol::Value.new(
32
+ rgb_color: Sass::EmbeddedProtocol::Value::RgbColor.new(
33
+ red: obj.red,
34
+ green: obj.green,
35
+ blue: obj.blue,
36
+ alpha: obj.alpha.to_f
37
+ )
38
+ )
39
+ elsif obj.instance_eval { @saturation.nil? }
40
+ Sass::EmbeddedProtocol::Value.new(
41
+ hwb_color: Sass::EmbeddedProtocol::Value::HwbColor.new(
42
+ hue: obj.hue.to_f,
43
+ whiteness: obj.whiteness.to_f,
44
+ blackness: obj.blackness.to_f,
45
+ alpha: obj.alpha.to_f
46
+ )
47
+ )
48
+ else
49
+ Sass::EmbeddedProtocol::Value.new(
50
+ hsl_color: Sass::EmbeddedProtocol::Value::HslColor.new(
51
+ hue: obj.hue.to_f,
52
+ saturation: obj.saturation.to_f,
53
+ lightness: obj.lightness.to_f,
54
+ alpha: obj.alpha.to_f
55
+ )
56
+ )
57
+ end
58
+ when Sass::Value::ArgumentList
59
+ Sass::EmbeddedProtocol::Value.new(
60
+ argument_list: Sass::EmbeddedProtocol::Value::ArgumentList.new(
61
+ id: obj.instance_eval { @id },
62
+ contents: obj.contents.map { |element| to_proto(element) },
63
+ keywords: obj.keywords.transform_values { |value| to_proto(value) },
64
+ separator: ListSeparator.to_proto(obj.separator)
65
+ )
66
+ )
67
+ when Sass::Value::List
68
+ Sass::EmbeddedProtocol::Value.new(
69
+ list: Sass::EmbeddedProtocol::Value::List.new(
70
+ contents: obj.contents.map { |element| to_proto(element) },
71
+ separator: ListSeparator.to_proto(obj.separator),
72
+ has_brackets: obj.bracketed?
73
+ )
74
+ )
75
+ when Sass::Value::Map
76
+ Sass::EmbeddedProtocol::Value.new(
77
+ map: Sass::EmbeddedProtocol::Value::Map.new(
78
+ entries: obj.contents.map do |key, value|
79
+ Sass::EmbeddedProtocol::Value::Map::Entry.new(
80
+ key: to_proto(key),
81
+ value: to_proto(value)
82
+ )
83
+ end
84
+ )
85
+ )
86
+ when Sass::Value::Function
87
+ if obj.id
88
+ Sass::EmbeddedProtocol::Value.new(
89
+ compiler_function: Sass::EmbeddedProtocol::Value::CompilerFunction.new(
90
+ id: obj.id
91
+ )
92
+ )
93
+ else
94
+ Sass::EmbeddedProtocol::Value.new(
95
+ host_function: Sass::EmbeddedProtocol::Value::HostFunction.new(
96
+ id: @function_registry.register(obj.callback),
97
+ signature: obj.signature
98
+ )
99
+ )
100
+ end
101
+ when Sass::Value::Boolean
102
+ Sass::EmbeddedProtocol::Value.new(
103
+ singleton: obj.value ? :TRUE : :FALSE
104
+ )
105
+ when Sass::Value::Null
106
+ Sass::EmbeddedProtocol::Value.new(
107
+ singleton: :NULL
108
+ )
109
+ else
110
+ raise Sass::ScriptError, "Unknown Sass::Value #{obj}"
111
+ end
112
+ end
113
+
114
+ def from_proto(proto)
115
+ obj = proto.method(proto.value).call
116
+ case proto.value
117
+ when :string
118
+ Sass::Value::String.new(
119
+ obj.text,
120
+ quoted: obj.quoted
121
+ )
122
+ when :number
123
+ Sass::Value::Number.new(
124
+ obj.value,
125
+ obj.numerators,
126
+ obj.denominators
127
+ )
128
+ when :rgb_color
129
+ Sass::Value::Color.new(
130
+ red: obj.red,
131
+ green: obj.green,
132
+ blue: obj.blue,
133
+ alpha: obj.alpha
134
+ )
135
+ when :hsl_color
136
+ Sass::Value::Color.new(
137
+ hue: obj.hue,
138
+ saturation: obj.saturation,
139
+ lightness: obj.lightness,
140
+ alpha: obj.alpha
141
+ )
142
+ when :hwb_color
143
+ Sass::Value::Color.new(
144
+ hue: obj.hue,
145
+ whiteness: obj.whiteness,
146
+ blackness: obj.blackness,
147
+ alpha: obj.alpha
148
+ )
149
+ when :argument_list
150
+ Sass::Value::ArgumentList.new(
151
+ obj.contents.map do |element|
152
+ from_proto(element)
153
+ end,
154
+ obj.keywords.entries.to_h do |entry|
155
+ [entry.first, from_proto(entry.last)]
156
+ end,
157
+ ListSeparator.from_proto(obj.separator)
158
+ ).instance_eval do
159
+ @id = obj.id
160
+ self
161
+ end
162
+ when :list
163
+ Sass::Value::List.new(
164
+ obj.contents.map do |element|
165
+ from_proto(element)
166
+ end,
167
+ separator: ListSeparator.from_proto(obj.separator),
168
+ bracketed: obj.has_brackets
169
+ )
170
+ when :map
171
+ Sass::Value::Map.new(
172
+ obj.entries.to_h do |entry|
173
+ [from_proto(entry.key), from_proto(entry.value)]
174
+ end
175
+ )
176
+ when :compiler_function
177
+ Sass::Value::Function.new(obj.id)
178
+ when :host_function
179
+ raise ProtocolError, 'The compiler may not send Value.host_function to host'
180
+ when :singleton
181
+ case obj
182
+ when :TRUE
183
+ Sass::Value::Boolean::TRUE
184
+ when :FALSE
185
+ Sass::Value::Boolean::FALSE
186
+ when :NULL
187
+ Sass::Value::Null::NULL
188
+ else
189
+ raise Sass::ScriptError, "Unknown Value.singleton #{obj}"
190
+ end
191
+ else
192
+ raise Sass::ScriptError, "Unknown Value.value #{obj}"
193
+ end
194
+ end
195
+
196
+ # The {ListSeparator} Protofier.
197
+ module ListSeparator
198
+ module_function
199
+
200
+ def to_proto(separator)
201
+ case separator
202
+ when ','
203
+ :COMMA
204
+ when ' '
205
+ :SPACE
206
+ when '/'
207
+ :SLASH
208
+ when nil
209
+ :UNDECIDED
210
+ else
211
+ raise Sass::ScriptError, "Unknown ListSeparator #{separator}"
212
+ end
213
+ end
214
+
215
+ def from_proto(separator)
216
+ case separator
217
+ when :COMMA
218
+ ','
219
+ when :SPACE
220
+ ' '
221
+ when :SLASH
222
+ '/'
223
+ when :UNDECIDED
224
+ nil
225
+ else
226
+ raise Sass::ScriptError, "Unknown ListSeparator #{separator}"
227
+ end
228
+ end
229
+ end
230
+
231
+ private_constant :ListSeparator
232
+ end
233
+
234
+ private_constant :ValueProtofier
235
+ end
236
+ end
237
+ end