sass 3.3.0.alpha.149 → 3.3.0.alpha.162

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 (71) hide show
  1. data/REVISION +1 -1
  2. data/VERSION +1 -1
  3. data/VERSION_DATE +1 -1
  4. data/lib/sass/css.rb +1 -1
  5. data/lib/sass/engine.rb +4 -4
  6. data/lib/sass/environment.rb +1 -1
  7. data/lib/sass/exec.rb +1 -1
  8. data/lib/sass/media.rb +15 -15
  9. data/lib/sass/script.rb +32 -7
  10. data/lib/sass/script/css_lexer.rb +2 -2
  11. data/lib/sass/script/css_parser.rb +1 -1
  12. data/lib/sass/script/functions.rb +246 -232
  13. data/lib/sass/script/lexer.rb +24 -32
  14. data/lib/sass/script/parser.rb +84 -65
  15. data/lib/sass/script/tree.rb +14 -0
  16. data/lib/sass/script/tree/funcall.rb +242 -0
  17. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +30 -13
  18. data/lib/sass/script/tree/list_literal.rb +65 -0
  19. data/lib/sass/script/tree/literal.rb +46 -0
  20. data/lib/sass/script/{node.rb → tree/node.rb} +10 -10
  21. data/lib/sass/script/{operation.rb → tree/operation.rb} +16 -27
  22. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +4 -4
  23. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +7 -8
  24. data/lib/sass/script/tree/variable.rb +56 -0
  25. data/lib/sass/script/value.rb +10 -0
  26. data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +5 -20
  27. data/lib/sass/script/value/base.rb +222 -0
  28. data/lib/sass/script/{bool.rb → value/bool.rb} +2 -2
  29. data/lib/sass/script/{color.rb → value/color.rb} +22 -20
  30. data/lib/sass/script/{list.rb → value/list.rb} +15 -28
  31. data/lib/sass/script/{null.rb → value/null.rb} +3 -3
  32. data/lib/sass/script/{number.rb → value/number.rb} +19 -19
  33. data/lib/sass/script/{string.rb → value/string.rb} +7 -7
  34. data/lib/sass/scss/parser.rb +14 -4
  35. data/lib/sass/selector.rb +26 -26
  36. data/lib/sass/selector/abstract_sequence.rb +1 -1
  37. data/lib/sass/selector/simple.rb +6 -7
  38. data/lib/sass/source/position.rb +13 -0
  39. data/lib/sass/supports.rb +4 -4
  40. data/lib/sass/tree/comment_node.rb +3 -3
  41. data/lib/sass/tree/css_import_node.rb +7 -7
  42. data/lib/sass/tree/debug_node.rb +2 -2
  43. data/lib/sass/tree/directive_node.rb +2 -2
  44. data/lib/sass/tree/each_node.rb +2 -2
  45. data/lib/sass/tree/extend_node.rb +4 -4
  46. data/lib/sass/tree/for_node.rb +4 -4
  47. data/lib/sass/tree/function_node.rb +4 -4
  48. data/lib/sass/tree/media_node.rb +3 -3
  49. data/lib/sass/tree/mixin_def_node.rb +4 -4
  50. data/lib/sass/tree/mixin_node.rb +6 -6
  51. data/lib/sass/tree/prop_node.rb +23 -15
  52. data/lib/sass/tree/return_node.rb +2 -2
  53. data/lib/sass/tree/rule_node.rb +3 -3
  54. data/lib/sass/tree/variable_node.rb +2 -2
  55. data/lib/sass/tree/visitors/convert.rb +2 -2
  56. data/lib/sass/tree/visitors/deep_copy.rb +5 -5
  57. data/lib/sass/tree/visitors/perform.rb +7 -7
  58. data/lib/sass/tree/visitors/set_options.rb +6 -6
  59. data/lib/sass/tree/visitors/to_css.rb +1 -1
  60. data/lib/sass/tree/warn_node.rb +2 -2
  61. data/lib/sass/tree/while_node.rb +2 -2
  62. data/lib/sass/util.rb +2 -2
  63. data/test/sass/engine_test.rb +6 -6
  64. data/test/sass/functions_test.rb +20 -20
  65. data/test/sass/plugin_test.rb +2 -2
  66. data/test/sass/script_test.rb +38 -29
  67. data/test/test_helper.rb +1 -1
  68. metadata +23 -19
  69. data/lib/sass/script/funcall.rb +0 -238
  70. data/lib/sass/script/literal.rb +0 -221
  71. data/lib/sass/script/variable.rb +0 -58
@@ -1,16 +1,4 @@
1
- require 'set'
2
- require 'sass/script/literal'
3
- require 'sass/script/string'
4
- require 'sass/script/number'
5
- require 'sass/script/color'
6
- require 'sass/script/bool'
7
- require 'sass/script/null'
8
- require 'sass/script/functions'
9
- require 'sass/script/unary_operation'
10
- require 'sass/script/interpolation'
11
- require 'sass/script/string_interpolation'
12
-
13
- module Sass::Script
1
+ module Sass::Script::Tree
14
2
  # A SassScript parse node representing a binary operation,
15
3
  # such as `$a + $b` or `"foo" + 1`.
16
4
  class Operation < Node
@@ -18,12 +6,12 @@ module Sass::Script
18
6
  attr_reader :operand2
19
7
  attr_reader :operator
20
8
 
21
- # @param operand1 [Script::Node] The parse-tree node
9
+ # @param operand1 [Sass::Script::Tree::Node] The parse-tree node
22
10
  # for the right-hand side of the operator
23
- # @param operand2 [Script::Node] The parse-tree node
11
+ # @param operand2 [Sass::Script::Tree::Node] The parse-tree node
24
12
  # for the left-hand side of the operator
25
13
  # @param operator [Symbol] The operator to perform.
26
- # This should be one of the binary operator names in {Lexer::OPERATORS}
14
+ # This should be one of the binary operator names in {Sass::Script::Lexer::OPERATORS}
27
15
  def initialize(operand1, operand2, operator)
28
16
  @operand1 = operand1
29
17
  @operand2 = operand2
@@ -44,7 +32,7 @@ module Sass::Script
44
32
  case @operator
45
33
  when :comma; ", "
46
34
  when :space; " "
47
- else; " #{Lexer::OPERATORS_REVERSE[@operator]} "
35
+ else; " #{Sass::Script::Lexer::OPERATORS_REVERSE[@operator]} "
48
36
  end
49
37
  "#{o1}#{sep}#{o2}"
50
38
  end
@@ -70,36 +58,37 @@ module Sass::Script
70
58
  # Evaluates the operation.
71
59
  #
72
60
  # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
73
- # @return [Literal] The SassScript object that is the value of the operation
61
+ # @return [Sass::Script::Value] The SassScript object that is the value of the operation
74
62
  # @raise [Sass::SyntaxError] if the operation is undefined for the operands
75
63
  def _perform(environment)
76
- literal1 = @operand1.perform(environment)
64
+ value1 = @operand1.perform(environment)
77
65
 
78
66
  # Special-case :and and :or to support short-circuiting.
79
67
  if @operator == :and
80
- return literal1.to_bool ? @operand2.perform(environment) : literal1
68
+ return value1.to_bool ? @operand2.perform(environment) : value1
81
69
  elsif @operator == :or
82
- return literal1.to_bool ? literal1 : @operand2.perform(environment)
70
+ return value1.to_bool ? value1 : @operand2.perform(environment)
83
71
  end
84
72
 
85
- literal2 = @operand2.perform(environment)
73
+ value2 = @operand2.perform(environment)
86
74
 
87
- if (literal1.is_a?(Null) || literal2.is_a?(Null)) && @operator != :eq && @operator != :neq
88
- raise Sass::SyntaxError.new("Invalid null operation: \"#{literal1.inspect} #{@operator} #{literal2.inspect}\".")
75
+ if (value1.is_a?(Sass::Script::Value::Null) || value2.is_a?(Sass::Script::Value::Null)) &&
76
+ @operator != :eq && @operator != :neq
77
+ raise Sass::SyntaxError.new("Invalid null operation: \"#{value1.inspect} #{@operator} #{value2.inspect}\".")
89
78
  end
90
79
 
91
80
  begin
92
- opts(literal1.send(@operator, literal2))
81
+ opts(value1.send(@operator, value2))
93
82
  rescue NoMethodError => e
94
83
  raise e unless e.name.to_s == @operator.to_s
95
- raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\".")
84
+ raise Sass::SyntaxError.new("Undefined operation: \"#{value1} #{@operator} #{value2}\".")
96
85
  end
97
86
  end
98
87
 
99
88
  private
100
89
 
101
90
  def operand_to_sass(op, side, opts)
102
- return "(#{op.to_sass(opts)})" if op.is_a?(List)
91
+ return "(#{op.to_sass(opts)})" if op.is_a?(Sass::Script::Tree::ListLiteral)
103
92
  return op.to_sass(opts) unless op.is_a?(Operation)
104
93
 
105
94
  pred = Sass::Script::Parser.precedence_of(@operator)
@@ -1,4 +1,4 @@
1
- module Sass::Script
1
+ module Sass::Script::Tree
2
2
  # A SassScript object representing `#{}` interpolation within a string.
3
3
  #
4
4
  # @see Interpolation
@@ -74,15 +74,15 @@ module Sass::Script
74
74
  # Evaluates the interpolation.
75
75
  #
76
76
  # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
77
- # @return [Sass::Script::String] The SassScript string that is the value of the interpolation
77
+ # @return [Sass::Script::Value::String] The SassScript string that is the value of the interpolation
78
78
  def _perform(environment)
79
79
  res = ""
80
80
  before = @before.perform(environment)
81
81
  res << before.value
82
82
  mid = @mid.perform(environment)
83
- res << (mid.is_a?(Sass::Script::String) ? mid.value : mid.to_s)
83
+ res << (mid.is_a?(Sass::Script::Value::String) ? mid.value : mid.to_s)
84
84
  res << @after.perform(environment).value
85
- opts(Sass::Script::String.new(res, before.type))
85
+ opts(Sass::Script::Value::String.new(res, before.type))
86
86
  end
87
87
 
88
88
  private
@@ -1,11 +1,10 @@
1
- module Sass::Script
1
+ module Sass::Script::Tree
2
2
  # A SassScript parse node representing a unary operation,
3
3
  # such as `-$b` or `not true`.
4
4
  #
5
5
  # Currently only `-`, `/`, and `not` are unary operators.
6
6
  class UnaryOperation < Node
7
- # @param operand [Script::Node] The parse-tree node
8
- # for the object of the operator
7
+ # @param operand [Node] The parse-tree node for the object of the operator
9
8
  # @param operator [Symbol] The operator to perform
10
9
  def initialize(operand, operator)
11
10
  @operand = operand
@@ -26,7 +25,7 @@ module Sass::Script
26
25
  (operand =~ Sass::SCSS::RX::IDENT) == 0)
27
26
  operand = "(#{@operand.to_sass(opts)})"
28
27
  end
29
- op = Lexer::OPERATORS_REVERSE[@operator]
28
+ op = Sass::Script::Lexer::OPERATORS_REVERSE[@operator]
30
29
  op + (op =~ /[a-z]/ ? " " : "") + operand
31
30
  end
32
31
 
@@ -50,15 +49,15 @@ module Sass::Script
50
49
  # Evaluates the operation.
51
50
  #
52
51
  # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
53
- # @return [Literal] The SassScript object that is the value of the operation
52
+ # @return [Sass::Script::Value] The SassScript object that is the value of the operation
54
53
  # @raise [Sass::SyntaxError] if the operation is undefined for the operand
55
54
  def _perform(environment)
56
55
  operator = "unary_#{@operator}"
57
- literal = @operand.perform(environment)
58
- literal.send(operator)
56
+ value = @operand.perform(environment)
57
+ value.send(operator)
59
58
  rescue NoMethodError => e
60
59
  raise e unless e.name.to_s == operator.to_s
61
- raise Sass::SyntaxError.new("Undefined unary operation: \"#{@operator} #{literal}\".")
60
+ raise Sass::SyntaxError.new("Undefined unary operation: \"#{@operator} #{value}\".")
62
61
  end
63
62
  end
64
63
  end
@@ -0,0 +1,56 @@
1
+ module Sass::Script::Tree
2
+ # A SassScript parse node representing a variable.
3
+ class Variable < Node
4
+ # The name of the variable.
5
+ #
6
+ # @return [String]
7
+ attr_reader :name
8
+
9
+ # The underscored name of the variable.
10
+ #
11
+ # @return [String]
12
+ attr_reader :underscored_name
13
+
14
+ # @param name [String] See \{#name}
15
+ def initialize(name)
16
+ @name = name
17
+ @underscored_name = name.gsub(/-/,"_")
18
+ super()
19
+ end
20
+
21
+ # @return [String] A string representation of the variable
22
+ def inspect(opts = {})
23
+ "$#{dasherize(name, opts)}"
24
+ end
25
+ alias_method :to_sass, :inspect
26
+
27
+ # Returns an empty array.
28
+ #
29
+ # @return [Array<Node>] empty
30
+ # @see Node#children
31
+ def children
32
+ []
33
+ end
34
+
35
+ # @see Node#deep_copy
36
+ def deep_copy
37
+ dup
38
+ end
39
+
40
+ protected
41
+
42
+ # Evaluates the variable.
43
+ #
44
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
45
+ # @return [Sass::Script::Value] The SassScript object that is the value of the variable
46
+ # @raise [Sass::SyntaxError] if the variable is undefined
47
+ def _perform(environment)
48
+ raise Sass::SyntaxError.new("Undefined variable: \"$#{name}\".") unless val = environment.var(name)
49
+ if val.is_a?(Sass::Script::Value::Number)
50
+ val = val.dup
51
+ val.original = nil
52
+ end
53
+ return val
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ module Sass::Script::Value; end
2
+
3
+ require 'sass/script/value/base'
4
+ require 'sass/script/value/string'
5
+ require 'sass/script/value/number'
6
+ require 'sass/script/value/color'
7
+ require 'sass/script/value/bool'
8
+ require 'sass/script/value/null'
9
+ require 'sass/script/value/list'
10
+ require 'sass/script/value/arg_list'
@@ -1,4 +1,4 @@
1
- module Sass::Script
1
+ module Sass::Script::Value
2
2
  # A SassScript object representing a variable argument list. This works just
3
3
  # like a normal list, but can also contain keyword arguments.
4
4
  #
@@ -13,8 +13,8 @@ module Sass::Script
13
13
 
14
14
  # Creates a new argument list.
15
15
  #
16
- # @param value [Array<Literal>] See \{List#value}.
17
- # @param keywords [Hash<String, Literal>] See \{#keywords}
16
+ # @param value [Array<Value>] See \{List#value}.
17
+ # @param keywords [Hash<String, Value>] See \{#keywords}
18
18
  # @param separator [String] See \{List#separator}.
19
19
  def initialize(value, keywords, separator)
20
20
  super(value, separator)
@@ -23,30 +23,15 @@ module Sass::Script
23
23
 
24
24
  # The keyword arguments attached to this list.
25
25
  #
26
- # @return [Hash<String, Literal>]
26
+ # @return [Hash<String, Value>]
27
27
  def keywords
28
28
  @keywords_accessed = true
29
29
  @keywords
30
30
  end
31
31
 
32
- # @see Node#children
32
+ # @see Base#children
33
33
  def children
34
34
  super + @keywords.values
35
35
  end
36
-
37
- # @see Node#deep_copy
38
- def deep_copy
39
- node = super
40
- node.instance_variable_set('@keywords',
41
- Sass::Util.map_hash(@keywords) {|k, v| [k, v.deep_copy]})
42
- node
43
- end
44
-
45
- protected
46
-
47
- # @see Node#_perform
48
- def _perform(environment)
49
- self
50
- end
51
36
  end
52
37
  end
@@ -0,0 +1,222 @@
1
+ module Sass::Script::Value
2
+ # The abstract superclass for SassScript objects.
3
+ #
4
+ # Many of these methods, especially the ones that correspond to SassScript operations,
5
+ # are designed to be overridden by subclasses which may change the semantics somewhat.
6
+ # The operations listed here are just the defaults.
7
+ class Base
8
+ # Returns the Ruby value of the value.
9
+ # The type of this value varies based on the subclass.
10
+ #
11
+ # @return [Object]
12
+ attr_reader :value
13
+
14
+ # The line of the document on which this node appeared.
15
+ #
16
+ # @return [Fixnum]
17
+ attr_accessor :line
18
+
19
+ # The source range in the document on which this node appeared.
20
+ #
21
+ # @return [Sass::Source::Range]
22
+ attr_accessor :source_range
23
+
24
+ # The file name of the document on which this node appeared.
25
+ #
26
+ # @return [String]
27
+ attr_accessor :filename
28
+
29
+ # Creates a new value.
30
+ #
31
+ # @param value [Object] The object for \{#value}
32
+ def initialize(value = nil)
33
+ @value = value
34
+ end
35
+
36
+ # Sets the options hash for this node,
37
+ # as well as for all child nodes.
38
+ # See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
39
+ #
40
+ # @param options [{Symbol => Object}] The options
41
+ def options=(options)
42
+ @options = options
43
+ end
44
+
45
+ # Returns the options hash for this node.
46
+ #
47
+ # @return [{Symbol => Object}]
48
+ # @raise [Sass::SyntaxError] if the options hash hasn't been set.
49
+ # This should only happen when the value was created
50
+ # outside of the parser and \{#to\_s} was called on it
51
+ def options
52
+ return @options if @options
53
+ raise Sass::SyntaxError.new(<<MSG)
54
+ The #options attribute is not set on this #{self.class}.
55
+ This error is probably occurring because #to_s was called
56
+ on this value within a custom Sass function without first
57
+ setting the #options attribute.
58
+ MSG
59
+ end
60
+
61
+ # The SassScript `==` operation.
62
+ # **Note that this returns a {Sass::Script::Value::Bool} object,
63
+ # not a Ruby boolean**.
64
+ #
65
+ # @param other [Value] The right-hand side of the operator
66
+ # @return [Sass::Script::Value::Bool] True if this value is the same as the other,
67
+ # false otherwise
68
+ def eq(other)
69
+ Sass::Script::Value::Bool.new(self.class == other.class && self.value == other.value)
70
+ end
71
+
72
+ # The SassScript `!=` operation.
73
+ # **Note that this returns a {Sass::Script::Value::Bool} object,
74
+ # not a Ruby boolean**.
75
+ #
76
+ # @param other [Value] The right-hand side of the operator
77
+ # @return [Sass::Script::Value::Bool] False if this value is the same as the other,
78
+ # true otherwise
79
+ def neq(other)
80
+ Sass::Script::Value::Bool.new(!eq(other).to_bool)
81
+ end
82
+
83
+ # The SassScript `==` operation.
84
+ # **Note that this returns a {Sass::Script::Value::Bool} object,
85
+ # not a Ruby boolean**.
86
+ #
87
+ # @param other [Value] The right-hand side of the operator
88
+ # @return [Sass::Script::Value::Bool] True if this value is the same as the other,
89
+ # false otherwise
90
+ def unary_not
91
+ Sass::Script::Value::Bool.new(!to_bool)
92
+ end
93
+
94
+ # The SassScript `=` operation
95
+ # (used for proprietary MS syntax like `alpha(opacity=20)`).
96
+ #
97
+ # @param other [Value] The right-hand side of the operator
98
+ # @return [Script::Value::String] A string containing both values
99
+ # separated by `"="`
100
+ def single_eq(other)
101
+ Sass::Script::Value::String.new("#{self.to_s}=#{other.to_s}")
102
+ end
103
+
104
+ # The SassScript `+` operation.
105
+ #
106
+ # @param other [Value] The right-hand side of the operator
107
+ # @return [Script::Value::String] A string containing both values
108
+ # without any separation
109
+ def plus(other)
110
+ if other.is_a?(Sass::Script::Value::String)
111
+ return Sass::Script::Value::String.new(self.to_s + other.value, other.type)
112
+ end
113
+ Sass::Script::Value::String.new(self.to_s + other.to_s)
114
+ end
115
+
116
+ # The SassScript `-` operation.
117
+ #
118
+ # @param other [Value] The right-hand side of the operator
119
+ # @return [Script::Value::String] A string containing both values
120
+ # separated by `"-"`
121
+ def minus(other)
122
+ Sass::Script::Value::String.new("#{self.to_s}-#{other.to_s}")
123
+ end
124
+
125
+ # The SassScript `/` operation.
126
+ #
127
+ # @param other [Value] The right-hand side of the operator
128
+ # @return [Script::Value::String] A string containing both values
129
+ # separated by `"/"`
130
+ def div(other)
131
+ Sass::Script::Value::String.new("#{self.to_s}/#{other.to_s}")
132
+ end
133
+
134
+ # The SassScript unary `+` operation (e.g. `+$a`).
135
+ #
136
+ # @param other [Value] The right-hand side of the operator
137
+ # @return [Script::Value::String] A string containing the value
138
+ # preceded by `"+"`
139
+ def unary_plus
140
+ Sass::Script::Value::String.new("+#{self.to_s}")
141
+ end
142
+
143
+ # The SassScript unary `-` operation (e.g. `-$a`).
144
+ #
145
+ # @param other [Value] The right-hand side of the operator
146
+ # @return [Script::Value::String] A string containing the value
147
+ # preceded by `"-"`
148
+ def unary_minus
149
+ Sass::Script::Value::String.new("-#{self.to_s}")
150
+ end
151
+
152
+ # The SassScript unary `/` operation (e.g. `/$a`).
153
+ #
154
+ # @param other [Value] The right-hand side of the operator
155
+ # @return [Script::Value::String] A string containing the value
156
+ # preceded by `"/"`
157
+ def unary_div
158
+ Sass::Script::Value::String.new("/#{self.to_s}")
159
+ end
160
+
161
+ # @return [String] A readable representation of the value
162
+ def inspect
163
+ value.inspect
164
+ end
165
+
166
+ # @return [Boolean] `true` (the Ruby boolean value)
167
+ def to_bool
168
+ true
169
+ end
170
+
171
+ # Compares this object with another.
172
+ #
173
+ # @param other [Object] The object to compare with
174
+ # @return [Boolean] Whether or not this value is equivalent to `other`
175
+ def ==(other)
176
+ eq(other).to_bool
177
+ end
178
+
179
+ # @return [Fixnum] The integer value of this value
180
+ # @raise [Sass::SyntaxError] if this value isn't an integer
181
+ def to_i
182
+ raise Sass::SyntaxError.new("#{self.inspect} is not an integer.")
183
+ end
184
+
185
+ # @raise [Sass::SyntaxError] if this value isn't an integer
186
+ def assert_int!; to_i; end
187
+
188
+ # Returns the value of this value as a list.
189
+ # Single values are considered the same as single-element lists.
190
+ #
191
+ # @return [Array<Value>] The of this value as a list
192
+ def to_a
193
+ [self]
194
+ end
195
+
196
+ # Returns the string representation of this value
197
+ # as it would be output to the CSS document.
198
+ #
199
+ # @return [String]
200
+ def to_s(opts = {})
201
+ Sass::Util.abstract(self)
202
+ end
203
+ alias_method :to_sass, :to_s
204
+
205
+ # Returns whether or not this object is null.
206
+ #
207
+ # @return [Boolean] `false`
208
+ def null?
209
+ false
210
+ end
211
+
212
+ protected
213
+
214
+ # Evaluates the value.
215
+ #
216
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
217
+ # @return [Value] This value
218
+ def _perform(environment)
219
+ self
220
+ end
221
+ end
222
+ end