sass-embedded 0.2.4 → 0.5.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/.github/workflows/build.yml +1 -1
- data/.rubocop.yml +11 -0
- data/README.md +1 -3
- data/Rakefile +9 -4
- data/ext/extconf.rb +15 -2
- data/lib/sass.rb +49 -27
- data/lib/sass/embedded.rb +186 -194
- data/lib/sass/error.rb +4 -9
- data/lib/sass/info.rb +30 -0
- data/lib/sass/observer.rb +38 -0
- data/lib/sass/render.rb +242 -0
- data/lib/sass/transport.rb +55 -80
- data/lib/sass/util.rb +24 -3
- data/lib/sass/version.rb +1 -1
- data/sass-embedded.gemspec +3 -1
- data/test/concurrency_test.rb +34 -0
- data/test/functions_test.rb +153 -157
- data/test/{custom_importer_test.rb → importer_test.rb} +24 -31
- 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/render_error_test.rb +44 -0
- data/test/render_test.rb +19 -0
- data/test/source_maps_test.rb +178 -0
- data/test/test_helper.rb +1 -0
- metadata +53 -13
- data/test/compiler_test.rb +0 -276
- data/test/error_test.rb +0 -31
- data/test/output_style_test.rb +0 -93
- data/test/sass_test.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: d1086f5483670120b40e9741187e5150a5af9e9ad5d38159d6d57459edec350b
|
4
|
+
data.tar.gz: d6afead31f102a04ad4d11c82e1381b597c285ae0206564640763173e2b67fc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8c534da41310d6b7e6228624d26a6e3dd94bccc4b67b2e9a25bff82251cb3b4a5d312c58ec1e498f944731cc99f4fdcb66b117278640cee2fc3d81f95924f66
|
7
|
+
data.tar.gz: 6d8808fc65dbb7fc4b43976beb6c8573635d874e9d72a7949f20eda5406e582ea0933a99f844256ec284e3ecf1e8e6f02b967f50854fde661470bf6834550abb
|
data/.github/workflows/build.yml
CHANGED
data/.rubocop.yml
ADDED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -2,17 +2,22 @@
|
|
2
2
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
|
5
|
-
task default:
|
5
|
+
task default: %i[rubocop test]
|
6
6
|
|
7
7
|
desc 'Download dart-sass-embedded'
|
8
8
|
task :extconf do
|
9
|
-
system('make', '-C', 'ext', 'distclean')
|
10
|
-
require_relative 'ext/extconf'
|
11
9
|
system('make', '-C', 'ext')
|
12
10
|
end
|
13
11
|
|
14
12
|
desc 'Run all tests'
|
15
|
-
task :
|
13
|
+
task test: :extconf do
|
16
14
|
$LOAD_PATH.unshift('lib', 'test')
|
17
15
|
Dir.glob('./test/**/*_test.rb').sort.each { |f| require f }
|
18
16
|
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'rubocop/rake_task'
|
20
|
+
RuboCop::RakeTask.new
|
21
|
+
rescue LoadError
|
22
|
+
nil
|
23
|
+
end
|
data/ext/extconf.rb
CHANGED
@@ -8,11 +8,24 @@ require 'fileutils'
|
|
8
8
|
require_relative '../lib/sass/platform'
|
9
9
|
|
10
10
|
module Sass
|
11
|
+
# The dependency downloader. This will download all the dependencies
|
12
|
+
# during gem installation, and the Makefile will unpack all downloaded
|
13
|
+
# dependencies. By default it will download 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 \
|
11
24
|
class Extconf
|
12
25
|
def initialize
|
26
|
+
get_with_config('protoc', true) { latest_protoc }
|
13
27
|
get_with_config('sass-embedded', true) { latest_sass_embedded }
|
14
28
|
get_with_config('sass-embedded-protocol', true) { latest_sass_embedded_protocol }
|
15
|
-
get_with_config('protoc', true) { latest_protoc }
|
16
29
|
end
|
17
30
|
|
18
31
|
private
|
@@ -141,7 +154,7 @@ module Sass
|
|
141
154
|
|
142
155
|
ext = 'zip'
|
143
156
|
|
144
|
-
"https://github.com/#{repo}/releases/download/#{tag_name}/protoc-#{tag_name[1
|
157
|
+
"https://github.com/#{repo}/releases/download/#{tag_name}/protoc-#{tag_name[1..]}-#{os_arch}.#{ext}"
|
145
158
|
end
|
146
159
|
|
147
160
|
def latest_sass_embedded_protocol
|
data/lib/sass.rb
CHANGED
@@ -1,36 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# The Sass module. This module will communicate with Embedded Dart Sass using
|
4
|
+
# the Embedded Sass protocol.
|
3
5
|
module Sass
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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 `@imported`. This include path is used by every instance of
|
10
|
+
# {Sass::Embedded}. They are lower-precedence than any include paths passed
|
11
|
+
# 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<String, Pathname>]
|
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
|
+
def info
|
30
|
+
embedded.info
|
31
|
+
end
|
32
|
+
|
33
|
+
# The global render method. This method automatically instantiates a
|
34
|
+
# global {Sass::Embedded} instance when invoked the first time and call
|
35
|
+
# `:render` method on the instance thereafter. See {Sass::Embedded#render}
|
36
|
+
# for supported options.
|
37
|
+
# @example
|
38
|
+
# Sass.render(data: 'h1 { font-size: 40px; }')
|
39
|
+
# @example
|
40
|
+
# Sass.render(file: 'style.css')
|
41
|
+
# @return [Hash]
|
42
|
+
def render(**kwargs)
|
43
|
+
embedded.render(**kwargs)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def embedded
|
49
|
+
return @embedded if defined?(@embedded) && !@embedded.closed?
|
25
50
|
|
26
|
-
def self.render(options)
|
27
|
-
unless defined? @embedded
|
28
51
|
@embedded = Sass::Embedded.new
|
29
|
-
at_exit do
|
30
|
-
@embedded.close
|
31
|
-
end
|
32
52
|
end
|
33
|
-
@embedded.render options
|
34
53
|
end
|
35
54
|
end
|
36
55
|
|
@@ -39,4 +58,7 @@ require_relative 'sass/error'
|
|
39
58
|
require_relative 'sass/platform'
|
40
59
|
require_relative 'sass/util'
|
41
60
|
require_relative 'sass/transport'
|
61
|
+
require_relative 'sass/observer'
|
62
|
+
require_relative 'sass/info'
|
63
|
+
require_relative 'sass/render'
|
42
64
|
require_relative 'sass/embedded'
|
data/lib/sass/embedded.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
|
3
6
|
module Sass
|
7
|
+
# The {Embedded} user interface for using dart-sass-embedded. Each instance
|
8
|
+
# will create its own {Transport}.
|
9
|
+
# @example
|
10
|
+
# embedded = Sass::Embedded.new
|
11
|
+
# result = embedded.render(data: 'h1 { font-size: 40px; }')
|
12
|
+
# result = embedded.render(file: 'style.css')
|
13
|
+
# embedded.close
|
4
14
|
class Embedded
|
5
15
|
def initialize
|
6
16
|
@transport = Transport.new
|
@@ -8,198 +18,85 @@ module Sass
|
|
8
18
|
@id = 0
|
9
19
|
end
|
10
20
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
raise Sass::NotRenderedError, 'Either :data or :file must be set.' if options[:file].nil? && options[:data].nil?
|
15
|
-
|
16
|
-
string = if options[:data]
|
17
|
-
Sass::EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
|
18
|
-
source: options[:data],
|
19
|
-
url: options[:file] ? Sass::Util.file_uri(options[:file]) : 'stdin',
|
20
|
-
syntax: options[:indented_syntax] == true ? Sass::EmbeddedProtocol::Syntax::INDENTED : Sass::EmbeddedProtocol::Syntax::SCSS
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
path = options[:data] ? nil : options[:file]
|
25
|
-
|
26
|
-
style = case options[:output_style]&.to_sym
|
27
|
-
when :expanded, nil
|
28
|
-
Sass::EmbeddedProtocol::OutputStyle::EXPANDED
|
29
|
-
when :compressed
|
30
|
-
Sass::EmbeddedProtocol::OutputStyle::COMPRESSED
|
31
|
-
when :nested, :compact
|
32
|
-
raise Sass::UnsupportedValue, "#{options[:output_style]} is not a supported :output_style"
|
33
|
-
else
|
34
|
-
raise Sass::InvalidStyleError, "#{options[:output_style]} is not a valid :output_style"
|
35
|
-
end
|
36
|
-
|
37
|
-
source_map = options[:source_map].is_a?(String) || (options[:source_map] == true && !options[:out_file].nil?)
|
38
|
-
|
39
|
-
# 1. Loading a file relative to the file in which the @use or @import appeared.
|
40
|
-
# 2. Each custom importer.
|
41
|
-
# 3. Loading a file relative to the current working directory.
|
42
|
-
# 4. Each load path in includePaths
|
43
|
-
# 5. Each load path specified in the SASS_PATH environment variable, which should be semicolon-separated on Windows and colon-separated elsewhere.
|
44
|
-
importers = (if options[:importer]
|
45
|
-
[
|
46
|
-
Sass::EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(importer_id: 0)
|
47
|
-
]
|
48
|
-
else
|
49
|
-
[]
|
50
|
-
end).concat(
|
51
|
-
(options[:include_paths] || []).concat(Sass.include_paths)
|
52
|
-
.map do |include_path|
|
53
|
-
Sass::EmbeddedProtocol::InboundMessage::CompileRequest::Importer.new(
|
54
|
-
path: File.absolute_path(include_path)
|
55
|
-
)
|
56
|
-
end
|
57
|
-
)
|
58
|
-
|
59
|
-
signatures = []
|
60
|
-
functions = {}
|
61
|
-
options[:functions]&.each do |signature, function|
|
62
|
-
signatures.push signature
|
63
|
-
functions[signature.to_s.split('(')[0].chomp] = function
|
64
|
-
end
|
21
|
+
def info
|
22
|
+
@info ||= Info.new(@transport, next_id).fetch
|
23
|
+
end
|
65
24
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
25
|
+
def render(data: nil,
|
26
|
+
file: nil,
|
27
|
+
indented_syntax: false,
|
28
|
+
include_paths: [],
|
29
|
+
output_style: :expanded,
|
30
|
+
# precision: 5,
|
31
|
+
indent_type: :space,
|
32
|
+
indent_width: 2,
|
33
|
+
linefeed: :lf,
|
34
|
+
# source_comments: false,
|
35
|
+
source_map: false,
|
36
|
+
out_file: nil,
|
37
|
+
omit_source_map_url: false,
|
38
|
+
# source_map_contents: false,
|
39
|
+
source_map_embed: false,
|
40
|
+
source_map_root: '',
|
41
|
+
functions: {},
|
42
|
+
importer: [])
|
43
|
+
start = Util.now
|
44
|
+
|
45
|
+
indent_type = parse_indent_type(indent_type)
|
46
|
+
indent_width = parse_indent_width(indent_width)
|
47
|
+
linefeed = parse_linefeed(linefeed)
|
48
|
+
|
49
|
+
result = Render.new(@transport, next_id,
|
50
|
+
data: data,
|
51
|
+
file: file,
|
52
|
+
indented_syntax: indented_syntax,
|
53
|
+
include_paths: include_paths,
|
54
|
+
output_style: output_style,
|
55
|
+
source_map: source_map,
|
56
|
+
out_file: out_file,
|
57
|
+
functions: functions,
|
58
|
+
importer: importer).fetch
|
59
|
+
|
60
|
+
if result.failure
|
61
|
+
raise RenderError.new(
|
62
|
+
result.failure.message,
|
63
|
+
result.failure.formatted,
|
64
|
+
if result.failure.span.nil?
|
65
|
+
nil
|
66
|
+
elsif result.failure.span.url == ''
|
67
|
+
'stdin'
|
95
68
|
else
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
rescue StandardError => e
|
101
|
-
resolved = e
|
102
|
-
end
|
103
|
-
break if resolved
|
104
|
-
end
|
105
|
-
if resolved.nil?
|
106
|
-
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
107
|
-
id: response.id,
|
108
|
-
url: url
|
109
|
-
)
|
110
|
-
elsif resolved.is_a? StandardError
|
111
|
-
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
112
|
-
id: response.id,
|
113
|
-
error: resolved.message
|
114
|
-
)
|
115
|
-
elsif resolved.key? :contents
|
116
|
-
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
117
|
-
id: response.id,
|
118
|
-
url: url
|
119
|
-
)
|
120
|
-
imports[url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
121
|
-
id: response.id,
|
122
|
-
success: Sass::EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
123
|
-
contents: resolved[:contents],
|
124
|
-
syntax: Sass::EmbeddedProtocol::Syntax::SCSS,
|
125
|
-
source_map_url: nil
|
126
|
-
)
|
127
|
-
)
|
128
|
-
elsif resolved.key? :file
|
129
|
-
canonicalized_url = Sass::Util.file_uri(resolved[:file])
|
130
|
-
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
131
|
-
id: response.id,
|
132
|
-
url: canonicalized_url
|
133
|
-
)
|
134
|
-
imports[canonicalized_url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
135
|
-
id: response.id,
|
136
|
-
success: Sass::EmbeddedProtocol::InboundMessage::ImportResponse::ImportSuccess.new(
|
137
|
-
contents: File.read(resolved[:file]),
|
138
|
-
syntax: Sass::EmbeddedProtocol::Syntax::SCSS,
|
139
|
-
source_map_url: nil
|
140
|
-
)
|
141
|
-
)
|
142
|
-
else
|
143
|
-
canonicalizations[url] = Sass::EmbeddedProtocol::InboundMessage::CanonicalizeResponse.new(
|
144
|
-
id: response.id,
|
145
|
-
error: "Unexpected value returned from importer: #{resolved}"
|
146
|
-
)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
response = @transport.send canonicalizations[url], compilation_id
|
151
|
-
when Sass::EmbeddedProtocol::OutboundMessage::ImportRequest
|
152
|
-
url = response.url
|
153
|
-
|
154
|
-
if imports.key? url
|
155
|
-
imports[url].id = response.id
|
156
|
-
else
|
157
|
-
imports[url] = Sass::EmbeddedProtocol::InboundMessage::ImportResponse.new(
|
158
|
-
id: response.id,
|
159
|
-
error: "Failed to import: #{url}"
|
160
|
-
)
|
161
|
-
end
|
162
|
-
|
163
|
-
response = @transport.send imports[url], compilation_id
|
164
|
-
when Sass::EmbeddedProtocol::OutboundMessage::FunctionCallRequest
|
165
|
-
begin
|
166
|
-
message = Sass::EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
167
|
-
id: response.id,
|
168
|
-
success: functions[response.name].call(*response.arguments)
|
169
|
-
)
|
170
|
-
rescue StandardError => e
|
171
|
-
message = Sass::EmbeddedProtocol::InboundMessage::FunctionCallResponse.new(
|
172
|
-
id: response.id,
|
173
|
-
error: e.message
|
174
|
-
)
|
175
|
-
end
|
176
|
-
|
177
|
-
response = @transport.send message, compilation_id
|
178
|
-
when Sass::EmbeddedProtocol::ProtocolError
|
179
|
-
raise Sass::ProtocolError, response.message
|
180
|
-
else
|
181
|
-
raise Sass::ProtocolError, "Unexpected packet received: #{response}"
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
if response.failure
|
186
|
-
raise Sass::CompilationError.new(
|
187
|
-
response.failure.message,
|
188
|
-
response.failure.formatted,
|
189
|
-
response.failure.span ? response.failure.span.url : nil,
|
190
|
-
response.failure.span ? response.failure.span.start.line + 1 : nil,
|
191
|
-
response.failure.span ? response.failure.span.start.column + 1 : nil,
|
69
|
+
Util.path(result.failure.span.url)
|
70
|
+
end,
|
71
|
+
result.failure.span ? result.failure.span.start.line + 1 : nil,
|
72
|
+
result.failure.span ? result.failure.span.start.column + 1 : nil,
|
192
73
|
1
|
193
74
|
)
|
194
75
|
end
|
195
76
|
|
196
|
-
|
77
|
+
map, source_map = post_process_map(map: result.success.source_map,
|
78
|
+
file: file,
|
79
|
+
out_file: out_file,
|
80
|
+
source_map: source_map,
|
81
|
+
source_map_root: source_map_root)
|
82
|
+
|
83
|
+
css = post_process_css(css: result.success.css,
|
84
|
+
indent_type: indent_type,
|
85
|
+
indent_width: indent_width,
|
86
|
+
linefeed: linefeed,
|
87
|
+
map: map,
|
88
|
+
out_file: out_file,
|
89
|
+
omit_source_map_url: omit_source_map_url,
|
90
|
+
source_map: source_map,
|
91
|
+
source_map_embed: source_map_embed)
|
92
|
+
|
93
|
+
finish = Util.now
|
197
94
|
|
198
95
|
{
|
199
|
-
css:
|
200
|
-
map:
|
96
|
+
css: css,
|
97
|
+
map: map,
|
201
98
|
stats: {
|
202
|
-
entry:
|
99
|
+
entry: file.nil? ? 'data' : file,
|
203
100
|
start: start,
|
204
101
|
end: finish,
|
205
102
|
duration: finish - start
|
@@ -209,21 +106,116 @@ module Sass
|
|
209
106
|
|
210
107
|
def close
|
211
108
|
@transport.close
|
212
|
-
|
109
|
+
end
|
110
|
+
|
111
|
+
def closed?
|
112
|
+
@transport.closed?
|
213
113
|
end
|
214
114
|
|
215
115
|
private
|
216
116
|
|
217
|
-
def
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
117
|
+
def post_process_map(map:,
|
118
|
+
file:,
|
119
|
+
out_file:,
|
120
|
+
source_map:,
|
121
|
+
source_map_root:)
|
122
|
+
return if map.nil? || map.empty?
|
123
|
+
|
124
|
+
map_data = JSON.parse(map)
|
125
|
+
|
126
|
+
map_data['sourceRoot'] = source_map_root
|
127
|
+
|
128
|
+
source_map_path = if source_map.is_a? String
|
129
|
+
source_map
|
130
|
+
else
|
131
|
+
"#{out_file}.map"
|
132
|
+
end
|
133
|
+
|
134
|
+
source_map_dir = File.dirname(source_map_path)
|
135
|
+
|
136
|
+
if out_file
|
137
|
+
map_data['file'] = Util.relative(source_map_dir, out_file)
|
138
|
+
elsif file
|
139
|
+
ext = File.extname(file)
|
140
|
+
map_data['file'] = "#{file[0..(ext.empty? ? -1 : -ext.length - 1)]}.css"
|
141
|
+
else
|
142
|
+
map_data['file'] = 'stdin.css'
|
143
|
+
end
|
144
|
+
|
145
|
+
map_data['sources'].map! do |source|
|
146
|
+
if source.start_with? Util::FILE_PROTOCOL
|
147
|
+
Util.relative(source_map_dir, Util.path(source))
|
148
|
+
else
|
149
|
+
source
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
[-JSON.generate(map_data), source_map_path]
|
154
|
+
end
|
155
|
+
|
156
|
+
def post_process_css(css:,
|
157
|
+
indent_type:,
|
158
|
+
indent_width:,
|
159
|
+
linefeed:,
|
160
|
+
map:,
|
161
|
+
omit_source_map_url:,
|
162
|
+
out_file:,
|
163
|
+
source_map:,
|
164
|
+
source_map_embed:)
|
165
|
+
css = +css
|
166
|
+
if indent_width != 2 || indent_type.to_sym != :space
|
167
|
+
indent = indent_type * indent_width
|
168
|
+
css.gsub!(/^ +/) do |space|
|
169
|
+
indent * (space.length / 2)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
css.gsub!("\n", linefeed) if linefeed != "\n"
|
173
|
+
|
174
|
+
unless map.nil? || omit_source_map_url == true
|
175
|
+
url = if source_map_embed
|
176
|
+
"data:application/json;base64,#{Base64.strict_encode64(map)}"
|
177
|
+
elsif out_file
|
178
|
+
Util.relative(File.dirname(out_file), source_map)
|
179
|
+
else
|
180
|
+
source_map
|
181
|
+
end
|
182
|
+
css += "#{linefeed}/*# sourceMappingURL=#{url} */"
|
183
|
+
end
|
184
|
+
|
185
|
+
-css
|
186
|
+
end
|
187
|
+
|
188
|
+
def parse_indent_type(indent_type)
|
189
|
+
case indent_type.to_sym
|
190
|
+
when :space
|
191
|
+
' '
|
192
|
+
when :tab
|
193
|
+
"\t"
|
194
|
+
else
|
195
|
+
raise ArgumentError, 'indent_type must be one of :space, :tab'
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def parse_indent_width(indent_width)
|
200
|
+
raise ArgumentError, 'indent_width must be an integer' unless indent_width.is_a? Integer
|
201
|
+
raise RangeError, 'indent_width must be in between 0 and 10 (inclusive)' unless indent_width.between? 0, 10
|
202
|
+
|
203
|
+
indent_width
|
204
|
+
end
|
205
|
+
|
206
|
+
def parse_linefeed(linefeed)
|
207
|
+
case linefeed.to_sym
|
208
|
+
when :lf
|
209
|
+
"\n"
|
210
|
+
when :lfcr
|
211
|
+
"\n\r"
|
212
|
+
when :cr
|
213
|
+
"\r"
|
214
|
+
when :crlf
|
215
|
+
"\r\n"
|
216
|
+
else
|
217
|
+
raise ArgumentError, 'linefeed must be one of :lf, :lfcr, :cr, :crlf'
|
218
|
+
end
|
227
219
|
end
|
228
220
|
|
229
221
|
def next_id
|