sass 3.4.20 → 3.4.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass/cache_stores/filesystem.rb +1 -1
- data/lib/sass/cache_stores/memory.rb +4 -5
- data/lib/sass/engine.rb +4 -10
- data/lib/sass/error.rb +4 -4
- data/lib/sass/exec/sass_convert.rb +6 -4
- data/lib/sass/exec/sass_scss.rb +5 -2
- data/lib/sass/plugin.rb +2 -1
- data/lib/sass/plugin/compiler.rb +14 -11
- data/lib/sass/plugin/configuration.rb +1 -1
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/script/css_parser.rb +2 -3
- data/lib/sass/script/functions.rb +20 -33
- data/lib/sass/script/lexer.rb +7 -8
- data/lib/sass/script/parser.rb +1 -1
- data/lib/sass/script/tree/node.rb +1 -1
- data/lib/sass/script/tree/operation.rb +1 -1
- data/lib/sass/script/tree/variable.rb +1 -1
- data/lib/sass/script/value/base.rb +6 -6
- data/lib/sass/script/value/color.rb +2 -2
- data/lib/sass/script/value/helpers.rb +7 -7
- data/lib/sass/script/value/number.rb +9 -2
- data/lib/sass/scss/parser.rb +34 -33
- data/lib/sass/scss/rx.rb +2 -3
- data/lib/sass/selector.rb +7 -10
- data/lib/sass/selector/abstract_sequence.rb +3 -1
- data/lib/sass/selector/comma_sequence.rb +4 -2
- data/lib/sass/selector/pseudo.rb +2 -2
- data/lib/sass/selector/sequence.rb +2 -2
- data/lib/sass/selector/simple.rb +3 -1
- data/lib/sass/selector/simple_sequence.rb +4 -4
- data/lib/sass/tree/function_node.rb +2 -3
- data/lib/sass/tree/prop_node.rb +4 -5
- data/lib/sass/tree/rule_node.rb +1 -1
- data/lib/sass/tree/visitors/check_nesting.rb +16 -22
- data/lib/sass/tree/visitors/convert.rb +2 -2
- data/lib/sass/tree/visitors/extend.rb +15 -13
- data/lib/sass/tree/visitors/perform.rb +1 -1
- data/lib/sass/tree/visitors/set_options.rb +1 -1
- data/lib/sass/tree/visitors/to_css.rb +18 -15
- data/lib/sass/util.rb +7 -8
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/test/sass/engine_test.rb +45 -4
- data/test/sass/script_test.rb +31 -0
- metadata +99 -98
@@ -93,7 +93,7 @@ module Sass::Script::Tree
|
|
93
93
|
Sass::Script::Value::Bool::FALSE
|
94
94
|
end)
|
95
95
|
|
96
|
-
operation = "#{value1} #{@operator == :eq ? '==' : '!='} #{value2}"
|
96
|
+
operation = "#{value1.to_sass} #{@operator == :eq ? '==' : '!='} #{value2.to_sass}"
|
97
97
|
future_value = @operator == :neq
|
98
98
|
Sass::Util.sass_warn <<WARNING
|
99
99
|
DEPRECATION WARNING on line #{line}#{" of #{filename}" if filename}:
|
@@ -87,7 +87,7 @@ MSG
|
|
87
87
|
# @return [Script::Value::String] A string containing both values
|
88
88
|
# separated by `"="`
|
89
89
|
def single_eq(other)
|
90
|
-
Sass::Script::Value::String.new("#{
|
90
|
+
Sass::Script::Value::String.new("#{self}=#{other}")
|
91
91
|
end
|
92
92
|
|
93
93
|
# The SassScript `+` operation.
|
@@ -106,7 +106,7 @@ MSG
|
|
106
106
|
# @return [Script::Value::String] A string containing both values
|
107
107
|
# separated by `"-"`
|
108
108
|
def minus(other)
|
109
|
-
Sass::Script::Value::String.new("#{
|
109
|
+
Sass::Script::Value::String.new("#{self}-#{other}")
|
110
110
|
end
|
111
111
|
|
112
112
|
# The SassScript `/` operation.
|
@@ -115,7 +115,7 @@ MSG
|
|
115
115
|
# @return [Script::Value::String] A string containing both values
|
116
116
|
# separated by `"/"`
|
117
117
|
def div(other)
|
118
|
-
Sass::Script::Value::String.new("#{
|
118
|
+
Sass::Script::Value::String.new("#{self}/#{other}")
|
119
119
|
end
|
120
120
|
|
121
121
|
# The SassScript unary `+` operation (e.g. `+$a`).
|
@@ -124,7 +124,7 @@ MSG
|
|
124
124
|
# @return [Script::Value::String] A string containing the value
|
125
125
|
# preceded by `"+"`
|
126
126
|
def unary_plus
|
127
|
-
Sass::Script::Value::String.new("+#{
|
127
|
+
Sass::Script::Value::String.new("+#{self}")
|
128
128
|
end
|
129
129
|
|
130
130
|
# The SassScript unary `-` operation (e.g. `-$a`).
|
@@ -133,7 +133,7 @@ MSG
|
|
133
133
|
# @return [Script::Value::String] A string containing the value
|
134
134
|
# preceded by `"-"`
|
135
135
|
def unary_minus
|
136
|
-
Sass::Script::Value::String.new("-#{
|
136
|
+
Sass::Script::Value::String.new("-#{self}")
|
137
137
|
end
|
138
138
|
|
139
139
|
# The SassScript unary `/` operation (e.g. `/$a`).
|
@@ -142,7 +142,7 @@ MSG
|
|
142
142
|
# @return [Script::Value::String] A string containing the value
|
143
143
|
# preceded by `"/"`
|
144
144
|
def unary_div
|
145
|
-
Sass::Script::Value::String.new("/#{
|
145
|
+
Sass::Script::Value::String.new("/#{self}")
|
146
146
|
end
|
147
147
|
|
148
148
|
# Returns the hash code of this value. Two objects' hash codes should be
|
@@ -237,7 +237,7 @@ module Sass::Script::Value
|
|
237
237
|
@attrs[:alpha] = attrs[3] ? attrs[3].to_f : 1
|
238
238
|
@representation = representation
|
239
239
|
else
|
240
|
-
attrs = attrs.reject {|
|
240
|
+
attrs = attrs.reject {|_k, v| v.nil?}
|
241
241
|
hsl = [:hue, :saturation, :lightness] & attrs.keys
|
242
242
|
rgb = [:red, :green, :blue] & attrs.keys
|
243
243
|
if !allow_both_rgb_and_hsl && !hsl.empty? && !rgb.empty?
|
@@ -421,7 +421,7 @@ module Sass::Script::Value
|
|
421
421
|
# @return [Color] The new Color object
|
422
422
|
# @raise [ArgumentError] if both RGB and HSL keys are specified
|
423
423
|
def with(attrs)
|
424
|
-
attrs = attrs.reject {|
|
424
|
+
attrs = attrs.reject {|_k, v| v.nil?}
|
425
425
|
hsl = !([:hue, :saturation, :lightness] & attrs.keys).empty?
|
426
426
|
rgb = !([:red, :green, :blue] & attrs.keys).empty?
|
427
427
|
if hsl && rgb
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Sass::Script::Value
|
2
2
|
# Provides helper functions for creating sass values from within ruby methods.
|
3
3
|
# @since `3.3.0`
|
4
|
+
# @comment
|
5
|
+
# rubocop:disable ModuleLength
|
4
6
|
module Helpers
|
5
7
|
# Construct a Sass Boolean.
|
6
8
|
#
|
@@ -139,7 +141,7 @@ module Sass::Script::Value
|
|
139
141
|
Sass::SCSS::StaticParser.new(str, nil, nil, 1, 1, allow_parent_ref).parse_selector
|
140
142
|
rescue Sass::SyntaxError => e
|
141
143
|
err = "#{value.inspect} is not a valid selector: #{e}"
|
142
|
-
err = "$#{name.to_s.
|
144
|
+
err = "$#{name.to_s.tr('_', '-')}: #{err}" if name
|
143
145
|
raise ArgumentError.new(err)
|
144
146
|
end
|
145
147
|
end
|
@@ -163,7 +165,7 @@ module Sass::Script::Value
|
|
163
165
|
return seq if selector.members.length == 1
|
164
166
|
|
165
167
|
err = "#{value.inspect} is not a complex selector"
|
166
|
-
err = "$#{name.to_s.
|
168
|
+
err = "$#{name.to_s.tr('_', '-')}: #{err}" if name
|
167
169
|
raise ArgumentError.new(err)
|
168
170
|
end
|
169
171
|
|
@@ -190,7 +192,7 @@ module Sass::Script::Value
|
|
190
192
|
end
|
191
193
|
|
192
194
|
err = "#{value.inspect} is not a compound selector"
|
193
|
-
err = "$#{name.to_s.
|
195
|
+
err = "$#{name.to_s.tr('_', '-')}: #{err}" if name
|
194
196
|
raise ArgumentError.new(err)
|
195
197
|
end
|
196
198
|
|
@@ -199,9 +201,7 @@ module Sass::Script::Value
|
|
199
201
|
# @param literal [Sass::Script::Value::Base] The value to check
|
200
202
|
# @return boolean
|
201
203
|
def calc?(literal)
|
202
|
-
|
203
|
-
literal.value =~ /calc\(/
|
204
|
-
end
|
204
|
+
literal.is_a?(Sass::Script::Value::String) && literal.value =~ /calc\(/
|
205
205
|
end
|
206
206
|
|
207
207
|
private
|
@@ -215,7 +215,7 @@ module Sass::Script::Value
|
|
215
215
|
|
216
216
|
err = "#{value.inspect} is not a valid selector: it must be a string,\n" +
|
217
217
|
"a list of strings, or a list of lists of strings"
|
218
|
-
err = "$#{name.to_s.
|
218
|
+
err = "$#{name.to_s.tr('_', '-')}: #{err}" if name
|
219
219
|
raise ArgumentError.new(err)
|
220
220
|
end
|
221
221
|
|
@@ -60,7 +60,7 @@ module Sass::Script::Value
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# Used so we don't allocate two new arrays for each new number.
|
63
|
-
NO_UNITS
|
63
|
+
NO_UNITS = []
|
64
64
|
|
65
65
|
# @param value [Numeric] The value of the number
|
66
66
|
# @param numerator_units [::String, Array<::String>] See \{#numerator\_units}
|
@@ -289,9 +289,16 @@ module Sass::Script::Value
|
|
289
289
|
# and confusing.
|
290
290
|
str = ("%0.#{self.class.precision}f" % value).gsub(/0*$/, '') if str.include?('e')
|
291
291
|
|
292
|
+
# Sometimes numeric formatting will result in a decimal number with a trailing zero (x.0)
|
293
|
+
if str =~ /(.*)\.0$/
|
294
|
+
str = $1
|
295
|
+
end
|
296
|
+
|
297
|
+
# We omit a leading zero before the decimal point in compressed mode.
|
292
298
|
if @options && options[:style] == :compressed
|
293
299
|
str.sub!(/^(-)?0\./, '\1.')
|
294
300
|
end
|
301
|
+
|
295
302
|
unitless? ? str : "#{str}#{unit_str}"
|
296
303
|
end
|
297
304
|
alias_method :to_sass, :inspect
|
@@ -403,7 +410,7 @@ module Sass::Script::Value
|
|
403
410
|
if num.is_a?(Float) && (num.infinite? || num.nan?)
|
404
411
|
num
|
405
412
|
elsif basically_equal?(num % 1, 0.0)
|
406
|
-
num.
|
413
|
+
num.round
|
407
414
|
else
|
408
415
|
((num * precision_factor).round / precision_factor).to_f
|
409
416
|
end
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -21,10 +21,7 @@ module Sass
|
|
21
21
|
# @param offset [Fixnum] The 1-based character (not byte) offset in the line on
|
22
22
|
# which the source string starts. Used for error reporting and sourcemap
|
23
23
|
# building.
|
24
|
-
# @comment
|
25
|
-
# rubocop:disable ParameterLists
|
26
24
|
def initialize(str, filename, importer, line = 1, offset = 1)
|
27
|
-
# rubocop:enable ParameterLists
|
28
25
|
@template = str
|
29
26
|
@filename = filename
|
30
27
|
@importer = importer
|
@@ -117,7 +114,7 @@ module Sass
|
|
117
114
|
if @template.is_a?(StringScanner)
|
118
115
|
@template
|
119
116
|
else
|
120
|
-
Sass::Util::MultibyteStringScanner.new(@template.
|
117
|
+
Sass::Util::MultibyteStringScanner.new(@template.tr("\r", ""))
|
121
118
|
end
|
122
119
|
end
|
123
120
|
|
@@ -396,7 +393,8 @@ module Sass
|
|
396
393
|
ss
|
397
394
|
media = media_query_list
|
398
395
|
if str =~ %r{^(https?:)?//} || media || supports || use_css_import?
|
399
|
-
return node(
|
396
|
+
return node(
|
397
|
+
Sass::Tree::CssImportNode.new(
|
400
398
|
Sass::Script::Value::String.quote(str), media.to_a, supports), start_pos)
|
401
399
|
end
|
402
400
|
|
@@ -646,8 +644,9 @@ module Sass
|
|
646
644
|
def ruleset
|
647
645
|
start_pos = source_position
|
648
646
|
return unless (rules = almost_any_value)
|
649
|
-
block(
|
650
|
-
|
647
|
+
block(
|
648
|
+
node(
|
649
|
+
Sass::Tree::RuleNode.new(rules, range(start_pos)), start_pos), :ruleset)
|
651
650
|
end
|
652
651
|
|
653
652
|
def block(node, context)
|
@@ -722,8 +721,9 @@ module Sass
|
|
722
721
|
selector << additional_selector
|
723
722
|
end
|
724
723
|
|
725
|
-
block(
|
726
|
-
|
724
|
+
block(
|
725
|
+
node(
|
726
|
+
Sass::Tree::RuleNode.new(merge(selector), range(start_pos)), start_pos), :ruleset)
|
727
727
|
end
|
728
728
|
|
729
729
|
# Tries to parse a declaration, and returns the value parsed so far if it
|
@@ -1187,33 +1187,34 @@ module Sass
|
|
1187
1187
|
|
1188
1188
|
def tok(rx, last_group_lookahead = false)
|
1189
1189
|
res = @scanner.scan(rx)
|
1190
|
-
if res
|
1191
|
-
# This fixes https://github.com/nex3/sass/issues/104, which affects
|
1192
|
-
# Ruby 1.8.7 and REE. This fix is to replace the ?= zero-width
|
1193
|
-
# positive lookahead operator in the Regexp (which matches without
|
1194
|
-
# consuming the matched group), with a match that does consume the
|
1195
|
-
# group, but then rewinds the scanner and removes the group from the
|
1196
|
-
# end of the matched string. This fix makes the assumption that the
|
1197
|
-
# matched group will always occur at the end of the match.
|
1198
|
-
if last_group_lookahead && @scanner[-1]
|
1199
|
-
@scanner.pos -= @scanner[-1].length
|
1200
|
-
res.slice!(-@scanner[-1].length..-1)
|
1201
|
-
end
|
1202
1190
|
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1191
|
+
return unless res
|
1192
|
+
|
1193
|
+
# This fixes https://github.com/nex3/sass/issues/104, which affects
|
1194
|
+
# Ruby 1.8.7 and REE. This fix is to replace the ?= zero-width
|
1195
|
+
# positive lookahead operator in the Regexp (which matches without
|
1196
|
+
# consuming the matched group), with a match that does consume the
|
1197
|
+
# group, but then rewinds the scanner and removes the group from the
|
1198
|
+
# end of the matched string. This fix makes the assumption that the
|
1199
|
+
# matched group will always occur at the end of the match.
|
1200
|
+
if last_group_lookahead && @scanner[-1]
|
1201
|
+
@scanner.pos -= @scanner[-1].length
|
1202
|
+
res.slice!(-@scanner[-1].length..-1)
|
1203
|
+
end
|
1210
1204
|
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1205
|
+
newline_count = res.count(NEWLINE)
|
1206
|
+
if newline_count > 0
|
1207
|
+
@line += newline_count
|
1208
|
+
@offset = res[res.rindex(NEWLINE)..-1].size
|
1209
|
+
else
|
1210
|
+
@offset += res.size
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
@expected = nil
|
1214
|
+
if !@strs.empty? && rx != COMMENT && rx != SINGLE_LINE_COMMENT
|
1215
|
+
@strs.each {|s| s << res}
|
1216
1216
|
end
|
1217
|
+
res
|
1217
1218
|
end
|
1218
1219
|
|
1219
1220
|
# Remove a vendor prefix from `str`.
|
data/lib/sass/scss/rx.rb
CHANGED
@@ -32,7 +32,7 @@ module Sass
|
|
32
32
|
# @return [String] The escaped character
|
33
33
|
# @private
|
34
34
|
def self.escape_char(c)
|
35
|
-
return "\\%06x" % Sass::Util.ord(c) unless c =~ /[ -\/:-~]/
|
35
|
+
return "\\%06x" % (Sass::Util.ord(c)) unless c =~ /[ -\/:-~]/
|
36
36
|
"\\#{c}"
|
37
37
|
end
|
38
38
|
|
@@ -66,7 +66,6 @@ module Sass
|
|
66
66
|
|
67
67
|
IDENT = /-*#{NMSTART}#{NMCHAR}*/
|
68
68
|
NAME = /#{NMCHAR}+/
|
69
|
-
NUM = //
|
70
69
|
STRING = /#{STRING1}|#{STRING2}/
|
71
70
|
URLCHAR = /[#%&*-~]|#{NONASCII}|#{ESCAPE}/
|
72
71
|
URL = /(#{URLCHAR}*)/
|
@@ -99,7 +98,7 @@ module Sass
|
|
99
98
|
# A unit is like an IDENT, but disallows a hyphen followed by a digit.
|
100
99
|
# This allows "1px-2px" to be interpreted as subtraction rather than "1"
|
101
100
|
# with the unit "px-2px". It also allows "%".
|
102
|
-
UNIT = /-?#{NMSTART}(?:[a-zA-Z0-9_]|#{NONASCII}|#{ESCAPE}|-(
|
101
|
+
UNIT = /-?#{NMSTART}(?:[a-zA-Z0-9_]|#{NONASCII}|#{ESCAPE}|-(?!\.?\d))*|%/
|
103
102
|
|
104
103
|
UNITLESS_NUMBER = /(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?\d+)?/
|
105
104
|
NUMBER = /#{UNITLESS_NUMBER}(?:#{UNIT})?/
|
data/lib/sass/selector.rb
CHANGED
@@ -39,7 +39,7 @@ module Sass
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# @see Selector#to_s
|
42
|
-
def to_s
|
42
|
+
def to_s(opts = {})
|
43
43
|
"&" + (@suffix || '')
|
44
44
|
end
|
45
45
|
|
@@ -65,7 +65,7 @@ module Sass
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# @see Selector#to_s
|
68
|
-
def to_s
|
68
|
+
def to_s(opts = {})
|
69
69
|
"." + @name
|
70
70
|
end
|
71
71
|
|
@@ -88,7 +88,7 @@ module Sass
|
|
88
88
|
end
|
89
89
|
|
90
90
|
# @see Selector#to_s
|
91
|
-
def to_s
|
91
|
+
def to_s(opts = {})
|
92
92
|
"#" + @name
|
93
93
|
end
|
94
94
|
|
@@ -123,7 +123,7 @@ module Sass
|
|
123
123
|
end
|
124
124
|
|
125
125
|
# @see Selector#to_s
|
126
|
-
def to_s
|
126
|
+
def to_s(opts = {})
|
127
127
|
"%" + @name
|
128
128
|
end
|
129
129
|
|
@@ -147,7 +147,7 @@ module Sass
|
|
147
147
|
end
|
148
148
|
|
149
149
|
# @see Selector#to_s
|
150
|
-
def to_s
|
150
|
+
def to_s(opts = {})
|
151
151
|
@namespace ? "#{@namespace}|*" : "*"
|
152
152
|
end
|
153
153
|
|
@@ -219,7 +219,7 @@ module Sass
|
|
219
219
|
end
|
220
220
|
|
221
221
|
# @see Selector#to_s
|
222
|
-
def to_s
|
222
|
+
def to_s(opts = {})
|
223
223
|
@namespace ? "#{@namespace}|#{@name}" : @name
|
224
224
|
end
|
225
225
|
|
@@ -296,10 +296,7 @@ module Sass
|
|
296
296
|
# @param operator [String] The matching operator, e.g. `"="` or `"^="`
|
297
297
|
# @param value [String] See \{#value}
|
298
298
|
# @param flags [String] See \{#flags}
|
299
|
-
# @comment
|
300
|
-
# rubocop:disable ParameterLists
|
301
299
|
def initialize(name, namespace, operator, value, flags)
|
302
|
-
# rubocop:enable ParameterLists
|
303
300
|
@name = name
|
304
301
|
@namespace = namespace
|
305
302
|
@operator = operator
|
@@ -308,7 +305,7 @@ module Sass
|
|
308
305
|
end
|
309
306
|
|
310
307
|
# @see Selector#to_s
|
311
|
-
def to_s
|
308
|
+
def to_s(opts = {})
|
312
309
|
res = "["
|
313
310
|
res << @namespace << "|" if @namespace
|
314
311
|
res << @name
|
@@ -159,8 +159,10 @@ module Sass
|
|
159
159
|
end
|
160
160
|
|
161
161
|
# @see AbstractSequence#to_s
|
162
|
-
def to_s
|
163
|
-
@members.
|
162
|
+
def to_s(opts = {})
|
163
|
+
@members.map {|m| m.to_s(opts)}.
|
164
|
+
join(opts[:style] == :compressed ? "," : ", ").
|
165
|
+
gsub(", \n", ",\n")
|
164
166
|
end
|
165
167
|
|
166
168
|
private
|
data/lib/sass/selector/pseudo.rb
CHANGED
@@ -113,13 +113,13 @@ module Sass
|
|
113
113
|
end
|
114
114
|
|
115
115
|
# @see Selector#to_s
|
116
|
-
def to_s
|
116
|
+
def to_s(opts = {})
|
117
117
|
res = (syntactic_type == :class ? ":" : "::") + @name
|
118
118
|
if @arg || @selector
|
119
119
|
res << "("
|
120
120
|
res << @arg.strip if @arg
|
121
121
|
res << " " if @arg && @selector
|
122
|
-
res << @selector.to_s if @selector
|
122
|
+
res << @selector.to_s(opts) if @selector
|
123
123
|
res << ")"
|
124
124
|
end
|
125
125
|
res
|
@@ -157,8 +157,8 @@ module Sass
|
|
157
157
|
end
|
158
158
|
|
159
159
|
# @see AbstractSequence#to_s
|
160
|
-
def to_s
|
161
|
-
@members.join(" ").gsub(/ ?\n ?/, "\n")
|
160
|
+
def to_s(opts = {})
|
161
|
+
@members.map {|m| m.is_a?(String) ? m : m.to_s(opts)}.join(" ").gsub(/ ?\n ?/, "\n")
|
162
162
|
end
|
163
163
|
|
164
164
|
# Returns a string representation of the sequence.
|