sass 3.4.20 → 3.4.21

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.
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.