sass-embedded 0.9.0 → 0.10.0
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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +3 -23
- data/ext/sass/extconf.rb +1 -3
- data/lib/sass/compile_error.rb +24 -0
- data/lib/sass/compile_result.rb +18 -0
- data/lib/sass/embedded/channel.rb +1 -1
- data/lib/sass/embedded/compile_context.rb +162 -137
- data/lib/sass/embedded/compiler/requirements.rb +1 -1
- data/lib/sass/embedded/compiler.rb +4 -4
- data/lib/sass/embedded/observer.rb +1 -0
- data/lib/sass/embedded/protocol_error.rb +7 -0
- data/lib/sass/embedded/render.rb +344 -0
- data/lib/sass/embedded/{util.rb → url.rb} +5 -13
- data/lib/sass/embedded/version.rb +1 -1
- data/lib/sass/embedded.rb +87 -210
- data/lib/sass/file_importer.rb +10 -0
- data/lib/sass/importer.rb +14 -0
- data/lib/sass/importer_result.rb +14 -0
- data/lib/sass/logger/source_location.rb +24 -0
- data/lib/sass/logger/source_span.rb +30 -0
- data/lib/sass/logger.rb +20 -0
- data/lib/sass.rb +40 -4
- metadata +26 -19
- data/lib/sass/embedded/error.rb +0 -29
- data/lib/sass/embedded/result.rb +0 -34
- data/lib/sass/embedded/struct.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3c01d861dce5149bb56f25e6cb89e54d21a26bc4e50486298f860b2386198b7
|
4
|
+
data.tar.gz: 36f04488a3118b833f6210766e590a617fe7204dabb31b0908023b32a008ed21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7c15d96579e3dc1843c3dfc66709c9a3ae48bcbb7458f0defcc91c313cffb53dc43b01d114c35b13b8a7b8cfae516440037730283d52e5ea506fffa70a9bcac
|
7
|
+
data.tar.gz: ae089947ade94c0550e9a066860e89e1c774572ddc1ab7c5b42327f4a9f3fe6db41c4422ce96a9454d63b44ae8675091239278ebd8d6f524438c0f680a3e5e26
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -16,32 +16,12 @@ gem install sass-embedded
|
|
16
16
|
## Usage
|
17
17
|
|
18
18
|
``` ruby
|
19
|
-
require
|
19
|
+
require 'sass'
|
20
20
|
|
21
|
-
Sass.
|
21
|
+
Sass.compile('style.scss')
|
22
|
+
Sass.compile_string('h1 { font-size: 40px; }')
|
22
23
|
```
|
23
24
|
|
24
|
-
## Options
|
25
|
-
|
26
|
-
`Sass.render(**kwargs)` supports the following options:
|
27
|
-
|
28
|
-
- [`data`](https://sass-lang.com/documentation/js-api#data)
|
29
|
-
- [`file`](https://sass-lang.com/documentation/js-api#file)
|
30
|
-
- [`indented_syntax`](https://sass-lang.com/documentation/js-api#indentedsyntax)
|
31
|
-
- [`include_paths`](https://sass-lang.com/documentation/js-api#includepaths)
|
32
|
-
- [`output_style`](https://sass-lang.com/documentation/js-api#outputstyle)
|
33
|
-
- [`indent_type`](https://sass-lang.com/documentation/js-api#indenttype)
|
34
|
-
- [`indent_width`](https://sass-lang.com/documentation/js-api#indentwidth)
|
35
|
-
- [`linefeed`](https://sass-lang.com/documentation/js-api#linefeed)
|
36
|
-
- [`source_map`](https://sass-lang.com/documentation/js-api#sourcemap)
|
37
|
-
- [`out_file`](https://sass-lang.com/documentation/js-api#outfile)
|
38
|
-
- [`omit_source_map_url`](https://sass-lang.com/documentation/js-api#omitsourcemapurl)
|
39
|
-
- [`source_map_contents`](https://sass-lang.com/documentation/js-api#sourcemapcontents)
|
40
|
-
- [`source_map_embed`](https://sass-lang.com/documentation/js-api#sourcemapembed)
|
41
|
-
- [`source_map_root`](https://sass-lang.com/documentation/js-api#sourcemaproot)
|
42
|
-
- [`functions`](https://sass-lang.com/documentation/js-api#functions)
|
43
|
-
- [`importer`](https://sass-lang.com/documentation/js-api#importer)
|
44
|
-
|
45
25
|
---
|
46
26
|
|
47
27
|
Disclaimer: this is not an official Google product.
|
data/ext/sass/extconf.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'logger/source_span'
|
4
|
+
|
5
|
+
module Sass
|
6
|
+
# The {CompileError} raised by {Embedded#compile} or {Embedded#compile_string}.
|
7
|
+
class CompileError < StandardError
|
8
|
+
attr_accessor :sass_message, :sass_stack, :span
|
9
|
+
|
10
|
+
def initialize(message, sass_message, sass_stack, span)
|
11
|
+
super(message)
|
12
|
+
@sass_message = sass_message
|
13
|
+
@sass_stack = sass_stack
|
14
|
+
@span = span
|
15
|
+
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
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sass
|
4
|
+
# The {CompileResult} of {Embedded#compile} or {Embedded#compile_string}.
|
5
|
+
class CompileResult
|
6
|
+
attr_reader :css, :source_map, :loaded_urls
|
7
|
+
|
8
|
+
def initialize(css, source_map, loaded_urls)
|
9
|
+
@css = css
|
10
|
+
@source_map = source_map == '' ? nil : source_map
|
11
|
+
@loaded_urls = loaded_urls
|
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
|
+
end
|
18
|
+
end
|
@@ -1,40 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../embedded_protocol'
|
4
|
+
require_relative '../logger/source_span'
|
4
5
|
require_relative 'observer'
|
5
|
-
require_relative 'util'
|
6
6
|
|
7
7
|
module Sass
|
8
8
|
class Embedded
|
9
|
-
# The {Observer} for {Embedded#
|
9
|
+
# The {Observer} for {Embedded#compile}.
|
10
10
|
class CompileContext
|
11
11
|
include Observer
|
12
12
|
|
13
13
|
def initialize(channel,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
path:,
|
15
|
+
source:,
|
16
|
+
|
17
|
+
importer:,
|
18
|
+
load_paths:,
|
19
|
+
syntax:,
|
20
|
+
url:,
|
21
|
+
|
19
22
|
source_map:,
|
20
|
-
|
23
|
+
style:,
|
24
|
+
|
21
25
|
functions:,
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@
|
26
|
+
importers:,
|
27
|
+
|
28
|
+
alert_ascii:,
|
29
|
+
alert_color:,
|
30
|
+
logger:,
|
31
|
+
quiet_deps:,
|
32
|
+
verbose:)
|
33
|
+
@path = path
|
34
|
+
@source = source
|
35
|
+
|
36
|
+
@importer = importer
|
37
|
+
@load_paths = load_paths
|
38
|
+
@syntax = syntax
|
39
|
+
@url = url
|
40
|
+
|
30
41
|
@source_map = source_map
|
31
|
-
@
|
32
|
-
|
42
|
+
@style = style
|
43
|
+
|
44
|
+
@global_functions = functions.keys.map(&:to_s)
|
45
|
+
|
33
46
|
@functions = functions.transform_keys do |key|
|
34
47
|
key.to_s.split('(')[0].chomp
|
35
48
|
end
|
36
|
-
@
|
37
|
-
|
49
|
+
@importers = importers
|
50
|
+
|
51
|
+
@alert_ascii = alert_ascii
|
52
|
+
@alert_color = alert_color
|
53
|
+
@logger = logger
|
54
|
+
@quiet_deps = quiet_deps
|
55
|
+
@verbose = verbose
|
38
56
|
|
39
57
|
super(channel)
|
40
58
|
|
@@ -52,9 +70,9 @@ module Sass
|
|
52
70
|
super(nil, message)
|
53
71
|
end
|
54
72
|
when EmbeddedProtocol::OutboundMessage::LogEvent
|
55
|
-
return unless message.compilation_id == id
|
73
|
+
return unless message.compilation_id == id
|
56
74
|
|
57
|
-
|
75
|
+
log message
|
58
76
|
when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
|
59
77
|
return unless message.compilation_id == id
|
60
78
|
|
@@ -68,7 +86,11 @@ module Sass
|
|
68
86
|
send_message import_response message
|
69
87
|
end
|
70
88
|
when EmbeddedProtocol::OutboundMessage::FileImportRequest
|
71
|
-
|
89
|
+
return unless message.compilation_id == id
|
90
|
+
|
91
|
+
Thread.new do
|
92
|
+
send_message file_import_response message
|
93
|
+
end
|
72
94
|
when EmbeddedProtocol::OutboundMessage::FunctionCallRequest
|
73
95
|
return unless message.compilation_id == id
|
74
96
|
|
@@ -84,94 +106,107 @@ module Sass
|
|
84
106
|
|
85
107
|
private
|
86
108
|
|
109
|
+
def log(event)
|
110
|
+
case event.type
|
111
|
+
when :DEBUG
|
112
|
+
if @logger.respond_to? :debug
|
113
|
+
@logger.debug(event.message, span: Logger::SourceSpan.from_proto(event.span))
|
114
|
+
else
|
115
|
+
Kernel.warn(event.formatted)
|
116
|
+
end
|
117
|
+
when :DEPRECATION_WARNING
|
118
|
+
if @logger.respond_to? :warn
|
119
|
+
@logger.warn(event.message, deprecation: true, span: Logger::SourceSpan.from_proto(event.span),
|
120
|
+
stack: event.stack_trace)
|
121
|
+
else
|
122
|
+
Kernel.warn(event.formatted)
|
123
|
+
end
|
124
|
+
when :WARNING
|
125
|
+
if @logger.respond_to? :warn
|
126
|
+
@logger.warn(event.message, deprecation: false, span: Logger::SourceSpan.from_proto(event.span),
|
127
|
+
stack: event.stack_trace)
|
128
|
+
else
|
129
|
+
Kernel.warn(event.formatted)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
87
134
|
def compile_request
|
88
135
|
EmbeddedProtocol::InboundMessage::CompileRequest.new(
|
89
136
|
id: id,
|
90
|
-
string:
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
137
|
+
string: unless @source.nil?
|
138
|
+
EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
|
139
|
+
source: @source,
|
140
|
+
url: @url,
|
141
|
+
syntax: to_proto_syntax(@syntax),
|
142
|
+
importer: @importer.nil? ? nil : to_proto_importer(@importer, @importers.length)
|
143
|
+
)
|
144
|
+
end,
|
145
|
+
path: @path,
|
146
|
+
style: to_proto_output_style(@style),
|
147
|
+
source_map: @source_map,
|
148
|
+
importers: to_proto_importers(@importers, @load_paths),
|
149
|
+
global_functions: @global_functions,
|
150
|
+
alert_ascii: @alert_ascii,
|
151
|
+
alert_color: @alert_color
|
98
152
|
)
|
99
153
|
end
|
100
154
|
|
101
155
|
def canonicalize_response(canonicalize_request)
|
102
|
-
url =
|
103
|
-
|
104
|
-
begin
|
105
|
-
result = @importer[canonicalize_request.importer_id].call canonicalize_request.url, @file
|
106
|
-
raise result if result.is_a? StandardError
|
107
|
-
rescue StandardError => e
|
108
|
-
return EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
109
|
-
id: canonicalize_request.id,
|
110
|
-
error: e.message
|
111
|
-
)
|
112
|
-
end
|
113
|
-
|
114
|
-
if result&.key? :contents
|
115
|
-
@import_responses[url] = EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
116
|
-
id: canonicalize_request.id,
|
117
|
-
success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
118
|
-
contents: result[:contents],
|
119
|
-
syntax: EmbeddedProtocol::Syntax::SCSS,
|
120
|
-
source_map_url: nil
|
121
|
-
)
|
122
|
-
)
|
123
|
-
EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
124
|
-
id: canonicalize_request.id,
|
125
|
-
url: url
|
126
|
-
)
|
127
|
-
elsif result&.key? :file
|
128
|
-
canonicalized_url = Util.file_uri_from_path(File.absolute_path(result[:file]))
|
129
|
-
|
130
|
-
# TODO: FileImportRequest is not supported yet.
|
131
|
-
# Workaround by reading contents and return it when server asks
|
132
|
-
@import_responses[canonicalized_url] = EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
133
|
-
id: canonicalize_request.id,
|
134
|
-
success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
135
|
-
contents: File.read(result[:file]),
|
136
|
-
syntax: EmbeddedProtocol::Syntax::SCSS,
|
137
|
-
source_map_url: nil
|
138
|
-
)
|
139
|
-
)
|
156
|
+
url = importer_with_id(canonicalize_request.importer_id).canonicalize canonicalize_request.url
|
140
157
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
158
|
+
EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
159
|
+
id: canonicalize_request.id,
|
160
|
+
url: url
|
161
|
+
)
|
162
|
+
rescue StandardError => e
|
163
|
+
EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
164
|
+
id: canonicalize_request.id,
|
165
|
+
error: e.message
|
166
|
+
)
|
150
167
|
end
|
151
168
|
|
152
169
|
def import_response(import_request)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
170
|
+
importer_result = importer_with_id(import_request.importer_id).load import_request.url
|
171
|
+
|
172
|
+
EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
173
|
+
id: import_request.id,
|
174
|
+
success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
175
|
+
contents: importer_result.contents,
|
176
|
+
syntax: to_proto_syntax(importer_result.syntax),
|
177
|
+
source_map_url: importer_result.source_map_url
|
161
178
|
)
|
162
|
-
|
179
|
+
)
|
180
|
+
rescue StandardError => e
|
181
|
+
EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
182
|
+
id: import_request.id,
|
183
|
+
error: e.message
|
184
|
+
)
|
185
|
+
end
|
163
186
|
|
164
|
-
|
187
|
+
def file_import_response(file_import_request)
|
188
|
+
file_importer = importer_with_id(file_import_request.importer_id)
|
189
|
+
file_url = file_importer.find_file_url file_import_request.url,
|
190
|
+
from_import: file_import_request.from_import
|
191
|
+
|
192
|
+
EmbeddedProtocol::InboundMessage::FileImportResponse.new(
|
193
|
+
id: file_import_request.id,
|
194
|
+
file_url: file_url
|
195
|
+
)
|
196
|
+
rescue StandardError => e
|
197
|
+
EmbeddedProtocol::InboundMessage::FileImportResponse.new(
|
198
|
+
id: file_import_request.id,
|
199
|
+
error: e.message
|
200
|
+
)
|
165
201
|
end
|
166
202
|
|
167
203
|
def function_call_response(function_call_request)
|
168
|
-
# TODO: convert argument_list to **kwargs
|
169
204
|
EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
170
205
|
id: function_call_request.id,
|
171
206
|
success: @functions[function_call_request.name].call(*function_call_request.arguments),
|
172
207
|
accessed_argument_lists: function_call_request.arguments
|
173
|
-
|
174
|
-
|
208
|
+
.filter { |argument| argument.value == :argument_list }
|
209
|
+
.map { |argument| argument.argument_list.id }
|
175
210
|
)
|
176
211
|
rescue StandardError => e
|
177
212
|
EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
@@ -180,36 +215,21 @@ module Sass
|
|
180
215
|
)
|
181
216
|
end
|
182
217
|
|
183
|
-
def syntax
|
184
|
-
|
218
|
+
def to_proto_syntax(syntax)
|
219
|
+
case syntax&.to_sym
|
220
|
+
when :scss
|
221
|
+
EmbeddedProtocol::Syntax::SCSS
|
222
|
+
when :indented
|
185
223
|
EmbeddedProtocol::Syntax::INDENTED
|
224
|
+
when :css
|
225
|
+
EmbeddedProtocol::Syntax::CSS
|
186
226
|
else
|
187
|
-
|
227
|
+
raise ArgumentError, 'syntax must be one of :scss, :indented, :css'
|
188
228
|
end
|
189
229
|
end
|
190
230
|
|
191
|
-
def
|
192
|
-
|
193
|
-
|
194
|
-
Util.file_uri_from_path File.absolute_path @file
|
195
|
-
end
|
196
|
-
|
197
|
-
def string
|
198
|
-
return if @data.nil?
|
199
|
-
|
200
|
-
EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
|
201
|
-
source: @data,
|
202
|
-
url: url,
|
203
|
-
syntax: syntax
|
204
|
-
)
|
205
|
-
end
|
206
|
-
|
207
|
-
def path
|
208
|
-
@file if @data.nil?
|
209
|
-
end
|
210
|
-
|
211
|
-
def style
|
212
|
-
case @output_style&.to_sym
|
231
|
+
def to_proto_output_style(style)
|
232
|
+
case style&.to_sym
|
213
233
|
when :expanded
|
214
234
|
EmbeddedProtocol::OutputStyle::EXPANDED
|
215
235
|
when :compressed
|
@@ -219,35 +239,40 @@ module Sass
|
|
219
239
|
end
|
220
240
|
end
|
221
241
|
|
222
|
-
def
|
223
|
-
|
224
|
-
end
|
225
|
-
|
226
|
-
attr_reader :global_functions
|
227
|
-
|
228
|
-
# Order
|
229
|
-
# 1. Loading a file relative to the file in which the @use or @import appeared.
|
230
|
-
# 2. Each custom importer.
|
231
|
-
# 3. Loading a file relative to the current working directory.
|
232
|
-
# 4. Each load path in includePaths
|
233
|
-
# 5. Each load path specified in the SASS_PATH environment variable, which should
|
234
|
-
# be semicolon-separated on Windows and colon-separated elsewhere.
|
235
|
-
def importers
|
236
|
-
custom_importers = @importer.map.with_index do |_, id|
|
242
|
+
def to_proto_importer(importer, id)
|
243
|
+
if importer.respond_to?(:canonicalize) && importer.respond_to?(:load)
|
237
244
|
EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
238
245
|
importer_id: id
|
239
246
|
)
|
247
|
+
elsif importer.respond_to?(:find_file_url)
|
248
|
+
EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
249
|
+
file_importer_id: id
|
250
|
+
)
|
251
|
+
else
|
252
|
+
raise ArgumentError, 'importer must be an Importer or a FileImporter'
|
240
253
|
end
|
254
|
+
end
|
241
255
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
256
|
+
def to_proto_importers(importers, load_paths)
|
257
|
+
proto_importers = importers.map.with_index do |importer, id|
|
258
|
+
to_proto_importer(importer, id)
|
259
|
+
end
|
260
|
+
|
261
|
+
load_paths.each do |load_path|
|
262
|
+
proto_importers << EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
263
|
+
path: File.absolute_path(load_path)
|
247
264
|
)
|
248
265
|
end
|
249
266
|
|
250
|
-
|
267
|
+
proto_importers
|
268
|
+
end
|
269
|
+
|
270
|
+
def importer_with_id(id)
|
271
|
+
if id == @importers.length
|
272
|
+
@importer
|
273
|
+
else
|
274
|
+
@importers[id]
|
275
|
+
end
|
251
276
|
end
|
252
277
|
end
|
253
278
|
end
|
@@ -4,7 +4,7 @@ require 'observer'
|
|
4
4
|
require 'open3'
|
5
5
|
require_relative '../embedded_protocol'
|
6
6
|
require_relative 'compiler/path'
|
7
|
-
require_relative '
|
7
|
+
require_relative 'protocol_error'
|
8
8
|
|
9
9
|
module Sass
|
10
10
|
class Embedded
|
@@ -17,9 +17,9 @@ module Sass
|
|
17
17
|
ONEOF_MESSAGE = EmbeddedProtocol::InboundMessage
|
18
18
|
.descriptor
|
19
19
|
.lookup_oneof('message')
|
20
|
-
.
|
20
|
+
.to_h do |field_descriptor|
|
21
21
|
[field_descriptor.subtype, field_descriptor.name]
|
22
|
-
end
|
22
|
+
end
|
23
23
|
|
24
24
|
private_constant :ONEOF_MESSAGE
|
25
25
|
|
@@ -41,7 +41,7 @@ module Sass
|
|
41
41
|
|
42
42
|
def add_observer(*args)
|
43
43
|
@observerable_mutex.synchronize do
|
44
|
-
raise
|
44
|
+
raise ProtocolError, 'half-closed compiler' if half_closed?
|
45
45
|
|
46
46
|
super(*args)
|
47
47
|
|