sass 3.4.20 → 3.4.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -13
  2. data/Rakefile +3 -1
  3. data/VERSION +1 -1
  4. data/VERSION_DATE +1 -1
  5. data/lib/sass/cache_stores/filesystem.rb +1 -1
  6. data/lib/sass/cache_stores/memory.rb +4 -5
  7. data/lib/sass/engine.rb +4 -10
  8. data/lib/sass/error.rb +4 -4
  9. data/lib/sass/exec/sass_convert.rb +6 -4
  10. data/lib/sass/exec/sass_scss.rb +5 -2
  11. data/lib/sass/plugin.rb +2 -1
  12. data/lib/sass/plugin/compiler.rb +14 -11
  13. data/lib/sass/plugin/configuration.rb +1 -1
  14. data/lib/sass/plugin/merb.rb +1 -1
  15. data/lib/sass/script/css_parser.rb +2 -3
  16. data/lib/sass/script/functions.rb +20 -33
  17. data/lib/sass/script/lexer.rb +7 -8
  18. data/lib/sass/script/parser.rb +1 -1
  19. data/lib/sass/script/tree/node.rb +1 -1
  20. data/lib/sass/script/tree/operation.rb +1 -1
  21. data/lib/sass/script/tree/variable.rb +1 -1
  22. data/lib/sass/script/value/base.rb +6 -6
  23. data/lib/sass/script/value/color.rb +2 -2
  24. data/lib/sass/script/value/helpers.rb +7 -7
  25. data/lib/sass/script/value/number.rb +9 -2
  26. data/lib/sass/scss/parser.rb +34 -33
  27. data/lib/sass/scss/rx.rb +2 -3
  28. data/lib/sass/selector.rb +7 -10
  29. data/lib/sass/selector/abstract_sequence.rb +3 -1
  30. data/lib/sass/selector/comma_sequence.rb +4 -2
  31. data/lib/sass/selector/pseudo.rb +2 -2
  32. data/lib/sass/selector/sequence.rb +2 -2
  33. data/lib/sass/selector/simple.rb +3 -1
  34. data/lib/sass/selector/simple_sequence.rb +4 -4
  35. data/lib/sass/tree/function_node.rb +2 -3
  36. data/lib/sass/tree/prop_node.rb +4 -5
  37. data/lib/sass/tree/rule_node.rb +1 -1
  38. data/lib/sass/tree/visitors/check_nesting.rb +16 -22
  39. data/lib/sass/tree/visitors/convert.rb +2 -2
  40. data/lib/sass/tree/visitors/extend.rb +15 -13
  41. data/lib/sass/tree/visitors/perform.rb +1 -1
  42. data/lib/sass/tree/visitors/set_options.rb +1 -1
  43. data/lib/sass/tree/visitors/to_css.rb +18 -15
  44. data/lib/sass/util.rb +7 -8
  45. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  46. data/test/sass/engine_test.rb +45 -4
  47. data/test/sass/script_test.rb +31 -0
  48. metadata +99 -98
@@ -90,7 +90,7 @@ module Sass::Script::Tree
90
90
  # Converts underscores to dashes if the :dasherize option is set.
91
91
  def dasherize(s, opts)
92
92
  if opts[:dasherize]
93
- s.gsub(/_/, '-')
93
+ s.tr('_', '-')
94
94
  else
95
95
  s
96
96
  end
@@ -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}:
@@ -14,7 +14,7 @@ module Sass::Script::Tree
14
14
  # @param name [String] See \{#name}
15
15
  def initialize(name)
16
16
  @name = name
17
- @underscored_name = name.gsub(/-/, "_")
17
+ @underscored_name = name.tr("-", "_")
18
18
  super()
19
19
  end
20
20
 
@@ -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("#{to_s}=#{other.to_s}")
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("#{to_s}-#{other.to_s}")
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("#{to_s}/#{other.to_s}")
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("+#{to_s}")
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("-#{to_s}")
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("/#{to_s}")
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 {|k, v| v.nil?}
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 {|k, v| v.nil?}
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.gsub('_', '-')}: #{err}" if name
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.gsub('_', '-')}: #{err}" if name
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.gsub('_', '-')}: #{err}" if name
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
- if literal.is_a?(Sass::Script::Value::String)
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.gsub('_', '-')}: #{err}" if name
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.to_i
413
+ num.round
407
414
  else
408
415
  ((num * precision_factor).round / precision_factor).to_f
409
416
  end
@@ -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.gsub("\r", ""))
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(Sass::Tree::CssImportNode.new(
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(node(
650
- Sass::Tree::RuleNode.new(rules, range(start_pos)), start_pos), :ruleset)
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(node(
726
- Sass::Tree::RuleNode.new(merge(selector), range(start_pos)), start_pos), :ruleset)
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
- newline_count = res.count(NEWLINE)
1204
- if newline_count > 0
1205
- @line += newline_count
1206
- @offset = res[res.rindex(NEWLINE)..-1].size
1207
- else
1208
- @offset += res.size
1209
- end
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
- @expected = nil
1212
- if !@strs.empty? && rx != COMMENT && rx != SINGLE_LINE_COMMENT
1213
- @strs.each {|s| s << res}
1214
- end
1215
- res
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`.
@@ -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}|-(?!\d))*|%/
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})?/
@@ -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
@@ -71,8 +71,10 @@ module Sass
71
71
 
72
72
  # Returns the selector string.
73
73
  #
74
+ # @param opts [Hash] rendering options.
75
+ # @option opts [Symbol] :style The css rendering style.
74
76
  # @return [String]
75
- def to_s
77
+ def to_s(opts = {})
76
78
  Sass::Util.abstract(self)
77
79
  end
78
80
 
@@ -159,8 +159,10 @@ module Sass
159
159
  end
160
160
 
161
161
  # @see AbstractSequence#to_s
162
- def to_s
163
- @members.join(", ").gsub(", \n", ",\n")
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
@@ -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.