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

Sign up to get free protection for your applications and to get access to all the features.
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