sass 3.2.7 → 3.3.0.rc.1

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 (184) hide show
  1. data/MIT-LICENSE +2 -2
  2. data/README.md +14 -2
  3. data/Rakefile +25 -1
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/lib/sass/cache_stores/base.rb +4 -2
  8. data/lib/sass/cache_stores/chain.rb +2 -1
  9. data/lib/sass/cache_stores/filesystem.rb +2 -6
  10. data/lib/sass/cache_stores/memory.rb +1 -1
  11. data/lib/sass/cache_stores/null.rb +2 -2
  12. data/lib/sass/callbacks.rb +1 -0
  13. data/lib/sass/css.rb +10 -10
  14. data/lib/sass/engine.rb +403 -150
  15. data/lib/sass/environment.rb +136 -57
  16. data/lib/sass/error.rb +7 -7
  17. data/lib/sass/exec.rb +123 -39
  18. data/lib/sass/features.rb +41 -0
  19. data/lib/sass/importers/base.rb +33 -2
  20. data/lib/sass/importers/deprecated_path.rb +45 -0
  21. data/lib/sass/importers/filesystem.rb +25 -14
  22. data/lib/sass/importers.rb +1 -0
  23. data/lib/sass/logger/base.rb +3 -3
  24. data/lib/sass/logger/log_level.rb +4 -6
  25. data/lib/sass/media.rb +19 -19
  26. data/lib/sass/plugin/compiler.rb +141 -101
  27. data/lib/sass/plugin/configuration.rb +18 -22
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/staleness_checker.rb +24 -8
  30. data/lib/sass/plugin.rb +4 -2
  31. data/lib/sass/repl.rb +3 -3
  32. data/lib/sass/script/css_lexer.rb +9 -4
  33. data/lib/sass/script/css_parser.rb +6 -2
  34. data/lib/sass/script/functions.rb +1343 -590
  35. data/lib/sass/script/lexer.rb +84 -52
  36. data/lib/sass/script/parser.rb +217 -97
  37. data/lib/sass/script/tree/funcall.rb +290 -0
  38. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +34 -13
  39. data/lib/sass/script/tree/list_literal.rb +80 -0
  40. data/lib/sass/script/tree/literal.rb +47 -0
  41. data/lib/sass/script/tree/map_literal.rb +64 -0
  42. data/lib/sass/script/{node.rb → tree/node.rb} +22 -12
  43. data/lib/sass/script/{operation.rb → tree/operation.rb} +17 -25
  44. data/lib/sass/script/tree/selector.rb +30 -0
  45. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +5 -4
  46. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +14 -9
  47. data/lib/sass/script/tree/variable.rb +57 -0
  48. data/lib/sass/script/tree.rb +16 -0
  49. data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +4 -24
  50. data/lib/sass/script/value/base.rb +248 -0
  51. data/lib/sass/script/value/bool.rb +36 -0
  52. data/lib/sass/script/{color.rb → value/color.rb} +239 -195
  53. data/lib/sass/script/value/helpers.rb +155 -0
  54. data/lib/sass/script/value/list.rb +119 -0
  55. data/lib/sass/script/value/map.rb +70 -0
  56. data/lib/sass/script/value/null.rb +45 -0
  57. data/lib/sass/script/{number.rb → value/number.rb} +91 -65
  58. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  59. data/lib/sass/script/value.rb +11 -0
  60. data/lib/sass/script.rb +35 -8
  61. data/lib/sass/scss/css_parser.rb +2 -1
  62. data/lib/sass/scss/parser.rb +338 -170
  63. data/lib/sass/scss/rx.rb +5 -6
  64. data/lib/sass/scss/script_lexer.rb +1 -0
  65. data/lib/sass/scss/script_parser.rb +1 -0
  66. data/lib/sass/scss/static_parser.rb +23 -6
  67. data/lib/sass/selector/abstract_sequence.rb +2 -2
  68. data/lib/sass/selector/comma_sequence.rb +21 -16
  69. data/lib/sass/selector/sequence.rb +60 -34
  70. data/lib/sass/selector/simple.rb +11 -12
  71. data/lib/sass/selector/simple_sequence.rb +55 -33
  72. data/lib/sass/selector.rb +52 -48
  73. data/lib/sass/source/map.rb +211 -0
  74. data/lib/sass/source/position.rb +39 -0
  75. data/lib/sass/source/range.rb +41 -0
  76. data/lib/sass/stack.rb +120 -0
  77. data/lib/sass/supports.rb +12 -13
  78. data/lib/sass/tree/at_root_node.rb +82 -0
  79. data/lib/sass/tree/comment_node.rb +3 -3
  80. data/lib/sass/tree/css_import_node.rb +11 -11
  81. data/lib/sass/tree/debug_node.rb +2 -2
  82. data/lib/sass/tree/directive_node.rb +13 -2
  83. data/lib/sass/tree/each_node.rb +8 -8
  84. data/lib/sass/tree/extend_node.rb +13 -6
  85. data/lib/sass/tree/for_node.rb +4 -4
  86. data/lib/sass/tree/function_node.rb +5 -4
  87. data/lib/sass/tree/if_node.rb +1 -1
  88. data/lib/sass/tree/import_node.rb +4 -5
  89. data/lib/sass/tree/media_node.rb +4 -14
  90. data/lib/sass/tree/mixin_def_node.rb +4 -4
  91. data/lib/sass/tree/mixin_node.rb +21 -8
  92. data/lib/sass/tree/node.rb +29 -12
  93. data/lib/sass/tree/prop_node.rb +38 -18
  94. data/lib/sass/tree/return_node.rb +3 -2
  95. data/lib/sass/tree/root_node.rb +19 -3
  96. data/lib/sass/tree/rule_node.rb +25 -17
  97. data/lib/sass/tree/supports_node.rb +0 -13
  98. data/lib/sass/tree/trace_node.rb +2 -1
  99. data/lib/sass/tree/variable_node.rb +9 -3
  100. data/lib/sass/tree/visitors/base.rb +6 -6
  101. data/lib/sass/tree/visitors/check_nesting.rb +12 -9
  102. data/lib/sass/tree/visitors/convert.rb +63 -38
  103. data/lib/sass/tree/visitors/cssize.rb +63 -23
  104. data/lib/sass/tree/visitors/deep_copy.rb +6 -5
  105. data/lib/sass/tree/visitors/extend.rb +7 -7
  106. data/lib/sass/tree/visitors/perform.rb +256 -151
  107. data/lib/sass/tree/visitors/set_options.rb +6 -6
  108. data/lib/sass/tree/visitors/to_css.rb +231 -81
  109. data/lib/sass/tree/warn_node.rb +2 -2
  110. data/lib/sass/tree/while_node.rb +2 -2
  111. data/lib/sass/util/multibyte_string_scanner.rb +2 -0
  112. data/lib/sass/util/normalized_map.rb +65 -0
  113. data/lib/sass/util/ordered_hash.rb +188 -0
  114. data/lib/sass/util/subset_map.rb +3 -2
  115. data/lib/sass/util/test.rb +9 -0
  116. data/lib/sass/util.rb +220 -34
  117. data/lib/sass/version.rb +9 -9
  118. data/lib/sass.rb +14 -7
  119. data/test/sass/compiler_test.rb +213 -0
  120. data/test/sass/conversion_test.rb +235 -9
  121. data/test/sass/engine_test.rb +230 -60
  122. data/test/sass/exec_test.rb +86 -0
  123. data/test/sass/extend_test.rb +215 -147
  124. data/test/sass/functions_test.rb +584 -99
  125. data/test/sass/importer_test.rb +165 -17
  126. data/test/sass/plugin_test.rb +19 -13
  127. data/test/sass/script_conversion_test.rb +40 -0
  128. data/test/sass/script_test.rb +231 -21
  129. data/test/sass/scss/css_test.rb +14 -5
  130. data/test/sass/scss/scss_test.rb +1266 -66
  131. data/test/sass/source_map_test.rb +879 -0
  132. data/test/sass/templates/bork5.sass +3 -0
  133. data/test/sass/util/normalized_map_test.rb +30 -0
  134. data/test/sass/util_test.rb +90 -0
  135. data/test/sass/value_helpers_test.rb +181 -0
  136. data/test/test_helper.rb +7 -2
  137. metadata +316 -291
  138. data/lib/sass/script/bool.rb +0 -18
  139. data/lib/sass/script/funcall.rb +0 -231
  140. data/lib/sass/script/list.rb +0 -84
  141. data/lib/sass/script/literal.rb +0 -239
  142. data/lib/sass/script/null.rb +0 -34
  143. data/lib/sass/script/variable.rb +0 -58
  144. data/test/Gemfile +0 -3
  145. data/vendor/listen/CHANGELOG.md +0 -221
  146. data/vendor/listen/CONTRIBUTING.md +0 -38
  147. data/vendor/listen/Gemfile +0 -30
  148. data/vendor/listen/Guardfile +0 -8
  149. data/vendor/listen/LICENSE +0 -20
  150. data/vendor/listen/README.md +0 -315
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen/adapter.rb +0 -214
  154. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -85
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -113
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -67
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -87
  159. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  160. data/vendor/listen/lib/listen/directory_record.rb +0 -371
  161. data/vendor/listen/lib/listen/listener.rb +0 -225
  162. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  163. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  164. data/vendor/listen/lib/listen/version.rb +0 -3
  165. data/vendor/listen/lib/listen.rb +0 -40
  166. data/vendor/listen/listen.gemspec +0 -22
  167. data/vendor/listen/spec/listen/adapter_spec.rb +0 -183
  168. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  169. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  170. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  171. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  172. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  173. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  174. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1225
  175. data/vendor/listen/spec/listen/listener_spec.rb +0 -169
  176. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
  177. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  178. data/vendor/listen/spec/listen_spec.rb +0 -73
  179. data/vendor/listen/spec/spec_helper.rb +0 -21
  180. data/vendor/listen/spec/support/adapter_helper.rb +0 -629
  181. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  182. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  183. data/vendor/listen/spec/support/listeners_helper.rb +0 -156
  184. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -1,13 +1,4 @@
1
- require 'set'
2
- require 'sass/script/string'
3
- require 'sass/script/number'
4
- require 'sass/script/color'
5
- require 'sass/script/functions'
6
- require 'sass/script/unary_operation'
7
- require 'sass/script/interpolation'
8
- require 'sass/script/string_interpolation'
9
-
10
- module Sass::Script
1
+ module Sass::Script::Tree
11
2
  # A SassScript parse node representing a binary operation,
12
3
  # such as `$a + $b` or `"foo" + 1`.
13
4
  class Operation < Node
@@ -15,12 +6,12 @@ module Sass::Script
15
6
  attr_reader :operand2
16
7
  attr_reader :operator
17
8
 
18
- # @param operand1 [Script::Node] The parse-tree node
9
+ # @param operand1 [Sass::Script::Tree::Node] The parse-tree node
19
10
  # for the right-hand side of the operator
20
- # @param operand2 [Script::Node] The parse-tree node
11
+ # @param operand2 [Sass::Script::Tree::Node] The parse-tree node
21
12
  # for the left-hand side of the operator
22
13
  # @param operator [Symbol] The operator to perform.
23
- # 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}
24
15
  def initialize(operand1, operand2, operator)
25
16
  @operand1 = operand1
26
17
  @operand2 = operand2
@@ -35,14 +26,13 @@ module Sass::Script
35
26
 
36
27
  # @see Node#to_sass
37
28
  def to_sass(opts = {})
38
- pred = Sass::Script::Parser.precedence_of(@operator)
39
29
  o1 = operand_to_sass @operand1, :left, opts
40
30
  o2 = operand_to_sass @operand2, :right, opts
41
31
  sep =
42
32
  case @operator
43
33
  when :comma; ", "
44
34
  when :space; " "
45
- else; " #{Lexer::OPERATORS_REVERSE[@operator]} "
35
+ else; " #{Sass::Script::Lexer::OPERATORS_REVERSE[@operator]} "
46
36
  end
47
37
  "#{o1}#{sep}#{o2}"
48
38
  end
@@ -68,36 +58,38 @@ module Sass::Script
68
58
  # Evaluates the operation.
69
59
  #
70
60
  # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
71
- # @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
72
62
  # @raise [Sass::SyntaxError] if the operation is undefined for the operands
73
63
  def _perform(environment)
74
- literal1 = @operand1.perform(environment)
64
+ value1 = @operand1.perform(environment)
75
65
 
76
66
  # Special-case :and and :or to support short-circuiting.
77
67
  if @operator == :and
78
- return literal1.to_bool ? @operand2.perform(environment) : literal1
68
+ return value1.to_bool ? @operand2.perform(environment) : value1
79
69
  elsif @operator == :or
80
- return literal1.to_bool ? literal1 : @operand2.perform(environment)
70
+ return value1.to_bool ? value1 : @operand2.perform(environment)
81
71
  end
82
72
 
83
- literal2 = @operand2.perform(environment)
73
+ value2 = @operand2.perform(environment)
84
74
 
85
- if (literal1.is_a?(Null) || literal2.is_a?(Null)) && @operator != :eq && @operator != :neq
86
- 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(
78
+ "Invalid null operation: \"#{value1.inspect} #{@operator} #{value2.inspect}\".")
87
79
  end
88
80
 
89
81
  begin
90
- opts(literal1.send(@operator, literal2))
82
+ opts(value1.send(@operator, value2))
91
83
  rescue NoMethodError => e
92
84
  raise e unless e.name.to_s == @operator.to_s
93
- raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\".")
85
+ raise Sass::SyntaxError.new("Undefined operation: \"#{value1} #{@operator} #{value2}\".")
94
86
  end
95
87
  end
96
88
 
97
89
  private
98
90
 
99
91
  def operand_to_sass(op, side, opts)
100
- return "(#{op.to_sass(opts)})" if op.is_a?(List)
92
+ return "(#{op.to_sass(opts)})" if op.is_a?(Sass::Script::Tree::ListLiteral)
101
93
  return op.to_sass(opts) unless op.is_a?(Operation)
102
94
 
103
95
  pred = Sass::Script::Parser.precedence_of(@operator)
@@ -0,0 +1,30 @@
1
+ module Sass::Script::Tree
2
+ # A SassScript node that will resolve to the current selector.
3
+ class Selector < Node
4
+ def initialize; end
5
+
6
+ def children
7
+ []
8
+ end
9
+
10
+ def to_sass(opts = {})
11
+ '&'
12
+ end
13
+
14
+ def deep_copy
15
+ dup
16
+ end
17
+
18
+ protected
19
+
20
+ def _perform(environment)
21
+ selector = environment.selector
22
+ return opts(Sass::Script::Value::Null.new) unless selector
23
+ opts(Sass::Script::Value::List.new(selector.members.map do |seq|
24
+ Sass::Script::Value::List.new(seq.members.map do |component|
25
+ Sass::Script::Value::String.new(component.to_s)
26
+ end, :space)
27
+ end, :comma))
28
+ end
29
+ end
30
+ end
@@ -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,16 @@ 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]
78
+ # The SassScript string that is the value of the interpolation
78
79
  def _perform(environment)
79
80
  res = ""
80
81
  before = @before.perform(environment)
81
82
  res << before.value
82
83
  mid = @mid.perform(environment)
83
- res << (mid.is_a?(Sass::Script::String) ? mid.value : mid.to_s)
84
+ res << (mid.is_a?(Sass::Script::Value::String) ? mid.value : mid.to_s)
84
85
  res << @after.perform(environment).value
85
- opts(Sass::Script::String.new(res, before.type))
86
+ opts(Sass::Script::Value::String.new(res, before.type))
86
87
  end
87
88
 
88
89
  private
@@ -1,12 +1,17 @@
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
9
- # @param operator [Symbol] The operator to perform
7
+ # @return [Symbol] The operation to perform
8
+ attr_reader :operator
9
+
10
+ # @return [Script::Node] The parse-tree node for the object of the operator
11
+ attr_reader :operand
12
+
13
+ # @param operand [Script::Node] See \{#operand}
14
+ # @param operator [Symbol] See \{#operator}
10
15
  def initialize(operand, operator)
11
16
  @operand = operand
12
17
  @operator = operator
@@ -26,7 +31,7 @@ module Sass::Script
26
31
  (operand =~ Sass::SCSS::RX::IDENT) == 0)
27
32
  operand = "(#{@operand.to_sass(opts)})"
28
33
  end
29
- op = Lexer::OPERATORS_REVERSE[@operator]
34
+ op = Sass::Script::Lexer::OPERATORS_REVERSE[@operator]
30
35
  op + (op =~ /[a-z]/ ? " " : "") + operand
31
36
  end
32
37
 
@@ -50,15 +55,15 @@ module Sass::Script
50
55
  # Evaluates the operation.
51
56
  #
52
57
  # @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
58
+ # @return [Sass::Script::Value] The SassScript object that is the value of the operation
54
59
  # @raise [Sass::SyntaxError] if the operation is undefined for the operand
55
60
  def _perform(environment)
56
61
  operator = "unary_#{@operator}"
57
- literal = @operand.perform(environment)
58
- literal.send(operator)
62
+ value = @operand.perform(environment)
63
+ value.send(operator)
59
64
  rescue NoMethodError => e
60
65
  raise e unless e.name.to_s == operator.to_s
61
- raise Sass::SyntaxError.new("Undefined unary operation: \"#{@operator} #{literal}\".")
66
+ raise Sass::SyntaxError.new("Undefined unary operation: \"#{@operator} #{value}\".")
62
67
  end
63
68
  end
64
69
  end
@@ -0,0 +1,57 @@
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
+ val = environment.var(name)
49
+ raise Sass::SyntaxError.new("Undefined variable: \"$#{name}\".") unless val
50
+ if val.is_a?(Sass::Script::Value::Number)
51
+ val = val.dup
52
+ val.original = nil
53
+ end
54
+ val
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,16 @@
1
+ # The module containing nodes in the SassScript parse tree. These nodes are
2
+ # all subclasses of {Sass::Script::Tree::Node}.
3
+ module Sass::Script::Tree
4
+ end
5
+
6
+ require 'sass/script/tree/node'
7
+ require 'sass/script/tree/variable'
8
+ require 'sass/script/tree/funcall'
9
+ require 'sass/script/tree/operation'
10
+ require 'sass/script/tree/unary_operation'
11
+ require 'sass/script/tree/interpolation'
12
+ require 'sass/script/tree/string_interpolation'
13
+ require 'sass/script/tree/literal'
14
+ require 'sass/script/tree/list_literal'
15
+ require 'sass/script/tree/map_literal'
16
+ require 'sass/script/tree/selector'
@@ -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,10 @@ 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
-
32
- # @see Node#children
33
- def children
34
- super + @keywords.values
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
31
  end
52
32
  end
@@ -0,0 +1,248 @@
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
+ attr_writer :options
42
+
43
+ # Returns the options hash for this node.
44
+ #
45
+ # @return [{Symbol => Object}]
46
+ # @raise [Sass::SyntaxError] if the options hash hasn't been set.
47
+ # This should only happen when the value was created
48
+ # outside of the parser and \{#to\_s} was called on it
49
+ def options
50
+ return @options if @options
51
+ raise Sass::SyntaxError.new(<<MSG)
52
+ The #options attribute is not set on this #{self.class}.
53
+ This error is probably occurring because #to_s was called
54
+ on this value within a custom Sass function without first
55
+ setting the #options attribute.
56
+ MSG
57
+ end
58
+
59
+ # The SassScript `==` operation.
60
+ # **Note that this returns a {Sass::Script::Value::Bool} object,
61
+ # not a Ruby boolean**.
62
+ #
63
+ # @param other [Value] The right-hand side of the operator
64
+ # @return [Sass::Script::Value::Bool] True if this value is the same as the other,
65
+ # false otherwise
66
+ def eq(other)
67
+ Sass::Script::Value::Bool.new(self.class == other.class && value == other.value)
68
+ end
69
+
70
+ # The SassScript `!=` operation.
71
+ # **Note that this returns a {Sass::Script::Value::Bool} object,
72
+ # not a Ruby boolean**.
73
+ #
74
+ # @param other [Value] The right-hand side of the operator
75
+ # @return [Sass::Script::Value::Bool] False if this value is the same as the other,
76
+ # true otherwise
77
+ def neq(other)
78
+ Sass::Script::Value::Bool.new(!eq(other).to_bool)
79
+ end
80
+
81
+ # The SassScript `==` operation.
82
+ # **Note that this returns a {Sass::Script::Value::Bool} object,
83
+ # not a Ruby boolean**.
84
+ #
85
+ # @param other [Value] The right-hand side of the operator
86
+ # @return [Sass::Script::Value::Bool] True if this value is the same as the other,
87
+ # false otherwise
88
+ def unary_not
89
+ Sass::Script::Value::Bool.new(!to_bool)
90
+ end
91
+
92
+ # The SassScript `=` operation
93
+ # (used for proprietary MS syntax like `alpha(opacity=20)`).
94
+ #
95
+ # @param other [Value] The right-hand side of the operator
96
+ # @return [Script::Value::String] A string containing both values
97
+ # separated by `"="`
98
+ def single_eq(other)
99
+ Sass::Script::Value::String.new("#{to_s}=#{other.to_s}")
100
+ end
101
+
102
+ # The SassScript `+` operation.
103
+ #
104
+ # @param other [Value] The right-hand side of the operator
105
+ # @return [Script::Value::String] A string containing both values
106
+ # without any separation
107
+ def plus(other)
108
+ if other.is_a?(Sass::Script::Value::String)
109
+ return Sass::Script::Value::String.new(to_s + other.value, other.type)
110
+ end
111
+ Sass::Script::Value::String.new(to_s + other.to_s)
112
+ end
113
+
114
+ # The SassScript `-` operation.
115
+ #
116
+ # @param other [Value] The right-hand side of the operator
117
+ # @return [Script::Value::String] A string containing both values
118
+ # separated by `"-"`
119
+ def minus(other)
120
+ Sass::Script::Value::String.new("#{to_s}-#{other.to_s}")
121
+ end
122
+
123
+ # The SassScript `/` operation.
124
+ #
125
+ # @param other [Value] The right-hand side of the operator
126
+ # @return [Script::Value::String] A string containing both values
127
+ # separated by `"/"`
128
+ def div(other)
129
+ Sass::Script::Value::String.new("#{to_s}/#{other.to_s}")
130
+ end
131
+
132
+ # The SassScript unary `+` operation (e.g. `+$a`).
133
+ #
134
+ # @param other [Value] The right-hand side of the operator
135
+ # @return [Script::Value::String] A string containing the value
136
+ # preceded by `"+"`
137
+ def unary_plus
138
+ Sass::Script::Value::String.new("+#{to_s}")
139
+ end
140
+
141
+ # The SassScript unary `-` operation (e.g. `-$a`).
142
+ #
143
+ # @param other [Value] The right-hand side of the operator
144
+ # @return [Script::Value::String] A string containing the value
145
+ # preceded by `"-"`
146
+ def unary_minus
147
+ Sass::Script::Value::String.new("-#{to_s}")
148
+ end
149
+
150
+ # The SassScript unary `/` operation (e.g. `/$a`).
151
+ #
152
+ # @param other [Value] The right-hand side of the operator
153
+ # @return [Script::Value::String] A string containing the value
154
+ # preceded by `"/"`
155
+ def unary_div
156
+ Sass::Script::Value::String.new("/#{to_s}")
157
+ end
158
+
159
+ # Returns the hash code of this value. Two objects' hash codes should be
160
+ # equal if the objects are equal.
161
+ #
162
+ # @return [Fixnum] The hash code.
163
+ def hash
164
+ value.hash
165
+ end
166
+
167
+ def eql?(other)
168
+ self == other
169
+ end
170
+
171
+ # @return [String] A readable representation of the value
172
+ def inspect
173
+ value.inspect
174
+ end
175
+
176
+ # @return [Boolean] `true` (the Ruby boolean value)
177
+ def to_bool
178
+ true
179
+ end
180
+
181
+ # Compares this object with another.
182
+ #
183
+ # @param other [Object] The object to compare with
184
+ # @return [Boolean] Whether or not this value is equivalent to `other`
185
+ def ==(other)
186
+ eq(other).to_bool
187
+ end
188
+
189
+ # @return [Fixnum] The integer value of this value
190
+ # @raise [Sass::SyntaxError] if this value isn't an integer
191
+ def to_i
192
+ raise Sass::SyntaxError.new("#{inspect} is not an integer.")
193
+ end
194
+
195
+ # @raise [Sass::SyntaxError] if this value isn't an integer
196
+ def assert_int!; to_i; end
197
+
198
+ # Returns the separator for this value. For non-list-like values or the
199
+ # empty list, this will be `nil`. For lists or maps, it will be `:space` or
200
+ # `:comma`.
201
+ #
202
+ # @return [Symbol]
203
+ def separator; nil; end
204
+
205
+ # Returns the value of this value as a list.
206
+ # Single values are considered the same as single-element lists.
207
+ #
208
+ # @return [Array<Value>] This value as a list
209
+ def to_a
210
+ [self]
211
+ end
212
+
213
+ # Returns the value of this value as a hash. Most values don't have hash
214
+ # representations, but [Map]s and empty [List]s do.
215
+ #
216
+ # @return [Hash<Value, Value>] This value as a hash
217
+ # @raise [Sass::SyntaxError] if this value doesn't have a hash representation
218
+ def to_h
219
+ raise Sass::SyntaxError.new("#{inspect} is not a map.")
220
+ end
221
+
222
+ # Returns the string representation of this value
223
+ # as it would be output to the CSS document.
224
+ #
225
+ # @return [String]
226
+ def to_s(opts = {})
227
+ Sass::Util.abstract(self)
228
+ end
229
+ alias_method :to_sass, :to_s
230
+
231
+ # Returns whether or not this object is null.
232
+ #
233
+ # @return [Boolean] `false`
234
+ def null?
235
+ false
236
+ end
237
+
238
+ protected
239
+
240
+ # Evaluates the value.
241
+ #
242
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
243
+ # @return [Value] This value
244
+ def _perform(environment)
245
+ self
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,36 @@
1
+ module Sass::Script::Value
2
+ # A SassScript object representing a boolean (true or false) value.
3
+ class Bool < Base
4
+
5
+ # The true value in SassScript.
6
+ #
7
+ # This is assigned before new is overridden below so that we use the default implementation.
8
+ TRUE = new(true)
9
+
10
+ # The false value in SassScript.
11
+ #
12
+ # This is assigned before new is overridden below so that we use the default implementation.
13
+ FALSE = new(false)
14
+
15
+ # We override object creation so that users of the core API
16
+ # will not need to know that booleans are specific constants.
17
+ #
18
+ # @param value A ruby value that will be tested for truthiness.
19
+ # @return [Bool] TRUE if value is truthy, FALSE if value is falsey
20
+ def self.new(value)
21
+ value ? TRUE : FALSE
22
+ end
23
+
24
+ # The Ruby value of the boolean.
25
+ #
26
+ # @return [Boolean]
27
+ attr_reader :value
28
+ alias_method :to_bool, :value
29
+
30
+ # @return [String] "true" or "false"
31
+ def to_s(opts = {})
32
+ @value.to_s
33
+ end
34
+ alias_method :to_sass, :to_s
35
+ end
36
+ end