sass-embedded 0.3.0 → 0.6.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/.rubocop.yml +0 -3
- data/README.md +26 -0
- data/ext/extconf.rb +14 -2
- data/lib/sass.rb +59 -37
- data/lib/sass/embedded.rb +159 -245
- data/lib/sass/error.rb +8 -6
- data/lib/sass/info.rb +30 -0
- data/lib/sass/observer.rb +37 -0
- data/lib/sass/render.rb +242 -0
- data/lib/sass/result.rb +30 -0
- data/lib/sass/struct.rb +20 -0
- data/lib/sass/transport.rb +30 -66
- data/lib/sass/util.rb +24 -4
- data/lib/sass/version.rb +1 -1
- data/sass-embedded.gemspec +1 -1
- data/test/concurrency_test.rb +34 -0
- data/test/functions_test.rb +4 -0
- data/test/{custom_importer_test.rb → importer_test.rb} +1 -1
- data/test/include_paths_test.rb +81 -0
- data/test/indented_syntax_test.rb +61 -0
- data/test/input_test.rb +56 -0
- data/test/output_test.rb +136 -0
- data/test/{error_test.rb → render_error_test.rb} +17 -2
- data/test/{sass_test.rb → render_test.rb} +3 -2
- data/test/source_maps_test.rb +178 -0
- data/test/test_helper.rb +1 -0
- metadata +26 -13
- data/test/compiler_test.rb +0 -262
- data/test/output_style_test.rb +0 -93
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8c00ba9bcce40d392862171f66b9ff3ef2ce1ef13e0a9d30a8541bc93804f6e
|
4
|
+
data.tar.gz: 9d4ccb5ab536b1f6a76a0e350a1244e00059d42db1ce666e5f7b19a84343424c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c6e542f29de342a3e9358136d3dda10be13d74c44c1a0e86be21f22a96997835a192aaf041d4a16d4092317de272d8be5589ad9075504057c9dbd7992be8b39
|
7
|
+
data.tar.gz: c05f1f8cd413387803ee9078fbb6670f21fc24ddde8b2661f64b495b7418ebea1488b496d98bcad9ebedd6e4f04532441652bf3b8aa2f4587a3780df548c0318
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -6,6 +6,12 @@ This is a Ruby library that implements the host side of the [Embedded Sass proto
|
|
6
6
|
|
7
7
|
It exposes a Ruby API for Sass that's backed by a native [Dart Sass](https://sass-lang.com/dart-sass) executable.
|
8
8
|
|
9
|
+
## Install
|
10
|
+
|
11
|
+
``` sh
|
12
|
+
gem install sass-embedded
|
13
|
+
```
|
14
|
+
|
9
15
|
## Usage
|
10
16
|
|
11
17
|
``` ruby
|
@@ -14,6 +20,26 @@ require "sass"
|
|
14
20
|
Sass.render(file: "style.scss")
|
15
21
|
```
|
16
22
|
|
23
|
+
## Options
|
24
|
+
|
25
|
+
`Sass.render()` support the following options:
|
26
|
+
|
27
|
+
- [`data`](https://sass-lang.com/documentation/js-api#data)
|
28
|
+
- [`file`](https://sass-lang.com/documentation/js-api#file)
|
29
|
+
- [`indented_syntax`](https://sass-lang.com/documentation/js-api#indentedsyntax)
|
30
|
+
- [`include_paths`](https://sass-lang.com/documentation/js-api#includepaths)
|
31
|
+
- [`output_style`](https://sass-lang.com/documentation/js-api#outputstyle)
|
32
|
+
- [`indent_type`](https://sass-lang.com/documentation/js-api#indenttype)
|
33
|
+
- [`indent_width`](https://sass-lang.com/documentation/js-api#indentwidth)
|
34
|
+
- [`linefeed`](https://sass-lang.com/documentation/js-api#linefeed)
|
35
|
+
- [`source_map`](https://sass-lang.com/documentation/js-api#sourcemap)
|
36
|
+
- [`out_file`](https://sass-lang.com/documentation/js-api#outfile)
|
37
|
+
- [`omit_source_map_url`](https://sass-lang.com/documentation/js-api#omitsourcemapurl)
|
38
|
+
- [`source_map_embed`](https://sass-lang.com/documentation/js-api#sourcemapembed)
|
39
|
+
- [`source_map_root`](https://sass-lang.com/documentation/js-api#sourcemaproot)
|
40
|
+
- [`functions`](https://sass-lang.com/documentation/js-api#functions)
|
41
|
+
- [`importer`](https://sass-lang.com/documentation/js-api#importer)
|
42
|
+
|
17
43
|
---
|
18
44
|
|
19
45
|
Disclaimer: this is not an official Google product.
|
data/ext/extconf.rb
CHANGED
@@ -8,12 +8,24 @@ require 'fileutils'
|
|
8
8
|
require_relative '../lib/sass/platform'
|
9
9
|
|
10
10
|
module Sass
|
11
|
-
#
|
11
|
+
# The dependency downloader. This downloads all the dependencies during gem
|
12
|
+
# installation. The companion Makefile then unpacks all downloaded
|
13
|
+
# dependencies. By default it downloads the latest release of each
|
14
|
+
# dependency from GitHub releases.
|
15
|
+
#
|
16
|
+
# It is possible to specify an alternative source or version of each
|
17
|
+
# dependency. Local sources can be used for offline installation.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# gem install sass-embedded -- \
|
21
|
+
# --with-protoc=file:///path/to/protoc-*.zip \
|
22
|
+
# --with-sass-embedded=file:///path/to/sass_embedded-*.(tar.gz|zip) \
|
23
|
+
# --with-sass-embedded-protocol=file:///path/to/embedded_sass.proto
|
12
24
|
class Extconf
|
13
25
|
def initialize
|
26
|
+
get_with_config('protoc', true) { latest_protoc }
|
14
27
|
get_with_config('sass-embedded', true) { latest_sass_embedded }
|
15
28
|
get_with_config('sass-embedded-protocol', true) { latest_sass_embedded_protocol }
|
16
|
-
get_with_config('protoc', true) { latest_protoc }
|
17
29
|
end
|
18
30
|
|
19
31
|
private
|
data/lib/sass.rb
CHANGED
@@ -1,50 +1,72 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# The Sass module
|
3
|
+
# The Sass module. This communicates with Embedded Dart Sass using
|
4
|
+
# the Embedded Sass protocol.
|
4
5
|
module Sass
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
6
|
+
class << self
|
7
|
+
# The global {.include_paths} for Sass files. This is meant for plugins and
|
8
|
+
# libraries to register the paths to their Sass stylesheets to that they may
|
9
|
+
# be included via `@import` or `@use`. This include path is used by every
|
10
|
+
# instance of {Sass::Embedded}. They are lower-precedence than any include
|
11
|
+
# paths passed in via the `include_paths` option.
|
12
|
+
#
|
13
|
+
# If the `SASS_PATH` environment variable is set,
|
14
|
+
# the initial value of `include_paths` will be initialized based on that.
|
15
|
+
# The variable should be a colon-separated list of path names
|
16
|
+
# (semicolon-separated on Windows).
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# Sass.include_paths << File.dirname(__FILE__) + '/sass'
|
20
|
+
# @return [Array]
|
21
|
+
def include_paths
|
22
|
+
@include_paths ||= if ENV['SASS_PATH']
|
23
|
+
ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
|
24
|
+
else
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# The global {.info} method. This instantiates a global {Embedded} instance
|
30
|
+
# and calls {Embedded#info}.
|
31
|
+
#
|
32
|
+
# @raise [ProtocolError]
|
33
|
+
def info
|
34
|
+
embedded.info
|
35
|
+
end
|
36
|
+
|
37
|
+
# The global {.render} method. This instantiates a global {Embedded} instance
|
38
|
+
# and calls {Embedded#render}.
|
39
|
+
#
|
40
|
+
# See {file:README.md#options} for supported options.
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# Sass.render(data: 'h1 { font-size: 40px; }')
|
44
|
+
# @example
|
45
|
+
# Sass.render(file: 'style.css')
|
46
|
+
# @return [Result]
|
47
|
+
# @raise [ProtocolError]
|
48
|
+
# @raise [RenderError]
|
49
|
+
def render(**kwargs)
|
50
|
+
embedded.render(**kwargs)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def embedded
|
56
|
+
return @embedded if defined?(@embedded) && !@embedded.closed?
|
26
57
|
|
27
|
-
# The global render methods. This method automatically instantiates a
|
28
|
-
# global {Sass::Embedded} instance when invoked the first time and call
|
29
|
-
# `:render` method on the instance thereafter. The global {Sass::Embedded}
|
30
|
-
# is automatically closed via {Kernel.at_exit}.
|
31
|
-
# @example
|
32
|
-
# Sass.render(options)
|
33
|
-
# @return [Hash]
|
34
|
-
def self.render(**kwargs)
|
35
|
-
unless defined? @embedded
|
36
58
|
@embedded = Sass::Embedded.new
|
37
|
-
at_exit do
|
38
|
-
@embedded.close
|
39
|
-
end
|
40
59
|
end
|
41
|
-
@embedded.render(**kwargs)
|
42
60
|
end
|
43
61
|
end
|
44
62
|
|
45
|
-
require_relative 'sass/version'
|
46
|
-
require_relative 'sass/error'
|
47
63
|
require_relative 'sass/platform'
|
48
64
|
require_relative 'sass/util'
|
65
|
+
require_relative 'sass/struct'
|
66
|
+
require_relative 'sass/result'
|
67
|
+
require_relative 'sass/error'
|
49
68
|
require_relative 'sass/transport'
|
69
|
+
require_relative 'sass/observer'
|
70
|
+
require_relative 'sass/version'
|
71
|
+
require_relative 'sass/render'
|
50
72
|
require_relative 'sass/embedded'
|
data/lib/sass/embedded.rb
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
|
3
6
|
module Sass
|
4
|
-
# The
|
7
|
+
# The {Embedded} host for using dart-sass-embedded. Each instance creates
|
8
|
+
# its own {Transport}.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# embedded = Sass::Embedded.new
|
12
|
+
# result = embedded.render(data: 'h1 { font-size: 40px; }')
|
13
|
+
# result = embedded.render(file: 'style.css')
|
14
|
+
# embedded.close
|
5
15
|
class Embedded
|
6
16
|
def initialize
|
7
17
|
@transport = Transport.new
|
@@ -9,308 +19,212 @@ module Sass
|
|
9
19
|
@id = 0
|
10
20
|
end
|
11
21
|
|
12
|
-
#
|
22
|
+
# The {Embedded#info} method.
|
23
|
+
#
|
24
|
+
# @raise [ProtocolError]
|
25
|
+
def info
|
26
|
+
@info ||= Version.new(@transport, next_id).fetch
|
27
|
+
end
|
13
28
|
|
29
|
+
# The {Embedded#render} method.
|
30
|
+
#
|
31
|
+
# See {file:README.md#options} for supported options.
|
32
|
+
#
|
33
|
+
# @return [Result]
|
34
|
+
# @raise [ProtocolError]
|
35
|
+
# @raise [RenderError]
|
14
36
|
def render(data: nil,
|
15
37
|
file: nil,
|
16
38
|
indented_syntax: false,
|
17
39
|
include_paths: [],
|
18
40
|
output_style: :expanded,
|
19
|
-
precision: 5,
|
20
41
|
indent_type: :space,
|
21
42
|
indent_width: 2,
|
22
43
|
linefeed: :lf,
|
23
|
-
source_comments: false,
|
24
44
|
source_map: false,
|
25
45
|
out_file: nil,
|
26
46
|
omit_source_map_url: false,
|
27
|
-
source_map_contents: false,
|
47
|
+
# source_map_contents: false,
|
28
48
|
source_map_embed: false,
|
29
49
|
source_map_root: '',
|
30
50
|
functions: {},
|
31
51
|
importer: [])
|
32
|
-
# rubocop:enable Lint/UnusedMethodArgument
|
33
|
-
|
34
52
|
start = Util.now
|
35
53
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
loop do
|
53
|
-
case response
|
54
|
-
when EmbeddedProtocol::OutboundMessage::CompileResponse
|
55
|
-
break
|
56
|
-
when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
|
57
|
-
response = @transport.send renderer.canonicalize_response(response), compilation_id
|
58
|
-
when EmbeddedProtocol::OutboundMessage::ImportRequest
|
59
|
-
response = @transport.send renderer.import_response(response), compilation_id
|
60
|
-
when EmbeddedProtocol::OutboundMessage::FunctionCallRequest
|
61
|
-
response = @transport.send renderer.function_call_response(response), compilation_id
|
62
|
-
when EmbeddedProtocol::ProtocolError
|
63
|
-
raise ProtocolError, response.message
|
64
|
-
else
|
65
|
-
raise ProtocolError, "Unexpected packet received: #{response}"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
if response.failure
|
54
|
+
indent_type = parse_indent_type(indent_type)
|
55
|
+
indent_width = parse_indent_width(indent_width)
|
56
|
+
linefeed = parse_linefeed(linefeed)
|
57
|
+
|
58
|
+
message = Render.new(@transport, next_id,
|
59
|
+
data: data,
|
60
|
+
file: file,
|
61
|
+
indented_syntax: indented_syntax,
|
62
|
+
include_paths: include_paths,
|
63
|
+
output_style: output_style,
|
64
|
+
source_map: source_map,
|
65
|
+
out_file: out_file,
|
66
|
+
functions: functions,
|
67
|
+
importer: importer).fetch
|
68
|
+
|
69
|
+
if message.failure
|
70
70
|
raise RenderError.new(
|
71
|
-
|
72
|
-
|
73
|
-
if
|
74
|
-
|
71
|
+
message.failure.message,
|
72
|
+
message.failure.formatted,
|
73
|
+
if message.failure.span.nil?
|
74
|
+
nil
|
75
|
+
elsif message.failure.span.url == ''
|
76
|
+
'stdin'
|
77
|
+
else
|
78
|
+
Util.path(message.failure.span.url)
|
75
79
|
end,
|
76
|
-
|
77
|
-
|
80
|
+
message.failure.span ? message.failure.span.start.line + 1 : nil,
|
81
|
+
message.failure.span ? message.failure.span.start.column + 1 : nil,
|
78
82
|
1
|
79
83
|
)
|
80
84
|
end
|
81
85
|
|
86
|
+
map, source_map = post_process_map(map: message.success.source_map,
|
87
|
+
file: file,
|
88
|
+
out_file: out_file,
|
89
|
+
source_map: source_map,
|
90
|
+
source_map_root: source_map_root)
|
91
|
+
|
92
|
+
css = post_process_css(css: message.success.css,
|
93
|
+
indent_type: indent_type,
|
94
|
+
indent_width: indent_width,
|
95
|
+
linefeed: linefeed,
|
96
|
+
map: map,
|
97
|
+
out_file: out_file,
|
98
|
+
omit_source_map_url: omit_source_map_url,
|
99
|
+
source_map: source_map,
|
100
|
+
source_map_embed: source_map_embed)
|
101
|
+
|
82
102
|
finish = Util.now
|
83
103
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
stats: {
|
88
|
-
entry: file.nil? ? 'data' : file,
|
89
|
-
start: start,
|
90
|
-
end: finish,
|
91
|
-
duration: finish - start
|
92
|
-
}
|
93
|
-
}
|
104
|
+
stats = Result::Stats.new(file.nil? ? 'data' : file, start, finish, finish - start)
|
105
|
+
|
106
|
+
Result.new(css, map, stats)
|
94
107
|
end
|
95
108
|
|
96
109
|
def close
|
97
110
|
@transport.close
|
98
|
-
nil
|
99
111
|
end
|
100
112
|
|
101
|
-
|
102
|
-
|
103
|
-
def info
|
104
|
-
version_response = @transport.send EmbeddedProtocol::InboundMessage::VersionRequest.new(
|
105
|
-
id: next_id
|
106
|
-
)
|
107
|
-
{
|
108
|
-
compiler_version: version_response.compiler_version,
|
109
|
-
protocol_version: version_response.protocol_version,
|
110
|
-
implementation_name: version_response.implementation_name,
|
111
|
-
implementation_version: version_response.implementation_version
|
112
|
-
}
|
113
|
+
def closed?
|
114
|
+
@transport.closed?
|
113
115
|
end
|
114
116
|
|
115
|
-
|
116
|
-
@id_semaphore.synchronize do
|
117
|
-
@id += 1
|
118
|
-
@id = 0 if @id == Transport::PROTOCOL_ERROR_ID
|
119
|
-
@id
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# Helper class that maintains render state
|
124
|
-
class Renderer
|
125
|
-
def initialize(data:,
|
126
|
-
file:,
|
127
|
-
indented_syntax:,
|
128
|
-
include_paths:,
|
129
|
-
output_style:,
|
130
|
-
source_map:,
|
131
|
-
out_file:,
|
132
|
-
functions:,
|
133
|
-
importer:)
|
134
|
-
raise ArgumentError, 'Either :data or :file must be set.' if file.nil? && data.nil?
|
117
|
+
private
|
135
118
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
@out_file = out_file
|
143
|
-
@global_functions = functions.keys
|
144
|
-
@functions = functions.transform_keys do |key|
|
145
|
-
key.to_s.split('(')[0].chomp
|
146
|
-
end
|
147
|
-
@importer = importer
|
148
|
-
@import_responses = {}
|
149
|
-
end
|
119
|
+
def post_process_map(map:,
|
120
|
+
file:,
|
121
|
+
out_file:,
|
122
|
+
source_map:,
|
123
|
+
source_map_root:)
|
124
|
+
return if map.nil? || map.empty?
|
150
125
|
|
151
|
-
|
152
|
-
EmbeddedProtocol::InboundMessage::CompileRequest.new(
|
153
|
-
id: id,
|
154
|
-
string: string,
|
155
|
-
path: path,
|
156
|
-
style: style,
|
157
|
-
source_map: source_map,
|
158
|
-
importers: importers,
|
159
|
-
global_functions: global_functions,
|
160
|
-
alert_color: $stderr.tty?,
|
161
|
-
alert_ascii: Platform::OS == 'windows'
|
162
|
-
)
|
163
|
-
end
|
164
|
-
|
165
|
-
def canonicalize_response(canonicalize_request)
|
166
|
-
url = Util.file_uri(File.absolute_path(canonicalize_request.url, (@file.nil? ? 'stdin' : @file)))
|
126
|
+
map_data = JSON.parse(map)
|
167
127
|
|
168
|
-
|
169
|
-
result = @importer[canonicalize_request.importer_id].call canonicalize_request.url, @file
|
170
|
-
raise result if result.is_a? StandardError
|
171
|
-
rescue StandardError => e
|
172
|
-
return EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
173
|
-
id: canonicalize_request.id,
|
174
|
-
error: e.message
|
175
|
-
)
|
176
|
-
end
|
128
|
+
map_data['sourceRoot'] = source_map_root
|
177
129
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
syntax: EmbeddedProtocol::Syntax::SCSS,
|
184
|
-
source_map_url: nil
|
185
|
-
)
|
186
|
-
)
|
187
|
-
EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
188
|
-
id: canonicalize_request.id,
|
189
|
-
url: url
|
190
|
-
)
|
191
|
-
elsif result&.key? :file
|
192
|
-
canonicalized_url = Util.file_uri(result[:file])
|
130
|
+
source_map_path = if source_map.is_a? String
|
131
|
+
source_map
|
132
|
+
else
|
133
|
+
"#{out_file}.map"
|
134
|
+
end
|
193
135
|
|
194
|
-
|
195
|
-
# Workaround by reading contents and return it when server asks
|
196
|
-
@import_responses[canonicalized_url] = EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
197
|
-
id: canonicalize_request.id,
|
198
|
-
success: EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
199
|
-
contents: File.read(result[:file]),
|
200
|
-
syntax: EmbeddedProtocol::Syntax::SCSS,
|
201
|
-
source_map_url: nil
|
202
|
-
)
|
203
|
-
)
|
136
|
+
source_map_dir = File.dirname(source_map_path)
|
204
137
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
)
|
213
|
-
end
|
138
|
+
if out_file
|
139
|
+
map_data['file'] = Util.relative(source_map_dir, out_file)
|
140
|
+
elsif file
|
141
|
+
ext = File.extname(file)
|
142
|
+
map_data['file'] = "#{file[0..(ext.empty? ? -1 : -ext.length - 1)]}.css"
|
143
|
+
else
|
144
|
+
map_data['file'] = 'stdin.css'
|
214
145
|
end
|
215
146
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
if @import_responses.key? url
|
220
|
-
@import_responses[url].id = import_request.id
|
147
|
+
map_data['sources'].map! do |source|
|
148
|
+
if source.start_with? Util::FILE_PROTOCOL
|
149
|
+
Util.relative(source_map_dir, Util.path(source))
|
221
150
|
else
|
222
|
-
|
223
|
-
id: import_request.id,
|
224
|
-
error: "Failed to import: #{url}"
|
225
|
-
)
|
151
|
+
source
|
226
152
|
end
|
227
|
-
|
228
|
-
@import_responses[url]
|
229
|
-
end
|
230
|
-
|
231
|
-
def function_call_response(function_call_request)
|
232
|
-
EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
233
|
-
id: function_call_request.id,
|
234
|
-
success: @functions[function_call_request.name].call(*function_call_request.arguments)
|
235
|
-
)
|
236
|
-
rescue StandardError => e
|
237
|
-
EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
238
|
-
id: function_call_request.id,
|
239
|
-
error: e.message
|
240
|
-
)
|
241
153
|
end
|
242
154
|
|
243
|
-
|
155
|
+
[-JSON.generate(map_data), source_map_path]
|
156
|
+
end
|
244
157
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
158
|
+
def post_process_css(css:,
|
159
|
+
indent_type:,
|
160
|
+
indent_width:,
|
161
|
+
linefeed:,
|
162
|
+
map:,
|
163
|
+
omit_source_map_url:,
|
164
|
+
out_file:,
|
165
|
+
source_map:,
|
166
|
+
source_map_embed:)
|
167
|
+
css = +css
|
168
|
+
if indent_width != 2 || indent_type.to_sym != :space
|
169
|
+
indent = indent_type * indent_width
|
170
|
+
css.gsub!(/^ +/) do |space|
|
171
|
+
indent * (space.length / 2)
|
250
172
|
end
|
251
173
|
end
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
174
|
+
css.gsub!("\n", linefeed) if linefeed != "\n"
|
175
|
+
|
176
|
+
unless map.nil? || omit_source_map_url == true
|
177
|
+
url = if source_map_embed
|
178
|
+
"data:application/json;base64,#{Base64.strict_encode64(map)}"
|
179
|
+
elsif out_file
|
180
|
+
Util.relative(File.dirname(out_file), source_map)
|
181
|
+
else
|
182
|
+
source_map
|
183
|
+
end
|
184
|
+
css += "#{linefeed}/*# sourceMappingURL=#{url} */"
|
257
185
|
end
|
258
186
|
|
259
|
-
|
260
|
-
|
187
|
+
-css
|
188
|
+
end
|
261
189
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
190
|
+
def parse_indent_type(indent_type)
|
191
|
+
case indent_type.to_sym
|
192
|
+
when :space
|
193
|
+
' '
|
194
|
+
when :tab
|
195
|
+
"\t"
|
196
|
+
else
|
197
|
+
raise ArgumentError, 'indent_type must be one of :space, :tab'
|
267
198
|
end
|
199
|
+
end
|
268
200
|
|
269
|
-
|
270
|
-
|
271
|
-
|
201
|
+
def parse_indent_width(indent_width)
|
202
|
+
raise ArgumentError, 'indent_width must be an integer' unless indent_width.is_a? Integer
|
203
|
+
raise RangeError, 'indent_width must be in between 0 and 10 (inclusive)' unless indent_width.between? 0, 10
|
272
204
|
|
273
|
-
|
274
|
-
|
275
|
-
when :expanded
|
276
|
-
EmbeddedProtocol::OutputStyle::EXPANDED
|
277
|
-
when :compressed
|
278
|
-
EmbeddedProtocol::OutputStyle::COMPRESSED
|
279
|
-
when :nested, :compact
|
280
|
-
raise ArgumentError, "#{@output_style} is not a supported output_style"
|
281
|
-
else
|
282
|
-
raise ArgumentError, "#{@output_style} is not a valid utput_style"
|
283
|
-
end
|
284
|
-
end
|
205
|
+
indent_width
|
206
|
+
end
|
285
207
|
|
286
|
-
|
287
|
-
|
208
|
+
def parse_linefeed(linefeed)
|
209
|
+
case linefeed.to_sym
|
210
|
+
when :lf
|
211
|
+
"\n"
|
212
|
+
when :lfcr
|
213
|
+
"\n\r"
|
214
|
+
when :cr
|
215
|
+
"\r"
|
216
|
+
when :crlf
|
217
|
+
"\r\n"
|
218
|
+
else
|
219
|
+
raise ArgumentError, 'linefeed must be one of :lf, :lfcr, :cr, :crlf'
|
288
220
|
end
|
221
|
+
end
|
289
222
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
# 3. Loading a file relative to the current working directory.
|
296
|
-
# 4. Each load path in includePaths
|
297
|
-
# 5. Each load path specified in the SASS_PATH environment variable, which should be semicolon-separated on Windows and colon-separated elsewhere.
|
298
|
-
def importers
|
299
|
-
custom_importers = @importer.map.with_index do |_, id|
|
300
|
-
EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
301
|
-
importer_id: id
|
302
|
-
)
|
303
|
-
end
|
304
|
-
|
305
|
-
include_path_importers = @include_paths
|
306
|
-
.concat(Sass.include_paths)
|
307
|
-
.map do |include_path|
|
308
|
-
EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
309
|
-
path: File.absolute_path(include_path)
|
310
|
-
)
|
311
|
-
end
|
312
|
-
|
313
|
-
custom_importers.concat include_path_importers
|
223
|
+
def next_id
|
224
|
+
@id_semaphore.synchronize do
|
225
|
+
@id += 1
|
226
|
+
@id = 0 if @id == Transport::PROTOCOL_ERROR_ID
|
227
|
+
@id
|
314
228
|
end
|
315
229
|
end
|
316
230
|
end
|