sass 3.3.0.alpha.231 → 3.3.0.alpha.243
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.
- data/README.md +1 -1
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass/engine.rb +11 -7
- data/lib/sass/environment.rb +8 -0
- data/lib/sass/script/functions.rb +140 -17
- data/lib/sass/script/parser.rb +28 -5
- data/lib/sass/script/tree.rb +1 -0
- data/lib/sass/script/tree/map_literal.rb +64 -0
- data/lib/sass/script/value.rb +1 -0
- data/lib/sass/script/value/base.rb +29 -1
- data/lib/sass/script/value/color.rb +4 -0
- data/lib/sass/script/value/list.rb +27 -1
- data/lib/sass/script/value/map.rb +70 -0
- data/lib/sass/script/value/number.rb +12 -0
- data/lib/sass/scss/parser.rb +8 -2
- data/lib/sass/stack.rb +9 -0
- data/lib/sass/tree/each_node.rb +6 -6
- data/lib/sass/tree/rule_node.rb +1 -1
- data/lib/sass/tree/visitors/convert.rb +2 -1
- data/lib/sass/tree/visitors/perform.rb +19 -22
- data/lib/sass/tree/visitors/to_css.rb +1 -1
- data/test/sass/conversion_test.rb +10 -0
- data/test/sass/engine_test.rb +21 -0
- data/test/sass/functions_test.rb +126 -0
- data/test/sass/script_conversion_test.rb +16 -0
- data/test/sass/script_test.rb +41 -0
- data/test/sass/scss/scss_test.rb +25 -0
- metadata +11 -9
data/README.md
CHANGED
@@ -56,7 +56,7 @@ to `config.ru`.
|
|
56
56
|
Then any Sass files in `public/stylesheets/sass`
|
57
57
|
will be compiled into CSS files in `public/stylesheets` on every request.
|
58
58
|
|
59
|
-
To use Sass
|
59
|
+
To use Sass programmatically,
|
60
60
|
check out the [YARD documentation](http://sass-lang.com/docs/yardoc/).
|
61
61
|
|
62
62
|
## Formatting
|
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
01ca24be4a152901b7caffd7d3eeaf717dda29d4
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.3.0.alpha.
|
1
|
+
3.3.0.alpha.243
|
data/VERSION_DATE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
29 August 2013 23:26:16 GMT
|
data/lib/sass/engine.rb
CHANGED
@@ -874,21 +874,25 @@ WARNING
|
|
874
874
|
end
|
875
875
|
|
876
876
|
def parse_each(line, root, text)
|
877
|
-
|
877
|
+
vars, list_expr = text.scan(/^([^\s]+(?:\s*,\s*[^\s]+)*)\s+in\s+(.+)$/).first
|
878
878
|
|
879
|
-
if
|
879
|
+
if vars.nil? # scan failed, try to figure out why for error message
|
880
880
|
if text !~ /^[^\s]+/
|
881
881
|
expected = "variable name"
|
882
|
-
elsif text !~ /^[^\s]+\s+from\s+.+/
|
882
|
+
elsif text !~ /^[^\s]+(?:\s*,\s*[^\s]+)*[^\s]+\s+from\s+.+/
|
883
883
|
expected = "'in <expr>'"
|
884
884
|
end
|
885
|
-
raise SyntaxError.new("Invalid
|
885
|
+
raise SyntaxError.new("Invalid each directive '@each #{text}': expected #{expected}.")
|
886
|
+
end
|
887
|
+
|
888
|
+
vars = vars.split(',').map do |var|
|
889
|
+
var.strip!
|
890
|
+
raise SyntaxError.new("Invalid variable \"#{var}\".") unless var =~ Script::VALIDATE
|
891
|
+
var[1..-1]
|
886
892
|
end
|
887
|
-
raise SyntaxError.new("Invalid variable \"#{var}\".") unless var =~ Script::VALIDATE
|
888
893
|
|
889
|
-
var = var[1..-1]
|
890
894
|
parsed_list = parse_script(list_expr, :offset => line.offset + line.text.index(list_expr))
|
891
|
-
Tree::EachNode.new(
|
895
|
+
Tree::EachNode.new(vars, parsed_list)
|
892
896
|
end
|
893
897
|
|
894
898
|
def parse_else(parent, line, text)
|
data/lib/sass/environment.rb
CHANGED
@@ -28,6 +28,7 @@ module Sass
|
|
28
28
|
def initialize(parent = nil, options = nil)
|
29
29
|
@parent = parent
|
30
30
|
@options = options || (parent && parent.options) || {}
|
31
|
+
@stack = Sass::Stack.new if @parent.nil?
|
31
32
|
end
|
32
33
|
|
33
34
|
# The environment of the caller of this environment's mixin or function.
|
@@ -47,6 +48,13 @@ module Sass
|
|
47
48
|
@global_env ||= parent.nil? ? self : parent.global_env
|
48
49
|
end
|
49
50
|
|
51
|
+
# The import/mixin stack.
|
52
|
+
#
|
53
|
+
# @return [Sass::Stack]
|
54
|
+
def stack
|
55
|
+
@stack || global_env.stack
|
56
|
+
end
|
57
|
+
|
50
58
|
private
|
51
59
|
|
52
60
|
class << self
|
@@ -40,7 +40,7 @@ module Sass::Script
|
|
40
40
|
#
|
41
41
|
# \{#hsla hsla($hue, $saturation, $lightness, $alpha)}
|
42
42
|
# : Creates a {Sass::Script::Value::Color Color} from hue, saturation,
|
43
|
-
# lightness,
|
43
|
+
# lightness, and alpha values.
|
44
44
|
#
|
45
45
|
# \{#hue hue($color)}
|
46
46
|
# : Gets the hue component of a color.
|
@@ -154,6 +154,8 @@ module Sass::Script
|
|
154
154
|
#
|
155
155
|
# ## List Functions {#list-functions}
|
156
156
|
#
|
157
|
+
# All list functions work for maps as well, treating them as lists of pairs.
|
158
|
+
#
|
157
159
|
# \{#length length($list)}
|
158
160
|
# : Returns the length of a list.
|
159
161
|
#
|
@@ -175,6 +177,23 @@ module Sass::Script
|
|
175
177
|
# \{#list_separator list-separator(#list)}
|
176
178
|
# : Returns the separator of a list.
|
177
179
|
#
|
180
|
+
# ## Map Functions {#map-functions}
|
181
|
+
#
|
182
|
+
# \{#map_get map-get($map, $key)}
|
183
|
+
# : Returns the value in a map associated with a given key.
|
184
|
+
#
|
185
|
+
# \{#map_merge map-merge($map1, $map2)}
|
186
|
+
# : Merges two maps together into a new map.
|
187
|
+
#
|
188
|
+
# \{#map_keys map-keys($map)}
|
189
|
+
# : Returns a list of all keys in a map.
|
190
|
+
#
|
191
|
+
# \{#map_values map-values($map)}
|
192
|
+
# : Returns a list of all values in a map.
|
193
|
+
#
|
194
|
+
# \{#map_has_key map-has-key($key)}
|
195
|
+
# : Returns whether a map has a value associated with a given key.
|
196
|
+
#
|
178
197
|
# ## Introspection Functions
|
179
198
|
#
|
180
199
|
# \{#feature_exists feature-exists($feature)}
|
@@ -348,8 +367,7 @@ module Sass::Script
|
|
348
367
|
class EvaluationContext
|
349
368
|
include Functions
|
350
369
|
|
351
|
-
|
352
|
-
# The environment of the {Sass::Engine}
|
370
|
+
# The global environment.
|
353
371
|
#
|
354
372
|
# @return [Environment]
|
355
373
|
attr_reader :environment
|
@@ -380,7 +398,9 @@ module Sass::Script
|
|
380
398
|
# @param name [String, Symbol, nil] The name of the argument.
|
381
399
|
# @raise [ArgumentError] if value is not of the correct type.
|
382
400
|
def assert_type(value, type, name = nil)
|
383
|
-
|
401
|
+
klass = Sass::Script::Value.const_get(type)
|
402
|
+
return if value.is_a?(klass)
|
403
|
+
return if value.is_a?(Sass::Script::Value::List) && type == :Map && value.is_pseudo_map?
|
384
404
|
err = "#{value.inspect} is not a #{type.to_s.downcase}"
|
385
405
|
err = "$#{name.to_s.gsub('_', '-')}: " + err if name
|
386
406
|
raise ArgumentError.new(err)
|
@@ -552,9 +572,9 @@ module Sass::Script
|
|
552
572
|
end
|
553
573
|
declare :hsl, [:hue, :saturation, :lightness]
|
554
574
|
|
555
|
-
# Creates a {Sass::Script::Value::Color Color} from hue,
|
556
|
-
#
|
557
|
-
# spec][].
|
575
|
+
# Creates a {Sass::Script::Value::Color Color} from hue,
|
576
|
+
# saturation, lightness, and alpha values. Uses the algorithm from
|
577
|
+
# the [CSS3 spec][].
|
558
578
|
#
|
559
579
|
# [CSS3 spec]: http://www.w3.org/TR/css3-color/#hsl-color
|
560
580
|
#
|
@@ -1561,9 +1581,12 @@ module Sass::Script
|
|
1561
1581
|
|
1562
1582
|
# Return the length of a list.
|
1563
1583
|
#
|
1584
|
+
# This can return the number of pairs in a map as well.
|
1585
|
+
#
|
1564
1586
|
# @example
|
1565
1587
|
# length(10px) => 1
|
1566
1588
|
# length(10px 20px 30px) => 3
|
1589
|
+
# length((width: 10px, height: 20px)) => 2
|
1567
1590
|
# @overload length($list)
|
1568
1591
|
# @param $list [Sass::Script::Value::Base]
|
1569
1592
|
# @return [Sass::Script::Value::Number]
|
@@ -1577,9 +1600,12 @@ module Sass::Script
|
|
1577
1600
|
# Note that unlike some languages, the first item in a Sass list is number
|
1578
1601
|
# 1, the second number 2, and so forth.
|
1579
1602
|
#
|
1603
|
+
# This can return the nth pair in a map as well.
|
1604
|
+
#
|
1580
1605
|
# @example
|
1581
1606
|
# nth(10px 20px 30px, 1) => 10px
|
1582
1607
|
# nth((Helvetica, Arial, sans-serif), 3) => sans-serif
|
1608
|
+
# nth((width: 10px, length: 20px), 2) => length, 20px
|
1583
1609
|
# @overload nth($list, $n)
|
1584
1610
|
# @param $list [Sass::Script::Value::Base]
|
1585
1611
|
# @param $n [Sass::Script::Value::Number] The index of the item to get.
|
@@ -1627,12 +1653,10 @@ module Sass::Script
|
|
1627
1653
|
unless %w[auto space comma].include?(separator.value)
|
1628
1654
|
raise ArgumentError.new("Separator name must be space, comma, or auto")
|
1629
1655
|
end
|
1630
|
-
sep1 = list1.separator if list1.is_a?(Sass::Script::Value::List) && !list1.value.empty?
|
1631
|
-
sep2 = list2.separator if list2.is_a?(Sass::Script::Value::List) && !list2.value.empty?
|
1632
1656
|
Sass::Script::Value::List.new(
|
1633
1657
|
list1.to_a + list2.to_a,
|
1634
1658
|
if separator.value == 'auto'
|
1635
|
-
|
1659
|
+
list1.separator || list2.separator || :space
|
1636
1660
|
else
|
1637
1661
|
separator.value.to_sym
|
1638
1662
|
end)
|
@@ -1663,11 +1687,10 @@ module Sass::Script
|
|
1663
1687
|
unless %w[auto space comma].include?(separator.value)
|
1664
1688
|
raise ArgumentError.new("Separator name must be space, comma, or auto")
|
1665
1689
|
end
|
1666
|
-
sep = list.separator if list.is_a?(Sass::Script::Value::List)
|
1667
1690
|
Sass::Script::Value::List.new(
|
1668
1691
|
list.to_a + [val],
|
1669
1692
|
if separator.value == 'auto'
|
1670
|
-
|
1693
|
+
list.separator || :space
|
1671
1694
|
else
|
1672
1695
|
separator.value.to_sym
|
1673
1696
|
end)
|
@@ -1711,9 +1734,12 @@ module Sass::Script
|
|
1711
1734
|
# Note that unlike some languages, the first item in a Sass list is number
|
1712
1735
|
# 1, the second number 2, and so forth.
|
1713
1736
|
#
|
1737
|
+
# This can return the position of a pair in a map as well.
|
1738
|
+
#
|
1714
1739
|
# @example
|
1715
1740
|
# index(1px solid red, solid) => 2
|
1716
1741
|
# index(1px solid red, dashed) => false
|
1742
|
+
# index((width: 10px, height: 20px), (height, 20px)) => 2
|
1717
1743
|
# @overload index($list, $value)
|
1718
1744
|
# @param $list [Sass::Script::Value::Base]
|
1719
1745
|
# @param $value [Sass::Script::Value::Base]
|
@@ -1740,14 +1766,99 @@ module Sass::Script
|
|
1740
1766
|
# @param $list [Sass::Script::Value::Base]
|
1741
1767
|
# @return [Sass::Script::Value::String] `comma` or `space`
|
1742
1768
|
def list_separator(list)
|
1743
|
-
|
1744
|
-
Sass::Script::Value::String.new(list.separator.to_s)
|
1745
|
-
else
|
1746
|
-
Sass::Script::Value::String.new('space')
|
1747
|
-
end
|
1769
|
+
Sass::Script::Value::String.new((list.separator || :space).to_s)
|
1748
1770
|
end
|
1749
1771
|
declare :separator, [:list]
|
1750
1772
|
|
1773
|
+
# Returns the value in a map associated with the given key. If the map
|
1774
|
+
# doesn't have such a key, returns `null`.
|
1775
|
+
#
|
1776
|
+
# @example
|
1777
|
+
# map-get(("foo": 1, "bar": 2), "foo") => 1
|
1778
|
+
# map-get(("foo": 1, "bar": 2), "bar") => 2
|
1779
|
+
# map-get(("foo": 1, "bar": 2), "baz") => null
|
1780
|
+
# @overload map_get($map, $key)
|
1781
|
+
# @param $map [Sass::Script::Value::Map]
|
1782
|
+
# @param $key [Sass::Script::Value::Base]
|
1783
|
+
# @return [Sass::Script::Value::Base] The value indexed by `$key`, or `null`
|
1784
|
+
# if the map doesn't contain the given key
|
1785
|
+
# @raise [ArgumentError] if `$map` is not a map
|
1786
|
+
def map_get(map, key)
|
1787
|
+
assert_type map, :Map
|
1788
|
+
to_h(map)[key] || Sass::Script::Value::Null.new
|
1789
|
+
end
|
1790
|
+
declare :map_get, [:map, :key]
|
1791
|
+
|
1792
|
+
# Merges two maps together into a new map. Keys in `$map2` will take
|
1793
|
+
# precedence over keys in `$map1`.
|
1794
|
+
#
|
1795
|
+
# This is the best way to add new values to a map.
|
1796
|
+
#
|
1797
|
+
# All keys in the returned map that also appear in `$map1` will have the
|
1798
|
+
# same order as in `$map1`. New keys from `$map2` will be placed at the end
|
1799
|
+
# of the map.
|
1800
|
+
#
|
1801
|
+
# @example
|
1802
|
+
# map-merge(("foo": 1), ("bar": 2)) => ("foo": 1, "bar": 2)
|
1803
|
+
# map-merge(("foo": 1, "bar": 2), ("bar": 3)) => ("foo": 1, "bar": 3)
|
1804
|
+
# @overload map_merge($map1, $map2)
|
1805
|
+
# @param $map1 [Sass::Script::Value::Map]
|
1806
|
+
# @param $map2 [Sass::Script::Value::Map]
|
1807
|
+
# @return [Sass::Script::Value::Map]
|
1808
|
+
# @raise [ArgumentError] if either parameter is not a map
|
1809
|
+
def map_merge(map1, map2)
|
1810
|
+
assert_type map1, :Map
|
1811
|
+
assert_type map2, :Map
|
1812
|
+
Sass::Script::Value::Map.new(to_h(map1).merge(to_h(map2)))
|
1813
|
+
end
|
1814
|
+
declare :map_get, [:map1, :map2]
|
1815
|
+
|
1816
|
+
# Returns a list of all keys in a map.
|
1817
|
+
#
|
1818
|
+
# @example
|
1819
|
+
# map-keys(("foo": 1, "bar": 2)) => "foo", "bar"
|
1820
|
+
# @overload map_keys($map)
|
1821
|
+
# @param $map [Map]
|
1822
|
+
# @return [List] the list of keys, comma-separated
|
1823
|
+
# @raise [ArgumentError] if `$map` is not a map
|
1824
|
+
def map_keys(map)
|
1825
|
+
assert_type map, :Map
|
1826
|
+
Sass::Script::Value::List.new(to_h(map).keys, :comma)
|
1827
|
+
end
|
1828
|
+
declare :map_keys, [:map]
|
1829
|
+
|
1830
|
+
# Returns a list of all values in a map. This list may include duplicate
|
1831
|
+
# values, if multiple keys have the same value.
|
1832
|
+
#
|
1833
|
+
# @example
|
1834
|
+
# map-keys(("foo": 1, "bar": 2)) => 1, 2
|
1835
|
+
# map-keys(("foo": 1, "bar": 2, "baz": 1)) => 1, 2, 1
|
1836
|
+
# @overload map_values($map)
|
1837
|
+
# @param $map [Map]
|
1838
|
+
# @return [List] the list of values, comma-separated
|
1839
|
+
# @raise [ArgumentError] if `$map` is not a map
|
1840
|
+
def map_values(map)
|
1841
|
+
assert_type map, :Map
|
1842
|
+
Sass::Script::Value::List.new(to_h(map).values, :comma)
|
1843
|
+
end
|
1844
|
+
declare :map_values, [:map]
|
1845
|
+
|
1846
|
+
# Returns whether a map has a value associated with a given key.
|
1847
|
+
#
|
1848
|
+
# @example
|
1849
|
+
# map-has-key(("foo": 1, "bar": 2), "foo") => true
|
1850
|
+
# map-has-key(("foo": 1, "bar": 2), "baz") => false
|
1851
|
+
# @overload map_has_key($map, $key)
|
1852
|
+
# @param $map [Sass::Script::Value::Map]
|
1853
|
+
# @param $key [Sass::Script::Value::Base]
|
1854
|
+
# @return [Sass::Script::Value::Bool]
|
1855
|
+
# @raise [ArgumentError] if `$map` is not a map
|
1856
|
+
def map_has_key(map, key)
|
1857
|
+
assert_type map, :Map
|
1858
|
+
Sass::Script::Value::Bool.new(to_h(map).has_key?(key))
|
1859
|
+
end
|
1860
|
+
declare :map_has_key, [:map, :key]
|
1861
|
+
|
1751
1862
|
# Returns one of two values, depending on whether or not `$condition` is
|
1752
1863
|
# true. Just like in `@if`, all values other than `false` and `null` are
|
1753
1864
|
# considered to be true.
|
@@ -1847,5 +1958,17 @@ module Sass::Script
|
|
1847
1958
|
color.with(attr => Sass::Util.restrict(
|
1848
1959
|
color.send(attr).send(op, amount.value), range))
|
1849
1960
|
end
|
1961
|
+
|
1962
|
+
def to_h(obj)
|
1963
|
+
return obj.to_h unless obj.is_a?(Sass::Script::Value::List) && obj.needs_map_warning?
|
1964
|
+
|
1965
|
+
fn_name = Sass::Util.caller_info.last.gsub('_', '-')
|
1966
|
+
Sass::Util.sass_warn <<WARNING + environment.stack.to_s.gsub(/^/, ' ')
|
1967
|
+
DEPRECATION WARNING: Passing lists of pairs to #{fn_name} is deprecated and will
|
1968
|
+
be removed in future versions of Sass. Use Sass maps instead. For details, see
|
1969
|
+
http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#maps.
|
1970
|
+
WARNING
|
1971
|
+
return obj.to_h
|
1972
|
+
end
|
1850
1973
|
end
|
1851
1974
|
end
|
data/lib/sass/script/parser.rb
CHANGED
@@ -253,11 +253,34 @@ RUBY
|
|
253
253
|
# @private
|
254
254
|
def lexer_class; Lexer; end
|
255
255
|
|
256
|
+
def map
|
257
|
+
start_pos = source_position
|
258
|
+
return unless e = interpolation
|
259
|
+
return list e, start_pos unless @lexer.peek && @lexer.peek.type == :colon
|
260
|
+
|
261
|
+
key, value = map_pair(e)
|
262
|
+
map = node(Sass::Script::Tree::MapLiteral.new([[key, value]]), start_pos)
|
263
|
+
while tok = try_tok(:comma)
|
264
|
+
key, value = assert_expr(:map_pair)
|
265
|
+
map.pairs << [key, value]
|
266
|
+
end
|
267
|
+
map
|
268
|
+
end
|
269
|
+
|
270
|
+
def map_pair(key=nil)
|
271
|
+
return unless key ||= interpolation
|
272
|
+
assert_tok :colon
|
273
|
+
return key, assert_expr(:interpolation)
|
274
|
+
end
|
275
|
+
|
256
276
|
def expr
|
257
|
-
interp = try_ops_after_interp([:comma], :expr) and return interp
|
258
277
|
start_pos = source_position
|
259
278
|
return unless e = interpolation
|
260
|
-
list
|
279
|
+
list e, start_pos
|
280
|
+
end
|
281
|
+
|
282
|
+
def list(first, start_pos)
|
283
|
+
list = node(Sass::Script::Tree::ListLiteral.new([first], :comma), start_pos)
|
261
284
|
while tok = try_tok(:comma)
|
262
285
|
if interp = try_op_before_interp(tok, list)
|
263
286
|
return interp unless other_interp = try_ops_after_interp([:comma], :expr, interp)
|
@@ -447,10 +470,10 @@ RUBY
|
|
447
470
|
was_in_parens = @in_parens
|
448
471
|
@in_parens = true
|
449
472
|
start_pos = source_position
|
450
|
-
e =
|
473
|
+
e = map
|
451
474
|
end_pos = source_position
|
452
475
|
assert_tok(:rparen)
|
453
|
-
return e || node(Sass::Script::Tree::ListLiteral.new([],
|
476
|
+
return e || node(Sass::Script::Tree::ListLiteral.new([], nil), start_pos, end_pos)
|
454
477
|
ensure
|
455
478
|
@in_parens = was_in_parens
|
456
479
|
end
|
@@ -502,7 +525,7 @@ RUBY
|
|
502
525
|
end
|
503
526
|
|
504
527
|
def try_tok(*names)
|
505
|
-
peeked =
|
528
|
+
peeked = @lexer.peek
|
506
529
|
peeked && names.include?(peeked.type) && @lexer.next
|
507
530
|
end
|
508
531
|
|
data/lib/sass/script/tree.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Sass::Script::Tree
|
2
|
+
# A class representing a map literal. When resolved, this returns a
|
3
|
+
# {Sass::Script::Node::Map}.
|
4
|
+
class MapLiteral < Node
|
5
|
+
# The key/value pairs that make up this map node. This isn't a Hash so that
|
6
|
+
# we can detect key collisions once all the keys have been performed.
|
7
|
+
#
|
8
|
+
# @return [Array<(Node, Node)>]
|
9
|
+
attr_reader :pairs
|
10
|
+
|
11
|
+
# Creates a new map literal.
|
12
|
+
#
|
13
|
+
# @param pairs [Array<(Node, Node)>] See \{#pairs}
|
14
|
+
def initialize(pairs)
|
15
|
+
@pairs = pairs
|
16
|
+
end
|
17
|
+
|
18
|
+
# @see Node#children
|
19
|
+
def children
|
20
|
+
@pairs.flatten
|
21
|
+
end
|
22
|
+
|
23
|
+
# @see Node#to_sass
|
24
|
+
def to_sass(opts = {})
|
25
|
+
return "()" if pairs.empty?
|
26
|
+
|
27
|
+
to_sass = lambda do |value|
|
28
|
+
if value.is_a?(ListLiteral) && value.separator == :comma
|
29
|
+
"(#{value.to_sass(opts)})"
|
30
|
+
else
|
31
|
+
value.to_sass(opts)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
"(" + pairs.map {|(k, v)| "#{to_sass[k]}: #{to_sass[v]}"}.join(', ') + ")"
|
36
|
+
end
|
37
|
+
alias_method :inspect, :to_sass
|
38
|
+
|
39
|
+
# @see Node#deep_copy
|
40
|
+
def deep_copy
|
41
|
+
node = dup
|
42
|
+
node.instance_variable_set('@pairs',
|
43
|
+
pairs.map {|(k, v)| [k.deep_copy, v.deep_copy]})
|
44
|
+
node
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
# @see Node#_perform
|
50
|
+
def _perform(environment)
|
51
|
+
keys = Set.new
|
52
|
+
map = Sass::Script::Value::Map.new(Sass::Util.to_hash(pairs.map do |(k, v)|
|
53
|
+
k, v = k.perform(environment), v.perform(environment)
|
54
|
+
if keys.include?(k)
|
55
|
+
raise Sass::SyntaxError.new("Duplicate key #{k.inspect} in map #{to_sass}.")
|
56
|
+
end
|
57
|
+
keys << k
|
58
|
+
[k, v]
|
59
|
+
end))
|
60
|
+
map.options = self.options
|
61
|
+
map
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|