sass 3.1.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING +1 -1
  3. data/MIT-LICENSE +2 -2
  4. data/README.md +29 -17
  5. data/Rakefile +43 -9
  6. data/VERSION +1 -1
  7. data/VERSION_DATE +1 -0
  8. data/VERSION_NAME +1 -1
  9. data/bin/sass +6 -1
  10. data/bin/sass-convert +6 -1
  11. data/bin/scss +6 -1
  12. data/ext/mkrf_conf.rb +27 -0
  13. data/lib/sass/cache_stores/base.rb +7 -3
  14. data/lib/sass/cache_stores/chain.rb +3 -2
  15. data/lib/sass/cache_stores/filesystem.rb +5 -7
  16. data/lib/sass/cache_stores/memory.rb +1 -1
  17. data/lib/sass/cache_stores/null.rb +2 -2
  18. data/lib/sass/callbacks.rb +2 -1
  19. data/lib/sass/css.rb +168 -53
  20. data/lib/sass/engine.rb +502 -174
  21. data/lib/sass/environment.rb +151 -111
  22. data/lib/sass/error.rb +7 -7
  23. data/lib/sass/exec.rb +176 -60
  24. data/lib/sass/features.rb +40 -0
  25. data/lib/sass/importers/base.rb +46 -7
  26. data/lib/sass/importers/deprecated_path.rb +51 -0
  27. data/lib/sass/importers/filesystem.rb +113 -30
  28. data/lib/sass/importers.rb +1 -0
  29. data/lib/sass/logger/base.rb +30 -0
  30. data/lib/sass/logger/log_level.rb +45 -0
  31. data/lib/sass/logger.rb +12 -0
  32. data/lib/sass/media.rb +213 -0
  33. data/lib/sass/plugin/compiler.rb +194 -104
  34. data/lib/sass/plugin/configuration.rb +18 -25
  35. data/lib/sass/plugin/merb.rb +1 -1
  36. data/lib/sass/plugin/staleness_checker.rb +37 -11
  37. data/lib/sass/plugin.rb +10 -13
  38. data/lib/sass/railtie.rb +2 -1
  39. data/lib/sass/repl.rb +5 -6
  40. data/lib/sass/script/css_lexer.rb +8 -4
  41. data/lib/sass/script/css_parser.rb +5 -2
  42. data/lib/sass/script/functions.rb +1547 -618
  43. data/lib/sass/script/lexer.rb +122 -72
  44. data/lib/sass/script/parser.rb +304 -135
  45. data/lib/sass/script/tree/funcall.rb +306 -0
  46. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +43 -13
  47. data/lib/sass/script/tree/list_literal.rb +77 -0
  48. data/lib/sass/script/tree/literal.rb +45 -0
  49. data/lib/sass/script/tree/map_literal.rb +64 -0
  50. data/lib/sass/script/{node.rb → tree/node.rb} +30 -12
  51. data/lib/sass/script/{operation.rb → tree/operation.rb} +33 -21
  52. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +14 -4
  53. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +21 -9
  54. data/lib/sass/script/tree/variable.rb +57 -0
  55. data/lib/sass/script/tree.rb +15 -0
  56. data/lib/sass/script/value/arg_list.rb +36 -0
  57. data/lib/sass/script/value/base.rb +238 -0
  58. data/lib/sass/script/value/bool.rb +40 -0
  59. data/lib/sass/script/{color.rb → value/color.rb} +256 -74
  60. data/lib/sass/script/value/deprecated_false.rb +55 -0
  61. data/lib/sass/script/value/helpers.rb +155 -0
  62. data/lib/sass/script/value/list.rb +128 -0
  63. data/lib/sass/script/value/map.rb +70 -0
  64. data/lib/sass/script/value/null.rb +49 -0
  65. data/lib/sass/script/{number.rb → value/number.rb} +115 -62
  66. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  67. data/lib/sass/script/value.rb +12 -0
  68. data/lib/sass/script.rb +35 -9
  69. data/lib/sass/scss/css_parser.rb +2 -12
  70. data/lib/sass/scss/parser.rb +657 -230
  71. data/lib/sass/scss/rx.rb +17 -12
  72. data/lib/sass/scss/static_parser.rb +37 -6
  73. data/lib/sass/scss.rb +0 -1
  74. data/lib/sass/selector/abstract_sequence.rb +35 -3
  75. data/lib/sass/selector/comma_sequence.rb +29 -14
  76. data/lib/sass/selector/sequence.rb +371 -74
  77. data/lib/sass/selector/simple.rb +28 -13
  78. data/lib/sass/selector/simple_sequence.rb +163 -36
  79. data/lib/sass/selector.rb +138 -36
  80. data/lib/sass/shared.rb +3 -5
  81. data/lib/sass/source/map.rb +196 -0
  82. data/lib/sass/source/position.rb +39 -0
  83. data/lib/sass/source/range.rb +41 -0
  84. data/lib/sass/stack.rb +126 -0
  85. data/lib/sass/supports.rb +228 -0
  86. data/lib/sass/tree/at_root_node.rb +82 -0
  87. data/lib/sass/tree/comment_node.rb +34 -29
  88. data/lib/sass/tree/content_node.rb +9 -0
  89. data/lib/sass/tree/css_import_node.rb +60 -0
  90. data/lib/sass/tree/debug_node.rb +3 -3
  91. data/lib/sass/tree/directive_node.rb +33 -3
  92. data/lib/sass/tree/each_node.rb +9 -9
  93. data/lib/sass/tree/extend_node.rb +20 -6
  94. data/lib/sass/tree/for_node.rb +6 -6
  95. data/lib/sass/tree/function_node.rb +12 -4
  96. data/lib/sass/tree/if_node.rb +2 -15
  97. data/lib/sass/tree/import_node.rb +11 -5
  98. data/lib/sass/tree/media_node.rb +27 -11
  99. data/lib/sass/tree/mixin_def_node.rb +15 -4
  100. data/lib/sass/tree/mixin_node.rb +27 -7
  101. data/lib/sass/tree/node.rb +69 -35
  102. data/lib/sass/tree/prop_node.rb +47 -31
  103. data/lib/sass/tree/return_node.rb +4 -3
  104. data/lib/sass/tree/root_node.rb +20 -4
  105. data/lib/sass/tree/rule_node.rb +37 -26
  106. data/lib/sass/tree/supports_node.rb +38 -0
  107. data/lib/sass/tree/trace_node.rb +33 -0
  108. data/lib/sass/tree/variable_node.rb +10 -4
  109. data/lib/sass/tree/visitors/base.rb +5 -8
  110. data/lib/sass/tree/visitors/check_nesting.rb +67 -52
  111. data/lib/sass/tree/visitors/convert.rb +134 -53
  112. data/lib/sass/tree/visitors/cssize.rb +245 -51
  113. data/lib/sass/tree/visitors/deep_copy.rb +102 -0
  114. data/lib/sass/tree/visitors/extend.rb +68 -0
  115. data/lib/sass/tree/visitors/perform.rb +331 -105
  116. data/lib/sass/tree/visitors/set_options.rb +125 -0
  117. data/lib/sass/tree/visitors/to_css.rb +259 -95
  118. data/lib/sass/tree/warn_node.rb +3 -3
  119. data/lib/sass/tree/while_node.rb +3 -3
  120. data/lib/sass/util/cross_platform_random.rb +19 -0
  121. data/lib/sass/util/multibyte_string_scanner.rb +157 -0
  122. data/lib/sass/util/normalized_map.rb +130 -0
  123. data/lib/sass/util/ordered_hash.rb +192 -0
  124. data/lib/sass/util/subset_map.rb +11 -2
  125. data/lib/sass/util/test.rb +9 -0
  126. data/lib/sass/util.rb +565 -39
  127. data/lib/sass/version.rb +27 -15
  128. data/lib/sass.rb +39 -4
  129. data/test/sass/cache_test.rb +15 -0
  130. data/test/sass/compiler_test.rb +223 -0
  131. data/test/sass/conversion_test.rb +901 -107
  132. data/test/sass/css2sass_test.rb +94 -0
  133. data/test/sass/engine_test.rb +1059 -164
  134. data/test/sass/exec_test.rb +86 -0
  135. data/test/sass/extend_test.rb +933 -837
  136. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  137. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  138. data/test/sass/functions_test.rb +995 -136
  139. data/test/sass/importer_test.rb +338 -18
  140. data/test/sass/logger_test.rb +58 -0
  141. data/test/sass/more_results/more_import.css +2 -2
  142. data/test/sass/plugin_test.rb +114 -30
  143. data/test/sass/results/cached_import_option.css +3 -0
  144. data/test/sass/results/filename_fn.css +3 -0
  145. data/test/sass/results/import.css +2 -2
  146. data/test/sass/results/import_charset.css +1 -0
  147. data/test/sass/results/import_charset_1_8.css +1 -0
  148. data/test/sass/results/import_charset_ibm866.css +1 -0
  149. data/test/sass/results/import_content.css +1 -0
  150. data/test/sass/results/script.css +1 -1
  151. data/test/sass/results/scss_import.css +2 -2
  152. data/test/sass/results/units.css +2 -2
  153. data/test/sass/script_conversion_test.rb +43 -1
  154. data/test/sass/script_test.rb +380 -36
  155. data/test/sass/scss/css_test.rb +257 -75
  156. data/test/sass/scss/scss_test.rb +2322 -110
  157. data/test/sass/source_map_test.rb +887 -0
  158. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  159. data/test/sass/templates/_double_import_loop2.sass +1 -0
  160. data/test/sass/templates/_filename_fn_import.scss +11 -0
  161. data/test/sass/templates/_imported_content.sass +3 -0
  162. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  163. data/test/sass/templates/bork5.sass +3 -0
  164. data/test/sass/templates/cached_import_option.scss +3 -0
  165. data/test/sass/templates/double_import_loop1.sass +1 -0
  166. data/test/sass/templates/filename_fn.scss +18 -0
  167. data/test/sass/templates/import_charset.sass +2 -0
  168. data/test/sass/templates/import_charset_1_8.sass +2 -0
  169. data/test/sass/templates/import_charset_ibm866.sass +2 -0
  170. data/test/sass/templates/import_content.sass +4 -0
  171. data/test/sass/templates/same_name_different_ext.sass +2 -0
  172. data/test/sass/templates/same_name_different_ext.scss +1 -0
  173. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  174. data/test/sass/templates/single_import_loop.sass +1 -0
  175. data/test/sass/templates/subdir/import_up1.scss +1 -0
  176. data/test/sass/templates/subdir/import_up2.scss +1 -0
  177. data/test/sass/test_helper.rb +1 -1
  178. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  179. data/test/sass/util/normalized_map_test.rb +51 -0
  180. data/test/sass/util_test.rb +183 -0
  181. data/test/sass/value_helpers_test.rb +181 -0
  182. data/test/test_helper.rb +45 -5
  183. data/vendor/listen/CHANGELOG.md +228 -0
  184. data/vendor/listen/CONTRIBUTING.md +38 -0
  185. data/vendor/listen/Gemfile +30 -0
  186. data/vendor/listen/Guardfile +8 -0
  187. data/vendor/{fssm → listen}/LICENSE +1 -1
  188. data/vendor/listen/README.md +315 -0
  189. data/vendor/listen/Rakefile +47 -0
  190. data/vendor/listen/Vagrantfile +96 -0
  191. data/vendor/listen/lib/listen/adapter.rb +214 -0
  192. data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
  193. data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
  194. data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
  195. data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
  196. data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
  197. data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
  198. data/vendor/listen/lib/listen/directory_record.rb +371 -0
  199. data/vendor/listen/lib/listen/listener.rb +225 -0
  200. data/vendor/listen/lib/listen/multi_listener.rb +143 -0
  201. data/vendor/listen/lib/listen/turnstile.rb +28 -0
  202. data/vendor/listen/lib/listen/version.rb +3 -0
  203. data/vendor/listen/lib/listen.rb +40 -0
  204. data/vendor/listen/listen.gemspec +22 -0
  205. data/vendor/listen/spec/listen/adapter_spec.rb +183 -0
  206. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  207. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
  208. data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
  209. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  210. data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
  211. data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
  212. data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
  213. data/vendor/listen/spec/listen/listener_spec.rb +169 -0
  214. data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
  215. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  216. data/vendor/listen/spec/listen_spec.rb +73 -0
  217. data/vendor/listen/spec/spec_helper.rb +21 -0
  218. data/vendor/listen/spec/support/adapter_helper.rb +629 -0
  219. data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
  220. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  221. data/vendor/listen/spec/support/listeners_helper.rb +156 -0
  222. data/vendor/listen/spec/support/platform_helper.rb +15 -0
  223. metadata +344 -271
  224. data/lib/sass/less.rb +0 -382
  225. data/lib/sass/script/bool.rb +0 -18
  226. data/lib/sass/script/funcall.rb +0 -162
  227. data/lib/sass/script/list.rb +0 -76
  228. data/lib/sass/script/literal.rb +0 -245
  229. data/lib/sass/script/variable.rb +0 -54
  230. data/lib/sass/scss/sass_parser.rb +0 -11
  231. data/test/sass/less_conversion_test.rb +0 -653
  232. data/vendor/fssm/README.markdown +0 -55
  233. data/vendor/fssm/Rakefile +0 -59
  234. data/vendor/fssm/VERSION.yml +0 -5
  235. data/vendor/fssm/example.rb +0 -9
  236. data/vendor/fssm/fssm.gemspec +0 -77
  237. data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  238. data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  239. data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  240. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  241. data/vendor/fssm/lib/fssm/monitor.rb +0 -26
  242. data/vendor/fssm/lib/fssm/path.rb +0 -91
  243. data/vendor/fssm/lib/fssm/pathname.rb +0 -502
  244. data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
  245. data/vendor/fssm/lib/fssm/state/file.rb +0 -24
  246. data/vendor/fssm/lib/fssm/support.rb +0 -63
  247. data/vendor/fssm/lib/fssm/tree.rb +0 -176
  248. data/vendor/fssm/lib/fssm.rb +0 -33
  249. data/vendor/fssm/profile/prof-cache.rb +0 -40
  250. data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  251. data/vendor/fssm/profile/prof-pathname.rb +0 -68
  252. data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  253. data/vendor/fssm/profile/prof.html +0 -2379
  254. data/vendor/fssm/spec/path_spec.rb +0 -75
  255. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  256. data/vendor/fssm/spec/root/file.css +0 -0
  257. data/vendor/fssm/spec/root/file.rb +0 -0
  258. data/vendor/fssm/spec/root/file.yml +0 -0
  259. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  260. data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -1,6 +1,4 @@
1
- require 'sass/script/literal'
2
-
3
- module Sass::Script
1
+ module Sass::Script::Value
4
2
  # A SassScript object representing a number.
5
3
  # SassScript numbers can have decimal values,
6
4
  # and can also have units.
@@ -9,7 +7,7 @@ module Sass::Script
9
7
  #
10
8
  # Numbers can also have more complex units, such as `1px*em/in`.
11
9
  # These cannot be inputted directly in Sass code at the moment.
12
- class Number < Literal
10
+ class Number < Base
13
11
  # The Ruby value of the number.
14
12
  #
15
13
  # @return [Numeric]
@@ -17,7 +15,7 @@ module Sass::Script
17
15
 
18
16
  # A list of units in the numerator of the number.
19
17
  # For example, `1px*em/in*cm` would return `["px", "em"]`
20
- # @return [Array<String>]
18
+ # @return [Array<String>]
21
19
  attr_reader :numerator_units
22
20
 
23
21
  # A list of units in the denominator of the number.
@@ -35,19 +33,33 @@ module Sass::Script
35
33
  # @return [Boolean, nil]
36
34
  attr_accessor :original
37
35
 
38
- # The precision with which numbers will be printed to CSS files.
39
- # For example, if this is `1000.0`,
36
+ def self.precision
37
+ @precision ||= 5
38
+ end
39
+
40
+ # Sets the number of digits of precision
41
+ # For example, if this is `3`,
40
42
  # `3.1415926` will be printed as `3.142`.
41
- # @api public
42
- PRECISION = 1000.0
43
+ def self.precision=(digits)
44
+ @precision = digits.round
45
+ @precision_factor = 10.0**@precision
46
+ end
47
+
48
+ # the precision factor used in numeric output
49
+ # it is derived from the `precision` method.
50
+ def self.precision_factor
51
+ @precision_factor ||= 10.0**precision
52
+ end
43
53
 
44
54
  # Used so we don't allocate two new arrays for each new number.
45
55
  NO_UNITS = []
46
56
 
47
57
  # @param value [Numeric] The value of the number
48
- # @param numerator_units [Array<String>] See \{#numerator\_units}
49
- # @param denominator_units [Array<String>] See \{#denominator\_units}
58
+ # @param numerator_units [::String, Array<::String>] See \{#numerator\_units}
59
+ # @param denominator_units [::String, Array<::String>] See \{#denominator\_units}
50
60
  def initialize(value, numerator_units = NO_UNITS, denominator_units = NO_UNITS)
61
+ numerator_units = [numerator_units] if numerator_units.is_a?(::String)
62
+ denominator_units = [denominator_units] if denominator_units.is_a?(::String)
51
63
  super(value)
52
64
  @numerator_units = numerator_units
53
65
  @denominator_units = denominator_units
@@ -63,11 +75,11 @@ module Sass::Script
63
75
  # {Color}
64
76
  # : Adds this number to each of the RGB color channels.
65
77
  #
66
- # {Literal}
67
- # : See {Literal#plus}.
78
+ # {Value}
79
+ # : See {Value::Base#plus}.
68
80
  #
69
- # @param other [Literal] The right-hand side of the operator
70
- # @return [Literal] The result of the operation
81
+ # @param other [Value] The right-hand side of the operator
82
+ # @return [Value] The result of the operation
71
83
  # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
72
84
  def plus(other)
73
85
  if other.is_a? Number
@@ -85,11 +97,11 @@ module Sass::Script
85
97
  # {Number}
86
98
  # : Subtracts this number from the other, converting units if possible.
87
99
  #
88
- # {Literal}
89
- # : See {Literal#minus}.
100
+ # {Value}
101
+ # : See {Value::Base#minus}.
90
102
  #
91
- # @param other [Literal] The right-hand side of the operator
92
- # @return [Literal] The result of the operation
103
+ # @param other [Value] The right-hand side of the operator
104
+ # @return [Value] The result of the operation
93
105
  # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
94
106
  def minus(other)
95
107
  if other.is_a? Number
@@ -141,16 +153,16 @@ module Sass::Script
141
153
  # {Number}
142
154
  # : Divides this number by the other, converting units appropriately.
143
155
  #
144
- # {Literal}
145
- # : See {Literal#div}.
156
+ # {Value}
157
+ # : See {Value::Base#div}.
146
158
  #
147
- # @param other [Literal] The right-hand side of the operator
148
- # @return [Literal] The result of the operation
159
+ # @param other [Value] The right-hand side of the operator
160
+ # @return [Value] The result of the operation
149
161
  def div(other)
150
162
  if other.is_a? Number
151
163
  res = operate(other, :/)
152
- if self.original && other.original
153
- res.original = "#{self.original}/#{other.original}"
164
+ if original && other.original
165
+ res.original = "#{original}/#{other.original}"
154
166
  end
155
167
  res
156
168
  else
@@ -163,12 +175,9 @@ module Sass::Script
163
175
  # @param other [Number] The right-hand side of the operator
164
176
  # @return [Number] This number modulo the other
165
177
  # @raise [NoMethodError] if `other` is an invalid type
166
- # @raise [Sass::UnitConversionError] if `other` has any units
178
+ # @raise [Sass::UnitConversionError] if `other` has incompatible units
167
179
  def mod(other)
168
180
  if other.is_a?(Number)
169
- unless other.unitless?
170
- raise Sass::UnitConversionError.new("Cannot modulo by a number with units: #{other.inspect}.")
171
- end
172
181
  operate(other, :%)
173
182
  else
174
183
  raise NoMethodError.new(nil, :mod)
@@ -177,10 +186,10 @@ module Sass::Script
177
186
 
178
187
  # The SassScript `==` operation.
179
188
  #
180
- # @param other [Literal] The right-hand side of the operator
189
+ # @param other [Value] The right-hand side of the operator
181
190
  # @return [Boolean] Whether this number is equal to the other object
182
191
  def eq(other)
183
- return Sass::Script::Bool.new(false) unless other.is_a?(Sass::Script::Number)
192
+ return Bool::FALSE unless other.is_a?(Sass::Script::Value::Number)
184
193
  this = self
185
194
  begin
186
195
  if unitless?
@@ -189,10 +198,21 @@ module Sass::Script
189
198
  other = other.coerce(@numerator_units, @denominator_units)
190
199
  end
191
200
  rescue Sass::UnitConversionError
192
- return Sass::Script::Bool.new(false)
201
+ return Bool::FALSE
193
202
  end
203
+ Bool.new(this.value == other.value)
204
+ end
205
+
206
+ def hash
207
+ [value, numerator_units, denominator_units].hash
208
+ end
194
209
 
195
- Sass::Script::Bool.new(this.value == other.value)
210
+ # Hash-equality works differently than `==` equality for numbers.
211
+ # Hash-equality must be transitive, so it just compares the exact value,
212
+ # numerator units, and denominator units.
213
+ def eql?(other)
214
+ value == other.value && numerator_units == other.numerator_units &&
215
+ denominator_units == other.denominator_units
196
216
  end
197
217
 
198
218
  # The SassScript `>` operation.
@@ -252,7 +272,14 @@ module Sass::Script
252
272
  # @return [String] The representation
253
273
  def inspect(opts = {})
254
274
  value = self.class.round(self.value)
255
- unitless? ? value.to_s : "#{value}#{unit_str}"
275
+ str = value.to_s
276
+
277
+ # Ruby will occasionally print in scientific notation if the number is
278
+ # small enough. That's technically valid CSS, but it's not well-supported
279
+ # and confusing.
280
+ str = ("%0.#{self.class.precision}f" % value).gsub(/0*$/, '') if str.include?('e')
281
+
282
+ unitless? ? str : "#{str}#{unit_str}"
256
283
  end
257
284
  alias_method :to_sass, :inspect
258
285
 
@@ -260,7 +287,7 @@ module Sass::Script
260
287
  # @raise [Sass::SyntaxError] if the number isn't an integer
261
288
  def to_i
262
289
  super unless int?
263
- return value
290
+ value
264
291
  end
265
292
 
266
293
  # @return [Boolean] Whether or not this number is an integer.
@@ -273,6 +300,24 @@ module Sass::Script
273
300
  @numerator_units.empty? && @denominator_units.empty?
274
301
  end
275
302
 
303
+ # Checks whether the number has the numerator unit specified.
304
+ #
305
+ # @example
306
+ # number = Sass::Script::Value::Number.new(10, "px")
307
+ # number.is_unit?("px") => true
308
+ # number.is_unit?(nil) => false
309
+ #
310
+ # @param unit [::String, nil] The unit the number should have or nil if the number
311
+ # should be unitless.
312
+ # @see Number#unitless? The unitless? method may be more readable.
313
+ def is_unit?(unit)
314
+ if unit
315
+ denominator_units.size == 0 && numerator_units.size == 1 && numerator_units.first == unit
316
+ else
317
+ unitless?
318
+ end
319
+ end
320
+
276
321
  # @return [Boolean] Whether or not this number has units that can be represented in CSS
277
322
  # (that is, zero or one \{#numerator\_units}).
278
323
  def legal_units?
@@ -297,9 +342,9 @@ module Sass::Script
297
342
  # current units
298
343
  def coerce(num_units, den_units)
299
344
  Number.new(if unitless?
300
- self.value
345
+ value
301
346
  else
302
- self.value * coercion_factor(@numerator_units, num_units) /
347
+ value * coercion_factor(@numerator_units, num_units) /
303
348
  coercion_factor(@denominator_units, den_units)
304
349
  end, num_units, den_units)
305
350
  end
@@ -307,12 +352,10 @@ module Sass::Script
307
352
  # @param other [Number] A number to decide if it can be compared with this number.
308
353
  # @return [Boolean] Whether or not this number can be compared with the other.
309
354
  def comparable_to?(other)
310
- begin
311
- operate(other, :+)
312
- true
313
- rescue Sass::UnitConversionError
314
- false
315
- end
355
+ operate(other, :+)
356
+ true
357
+ rescue Sass::UnitConversionError
358
+ false
316
359
  end
317
360
 
318
361
  # Returns a human readable representation of the units in this number.
@@ -337,11 +380,11 @@ module Sass::Script
337
380
  elsif num % 1 == 0.0
338
381
  num.to_i
339
382
  else
340
- (num * PRECISION).round / PRECISION
383
+ ((num * precision_factor).round / precision_factor).to_f
341
384
  end
342
385
  end
343
386
 
344
- OPERATIONS = [:+, :-, :<=, :<, :>, :>=]
387
+ OPERATIONS = [:+, :-, :<=, :<, :>, :>=, :%]
345
388
 
346
389
  def operate(other, operation)
347
390
  this = self
@@ -353,7 +396,7 @@ module Sass::Script
353
396
  end
354
397
  end
355
398
  # avoid integer division
356
- value = (:/ == operation) ? this.value.to_f : this.value
399
+ value = :/ == operation ? this.value.to_f : this.value
357
400
  result = value.send(operation, other.value)
358
401
 
359
402
  if result.is_a?(Numeric)
@@ -368,29 +411,33 @@ module Sass::Script
368
411
  from_units, to_units = sans_common_units(from_units, to_units)
369
412
 
370
413
  if from_units.size != to_units.size || !convertable?(from_units | to_units)
371
- raise Sass::UnitConversionError.new("Incompatible units: '#{from_units.join('*')}' and '#{to_units.join('*')}'.")
414
+ raise Sass::UnitConversionError.new(
415
+ "Incompatible units: '#{from_units.join('*')}' and '#{to_units.join('*')}'.")
372
416
  end
373
417
 
374
- from_units.zip(to_units).inject(1) {|m,p| m * conversion_factor(p[0], p[1]) }
418
+ from_units.zip(to_units).inject(1) {|m, p| m * conversion_factor(p[0], p[1])}
375
419
  end
376
420
 
377
421
  def compute_units(this, other, operation)
378
422
  case operation
379
423
  when :*
380
- [this.numerator_units + other.numerator_units, this.denominator_units + other.denominator_units]
424
+ [this.numerator_units + other.numerator_units,
425
+ this.denominator_units + other.denominator_units]
381
426
  when :/
382
- [this.numerator_units + other.denominator_units, this.denominator_units + other.numerator_units]
383
- else
427
+ [this.numerator_units + other.denominator_units,
428
+ this.denominator_units + other.numerator_units]
429
+ else
384
430
  [this.numerator_units, this.denominator_units]
385
431
  end
386
432
  end
387
433
 
388
434
  def normalize!
389
435
  return if unitless?
390
- @numerator_units, @denominator_units = sans_common_units(@numerator_units, @denominator_units)
436
+ @numerator_units, @denominator_units =
437
+ sans_common_units(@numerator_units, @denominator_units)
391
438
 
392
439
  @denominator_units.each_with_index do |d, i|
393
- if convertable?(d) && (u = @numerator_units.detect(&method(:convertable?)))
440
+ if convertable?(d) && (u = @numerator_units.find(&method(:convertable?)))
394
441
  @value /= conversion_factor(d, u)
395
442
  @denominator_units.delete_at(i)
396
443
  @numerator_units.delete_at(@numerator_units.index(u))
@@ -399,12 +446,15 @@ module Sass::Script
399
446
  end
400
447
 
401
448
  # A hash of unit names to their index in the conversion table
402
- CONVERTABLE_UNITS = {"in" => 0, "cm" => 1, "pc" => 2, "mm" => 3, "pt" => 4}
403
- CONVERSION_TABLE = [[ 1, 2.54, 6, 25.4, 72 ], # in
404
- [ nil, 1, 2.36220473, 10, 28.3464567], # cm
405
- [ nil, nil, 1, 4.23333333, 12 ], # pc
406
- [ nil, nil, nil, 1, 2.83464567], # mm
407
- [ nil, nil, nil, nil, 1 ]] # pt
449
+ CONVERTABLE_UNITS = %w(in cm pc mm pt px).inject({}) {|m, v| m[v] = m.size; m}
450
+
451
+ # in cm pc mm pt px
452
+ CONVERSION_TABLE = [[1, 2.54, 6, 25.4, 72 , 96], # in
453
+ [nil, 1, 2.36220473, 10, 28.3464567, 37.795275591], # cm
454
+ [nil, nil, 1, 4.23333333, 12 , 16], # pc
455
+ [nil, nil, nil, 1, 2.83464567, 3.7795275591], # mm
456
+ [nil, nil, nil, nil, 1 , 1.3333333333], # pt
457
+ [nil, nil, nil, nil, nil , 1]] # px
408
458
 
409
459
  def conversion_factor(from_unit, to_unit)
410
460
  res = CONVERSION_TABLE[CONVERTABLE_UNITS[from_unit]][CONVERTABLE_UNITS[to_unit]]
@@ -419,11 +469,14 @@ module Sass::Script
419
469
  def sans_common_units(units1, units2)
420
470
  units2 = units2.dup
421
471
  # Can't just use -, because we want px*px to coerce properly to px*mm
422
- return units1.map do |u|
423
- next u unless j = units2.index(u)
472
+ units1 = units1.map do |u|
473
+ j = units2.index(u)
474
+ next u unless j
424
475
  units2.delete_at(j)
425
476
  nil
426
- end.compact, units2
477
+ end
478
+ units1.compact!
479
+ return units1, units2
427
480
  end
428
481
  end
429
482
  end
@@ -1,8 +1,6 @@
1
- require 'sass/script/literal'
2
-
3
- module Sass::Script
1
+ module Sass::Script::Value
4
2
  # A SassScript object representing a CSS string *or* a CSS identifier.
5
- class String < Literal
3
+ class String < Base
6
4
  # The Ruby value of the string.
7
5
  #
8
6
  # @return [String]
@@ -24,26 +22,26 @@ module Sass::Script
24
22
  @type = type
25
23
  end
26
24
 
27
- # @see Literal#plus
25
+ # @see Value#plus
28
26
  def plus(other)
29
- other_str = other.is_a?(Sass::Script::String) ? other.value : other.to_s
30
- Sass::Script::String.new(self.value + other_str, self.type)
27
+ other_str = other.is_a?(Sass::Script::Value::String) ? other.value : other.to_s
28
+ Sass::Script::Value::String.new(value + other_str, type)
31
29
  end
32
30
 
33
- # @see Node#to_s
31
+ # @see Value#to_s
34
32
  def to_s(opts = {})
35
33
  if @type == :identifier
36
- return @value.tr("\n", " ")
34
+ return @value.gsub(/\n\s*/, " ")
37
35
  end
38
36
 
39
37
  return "\"#{value.gsub('"', "\\\"")}\"" if opts[:quote] == %q{"}
40
38
  return "'#{value.gsub("'", "\\'")}'" if opts[:quote] == %q{'}
41
39
  return "\"#{value}\"" unless value.include?('"')
42
40
  return "'#{value}'" unless value.include?("'")
43
- "\"#{value.gsub('"', "\\\"")}\"" #'
41
+ "\"#{value.gsub('"', "\\\"")}\"" # '
44
42
  end
45
43
 
46
- # @see Node#to_sass
44
+ # @see Value#to_sass
47
45
  def to_sass(opts = {})
48
46
  to_s
49
47
  end
@@ -0,0 +1,12 @@
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/deprecated_false'
9
+ require 'sass/script/value/null'
10
+ require 'sass/script/value/list'
11
+ require 'sass/script/value/arg_list'
12
+ require 'sass/script/value/map'
data/lib/sass/script.rb CHANGED
@@ -1,10 +1,4 @@
1
- require 'strscan'
2
- require 'sass/script/node'
3
- require 'sass/script/variable'
4
- require 'sass/script/funcall'
5
- require 'sass/script/operation'
6
- require 'sass/script/literal'
7
- require 'sass/script/parser'
1
+ require 'sass/scss/rx'
8
2
 
9
3
  module Sass
10
4
  # SassScript is code that's embedded in Sass documents
@@ -13,7 +7,8 @@ module Sass
13
7
  # This module contains code that handles the parsing and evaluation of SassScript.
14
8
  module Script
15
9
  # The regular expression used to parse variables.
16
- MATCH = /^\$(#{Sass::SCSS::RX::IDENT})\s*:\s*(.+?)(!(?i:default))?$/
10
+ MATCH = /^\$(#{Sass::SCSS::RX::IDENT})\s*:\s*(.+?)
11
+ (!#{Sass::SCSS::RX::IDENT}(?:\s+!#{Sass::SCSS::RX::IDENT})*)?$/x
17
12
 
18
13
  # The regular expression used to validate variables without matching.
19
14
  VALIDATE = /^\$#{Sass::SCSS::RX::IDENT}$/
@@ -27,7 +22,7 @@ module Sass
27
22
  # Used for error reporting
28
23
  # @param options [{Symbol => Object}] An options hash;
29
24
  # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
30
- # @return [Script::Node] The root node of the parse tree
25
+ # @return [Script::Tree::Node] The root node of the parse tree
31
26
  def self.parse(value, line, offset, options = {})
32
27
  Parser.parse(value, line, offset, options)
33
28
  rescue Sass::SyntaxError => e
@@ -36,5 +31,36 @@ module Sass
36
31
  raise e
37
32
  end
38
33
 
34
+ require 'sass/script/functions'
35
+ require 'sass/script/parser'
36
+ require 'sass/script/tree'
37
+ require 'sass/script/value'
38
+
39
+ # @private
40
+ CONST_RENAMES = {
41
+ :Literal => Sass::Script::Value::Base,
42
+ :ArgList => Sass::Script::Value::ArgList,
43
+ :Bool => Sass::Script::Value::Bool,
44
+ :Color => Sass::Script::Value::Color,
45
+ :List => Sass::Script::Value::List,
46
+ :Null => Sass::Script::Value::Null,
47
+ :Number => Sass::Script::Value::Number,
48
+ :String => Sass::Script::Value::String,
49
+ :Node => Sass::Script::Tree::Node,
50
+ :Funcall => Sass::Script::Tree::Funcall,
51
+ :Interpolation => Sass::Script::Tree::Interpolation,
52
+ :Operation => Sass::Script::Tree::Operation,
53
+ :StringInterpolation => Sass::Script::Tree::StringInterpolation,
54
+ :UnaryOperation => Sass::Script::Tree::UnaryOperation,
55
+ :Variable => Sass::Script::Tree::Variable,
56
+ }
57
+
58
+ # @private
59
+ def self.const_missing(name)
60
+ klass = CONST_RENAMES[name]
61
+ super unless klass
62
+ CONST_RENAMES.each {|n, k| const_set(n, k)}
63
+ klass
64
+ end
39
65
  end
40
66
  end
@@ -7,21 +7,11 @@ module Sass
7
7
  # parent references, nested selectors, and so forth.
8
8
  # It does support all the same CSS hacks as the SCSS parser, though.
9
9
  class CssParser < StaticParser
10
- # Parse a selector, and return its value as a string.
11
- #
12
- # @return [String, nil] The parsed selector, or nil if no selector was parsed
13
- # @raise [Sass::SyntaxError] if there's a syntax error in the selector
14
- def parse_selector_string
15
- init_scanner!
16
- str {return unless selector}
17
- end
18
-
19
10
  private
20
11
 
12
+ def placeholder_selector; nil; end
21
13
  def parent_selector; nil; end
22
14
  def interpolation; nil; end
23
- def interp_string; tok(STRING); end
24
- def interp_ident(ident = IDENT); tok(ident); end
25
15
  def use_css_import?; true; end
26
16
 
27
17
  def block_child(context)
@@ -36,7 +26,7 @@ module Sass
36
26
  end
37
27
 
38
28
  def nested_properties!(node, space)
39
- expected('expression (e.g. 1px, bold)');
29
+ expected('expression (e.g. 1px, bold)')
40
30
  end
41
31
 
42
32
  @sass_script_parser = Class.new(Sass::Script::CssParser)