sass 3.2.0.alpha.96 → 3.2.0.alpha.99
Sign up to get free protection for your applications and to get access to all the features.
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/lib/sass/engine.rb +2 -0
- data/lib/sass/scss/parser.rb +29 -16
- data/lib/sass/selector.rb +47 -0
- data/lib/sass/selector/abstract_sequence.rb +16 -0
- data/lib/sass/selector/comma_sequence.rb +9 -1
- data/lib/sass/selector/sequence.rb +24 -2
- data/lib/sass/selector/simple_sequence.rb +36 -5
- data/lib/sass/supports.rb +229 -0
- data/lib/sass/tree/media_node.rb +3 -0
- data/lib/sass/tree/node.rb +7 -0
- data/lib/sass/tree/supports_node.rb +51 -0
- data/lib/sass/tree/visitors/convert.rb +4 -0
- data/lib/sass/tree/visitors/cssize.rb +22 -13
- data/lib/sass/tree/visitors/deep_copy.rb +5 -0
- data/lib/sass/tree/visitors/perform.rb +6 -0
- data/lib/sass/tree/visitors/set_options.rb +5 -0
- data/lib/sass/tree/visitors/to_css.rb +4 -0
- data/test/sass/conversion_test.rb +22 -0
- data/test/sass/extend_test.rb +114 -569
- data/test/sass/scss/css_test.rb +9 -0
- data/test/sass/scss/scss_test.rb +35 -0
- metadata +6 -4
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
052db34a7f6d34fa0ed364f6c38923dedcd95cd6
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.0.alpha.
|
1
|
+
3.2.0.alpha.99
|
data/lib/sass/engine.rb
CHANGED
@@ -8,6 +8,7 @@ require 'sass/tree/comment_node'
|
|
8
8
|
require 'sass/tree/prop_node'
|
9
9
|
require 'sass/tree/directive_node'
|
10
10
|
require 'sass/tree/media_node'
|
11
|
+
require 'sass/tree/supports_node'
|
11
12
|
require 'sass/tree/css_import_node'
|
12
13
|
require 'sass/tree/variable_node'
|
13
14
|
require 'sass/tree/mixin_def_node'
|
@@ -41,6 +42,7 @@ require 'sass/error'
|
|
41
42
|
require 'sass/importers'
|
42
43
|
require 'sass/shared'
|
43
44
|
require 'sass/media'
|
45
|
+
require 'sass/supports'
|
44
46
|
|
45
47
|
module Sass
|
46
48
|
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -425,36 +425,50 @@ module Sass
|
|
425
425
|
|
426
426
|
# http://www.w3.org/TR/css3-conditional/
|
427
427
|
def supports_directive(name)
|
428
|
-
|
429
|
-
|
428
|
+
condition = expr!(:supports_condition)
|
429
|
+
node = node(Sass::Tree::SupportsNode.new(name, condition))
|
430
|
+
|
431
|
+
tok!(/\{/)
|
432
|
+
node.has_children = true
|
433
|
+
block_contents(node, :directive)
|
434
|
+
tok!(/\}/)
|
435
|
+
|
436
|
+
node
|
430
437
|
end
|
431
438
|
|
432
439
|
def supports_condition
|
433
|
-
supports_negation || supports_operator ||
|
440
|
+
supports_negation || supports_operator || supports_interpolation
|
434
441
|
end
|
435
442
|
|
436
443
|
def supports_negation
|
437
444
|
return unless tok(/not/i)
|
438
445
|
ss
|
439
|
-
expr!(:supports_condition_in_parens)
|
446
|
+
Sass::Supports::Negation.new(expr!(:supports_condition_in_parens))
|
440
447
|
end
|
441
448
|
|
442
449
|
def supports_operator
|
443
|
-
return unless supports_condition_in_parens
|
444
|
-
tok
|
450
|
+
return unless cond = supports_condition_in_parens
|
451
|
+
return cond unless op = tok(/and|or/i)
|
445
452
|
begin
|
446
453
|
ss
|
447
|
-
|
448
|
-
|
449
|
-
|
454
|
+
cond = Sass::Supports::Operator.new(
|
455
|
+
cond, expr!(:supports_condition_in_parens), op)
|
456
|
+
end while op = tok(/and|or/i)
|
457
|
+
cond
|
450
458
|
end
|
451
459
|
|
452
460
|
def supports_condition_in_parens
|
461
|
+
interp = supports_interpolation and return interp
|
453
462
|
return unless tok(/\(/); ss
|
454
|
-
if supports_condition
|
463
|
+
if cond = supports_condition
|
455
464
|
tok!(/\)/); ss
|
465
|
+
cond
|
456
466
|
else
|
457
|
-
|
467
|
+
name = sass_script(:parse)
|
468
|
+
tok!(/:/); ss
|
469
|
+
value = sass_script(:parse)
|
470
|
+
tok!(/\)/); ss
|
471
|
+
Sass::Supports::Declaration.new(name, value)
|
458
472
|
end
|
459
473
|
end
|
460
474
|
|
@@ -463,11 +477,10 @@ module Sass
|
|
463
477
|
supports_declaration_body
|
464
478
|
end
|
465
479
|
|
466
|
-
def
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
tok!(/\)/); ss
|
480
|
+
def supports_interpolation
|
481
|
+
return unless interp = interpolation
|
482
|
+
ss
|
483
|
+
Sass::Supports::Interpolation.new(interp)
|
471
484
|
end
|
472
485
|
|
473
486
|
def variable
|
data/lib/sass/selector.rb
CHANGED
@@ -18,6 +18,13 @@ module Sass
|
|
18
18
|
# Finally, {Simple} is the superclass of the simplest selectors,
|
19
19
|
# such as `.foo` or `#bar`.
|
20
20
|
module Selector
|
21
|
+
# The base used for calculating selector specificity. The spec says this
|
22
|
+
# should be "sufficiently high"; it's extremely unlikely that any single
|
23
|
+
# selector sequence will contain 1,000 simple selectors.
|
24
|
+
#
|
25
|
+
# @type [Fixnum]
|
26
|
+
SPECIFICITY_BASE = 1_000
|
27
|
+
|
21
28
|
# A parent-referencing selector (`&` in Sass).
|
22
29
|
# The function of this is to be replaced by the parent selector
|
23
30
|
# in the nested hierarchy.
|
@@ -52,6 +59,11 @@ module Sass
|
|
52
59
|
def to_a
|
53
60
|
[".", *@name]
|
54
61
|
end
|
62
|
+
|
63
|
+
# @see AbstractSequence#specificity
|
64
|
+
def specificity
|
65
|
+
SPECIFICITY_BASE
|
66
|
+
end
|
55
67
|
end
|
56
68
|
|
57
69
|
# An id selector (e.g. `#foo`).
|
@@ -79,6 +91,11 @@ module Sass
|
|
79
91
|
return if sels.any? {|sel2| sel2.is_a?(Id) && self.name != sel2.name}
|
80
92
|
super
|
81
93
|
end
|
94
|
+
|
95
|
+
# @see AbstractSequence#specificity
|
96
|
+
def specificity
|
97
|
+
SPECIFICITY_BASE**2
|
98
|
+
end
|
82
99
|
end
|
83
100
|
|
84
101
|
# A placeholder selector (e.g. `%foo`).
|
@@ -100,6 +117,11 @@ module Sass
|
|
100
117
|
def to_a
|
101
118
|
["%", *@name]
|
102
119
|
end
|
120
|
+
|
121
|
+
# @see AbstractSequence#specificity
|
122
|
+
def specificity
|
123
|
+
0
|
124
|
+
end
|
103
125
|
end
|
104
126
|
|
105
127
|
# A universal selector (`*` in CSS).
|
@@ -162,6 +184,11 @@ module Sass
|
|
162
184
|
return unless accept
|
163
185
|
[name == :universal ? Universal.new(ns) : Element.new(name, ns)] + sels[1..-1]
|
164
186
|
end
|
187
|
+
|
188
|
+
# @see AbstractSequence#specificity
|
189
|
+
def specificity
|
190
|
+
0
|
191
|
+
end
|
165
192
|
end
|
166
193
|
|
167
194
|
# An element selector (e.g. `h1`).
|
@@ -224,6 +251,11 @@ module Sass
|
|
224
251
|
return unless accept
|
225
252
|
[Element.new(name, ns)] + sels[1..-1]
|
226
253
|
end
|
254
|
+
|
255
|
+
# @see AbstractSequence#specificity
|
256
|
+
def specificity
|
257
|
+
1
|
258
|
+
end
|
227
259
|
end
|
228
260
|
|
229
261
|
# Selector interpolation (`#{}` in Sass).
|
@@ -296,6 +328,11 @@ module Sass
|
|
296
328
|
(res << @operator).concat @value if @value
|
297
329
|
res << "]"
|
298
330
|
end
|
331
|
+
|
332
|
+
# @see AbstractSequence#specificity
|
333
|
+
def specificity
|
334
|
+
SPECIFICITY_BASE
|
335
|
+
end
|
299
336
|
end
|
300
337
|
|
301
338
|
# A pseudoclass (e.g. `:visited`) or pseudoelement (e.g. `::first-line`) selector.
|
@@ -363,6 +400,11 @@ module Sass
|
|
363
400
|
return sels + [self] if final?
|
364
401
|
super
|
365
402
|
end
|
403
|
+
|
404
|
+
# @see AbstractSequence#specificity
|
405
|
+
def specificity
|
406
|
+
type == :class ? SPECIFICITY_BASE : 1
|
407
|
+
end
|
366
408
|
end
|
367
409
|
|
368
410
|
# A pseudoclass selector whose argument is itself a selector
|
@@ -389,6 +431,11 @@ module Sass
|
|
389
431
|
def to_a
|
390
432
|
[":", @name, "("] + @selector.to_a + [")"]
|
391
433
|
end
|
434
|
+
|
435
|
+
# @see AbstractSequence#specificity
|
436
|
+
def specificity
|
437
|
+
SPECIFICITY_BASE
|
438
|
+
end
|
392
439
|
end
|
393
440
|
end
|
394
441
|
end
|
@@ -73,6 +73,22 @@ module Sass
|
|
73
73
|
def to_s
|
74
74
|
to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
|
75
75
|
end
|
76
|
+
|
77
|
+
# Returns the specificity of the selector as an integer. The base is given
|
78
|
+
# by {Sass::Selector::SPECIFICITY_BASE}.
|
79
|
+
#
|
80
|
+
# @return [Fixnum]
|
81
|
+
def specificity
|
82
|
+
_specificity(members)
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
def _specificity(arr)
|
88
|
+
spec = 0
|
89
|
+
arr.map {|m| spec += m.is_a?(String) ? 0 : m.specificity}
|
90
|
+
spec
|
91
|
+
end
|
76
92
|
end
|
77
93
|
end
|
78
94
|
end
|
@@ -49,7 +49,15 @@ module Sass
|
|
49
49
|
# @return [CommaSequence] A copy of this selector,
|
50
50
|
# with extensions made according to `extends`
|
51
51
|
def do_extend(extends)
|
52
|
-
CommaSequence.new(members.map
|
52
|
+
CommaSequence.new(members.map do |seq|
|
53
|
+
extended = seq.do_extend(extends)
|
54
|
+
# First Law of Extend: the result of extending a selector should
|
55
|
+
# always contain the base selector.
|
56
|
+
#
|
57
|
+
# See https://github.com/nex3/sass/issues/324.
|
58
|
+
extended.unshift seq unless seq.has_placeholder? || extended.include?(seq)
|
59
|
+
extended
|
60
|
+
end.flatten)
|
53
61
|
end
|
54
62
|
|
55
63
|
# Returns a string representation of the sequence.
|
@@ -115,6 +115,15 @@ module Sass
|
|
115
115
|
members.map {|m| m.inspect}.join(" ")
|
116
116
|
end
|
117
117
|
|
118
|
+
# Add to the {SimpleSequence#sources} sets of the child simple sequences.
|
119
|
+
# This destructively modifies this sequence's members array, but not the
|
120
|
+
# child simple sequences.
|
121
|
+
#
|
122
|
+
# @param sources [Set<Sequence>]
|
123
|
+
def add_sources!(sources)
|
124
|
+
members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
|
125
|
+
end
|
126
|
+
|
118
127
|
private
|
119
128
|
|
120
129
|
# Conceptually, this expands "parenthesized selectors".
|
@@ -430,9 +439,16 @@ module Sass
|
|
430
439
|
# separate sequences should limit the quadratic behavior.
|
431
440
|
seqses.map do |seqs1|
|
432
441
|
seqs1.reject do |seq1|
|
442
|
+
min_spec = 0
|
443
|
+
_sources(seq1).map {|seq| min_spec += seq.specificity}
|
433
444
|
seqses.any? do |seqs2|
|
434
|
-
next if seqs1.
|
435
|
-
|
445
|
+
next if seqs1.equal?(seqs2)
|
446
|
+
# Second Law of Extend: the specificity of a generated selector
|
447
|
+
# should never be less than the specificity of the extending
|
448
|
+
# selector.
|
449
|
+
#
|
450
|
+
# See https://github.com/nex3/sass/issues/324.
|
451
|
+
seqs2.any? {|seq2| _specificity(seq2) >= min_spec && _superselector?(seq2, seq1)}
|
436
452
|
end
|
437
453
|
end
|
438
454
|
end
|
@@ -448,6 +464,12 @@ module Sass
|
|
448
464
|
|
449
465
|
private
|
450
466
|
|
467
|
+
def _sources(seq)
|
468
|
+
s = Set.new
|
469
|
+
seq.map {|sseq_or_op| s.merge sseq_or_op.sources if sseq_or_op.is_a?(SimpleSequence)}
|
470
|
+
s
|
471
|
+
end
|
472
|
+
|
451
473
|
def extended_not_expanded_to_s(extended_not_expanded)
|
452
474
|
extended_not_expanded.map do |choices|
|
453
475
|
choices = choices.map do |sel|
|
@@ -8,7 +8,23 @@ module Sass
|
|
8
8
|
# The array of individual selectors.
|
9
9
|
#
|
10
10
|
# @return [Array<Simple>]
|
11
|
-
|
11
|
+
attr_accessor :members
|
12
|
+
|
13
|
+
# The extending selectors that caused this selector sequence to be
|
14
|
+
# generated. For example:
|
15
|
+
#
|
16
|
+
# a.foo { ... }
|
17
|
+
# b.bar {@extend a}
|
18
|
+
# c.baz {@extend b}
|
19
|
+
#
|
20
|
+
# The generated selector `b.foo.bar` has `{b.bar}` as its `sources` set,
|
21
|
+
# and the generated selector `c.foo.bar.baz` has `{b.bar, c.baz}` as its
|
22
|
+
# `sources` set.
|
23
|
+
#
|
24
|
+
# This is populated during the {#do_extend} process.
|
25
|
+
#
|
26
|
+
# @return {Set<Sequence>}
|
27
|
+
attr_accessor :sources
|
12
28
|
|
13
29
|
# Returns the element or universal selector in this sequence,
|
14
30
|
# if it exists.
|
@@ -26,8 +42,10 @@ module Sass
|
|
26
42
|
end
|
27
43
|
|
28
44
|
# @param selectors [Array<Simple>] See \{#members}
|
29
|
-
|
45
|
+
# @param sources [Set<Sequence>]
|
46
|
+
def initialize(selectors, sources = Set.new)
|
30
47
|
@members = selectors
|
48
|
+
@sources = sources
|
31
49
|
end
|
32
50
|
|
33
51
|
# Resolves the {Parent} selectors within this selector
|
@@ -54,7 +72,7 @@ module Sass
|
|
54
72
|
# Non-destrucively extends this selector with the extensions specified in a hash
|
55
73
|
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
56
74
|
#
|
57
|
-
# @overload def do_extend(extends)
|
75
|
+
# @overload def do_extend(extends, sources)
|
58
76
|
# @param extends [{Selector::Simple => Selector::Sequence}]
|
59
77
|
# The extensions to perform on this selector
|
60
78
|
# @return [Array<Sequence>] A list of selectors generated
|
@@ -68,9 +86,10 @@ module Sass
|
|
68
86
|
|
69
87
|
self_without_sel = self.members - sels
|
70
88
|
next unless unified = seq.members.last.unify(self_without_sel)
|
71
|
-
|
89
|
+
new_seq = Sequence.new(seq.members[0...-1] + [unified])
|
90
|
+
new_seq.add_sources!(sources + [seq])
|
91
|
+
[sels, new_seq]
|
72
92
|
end.compact.map do |sels, seq|
|
73
|
-
seq = Sequence.new(seq)
|
74
93
|
seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
|
75
94
|
end.flatten.uniq
|
76
95
|
end
|
@@ -121,6 +140,18 @@ module Sass
|
|
121
140
|
members.map {|m| m.inspect}.join
|
122
141
|
end
|
123
142
|
|
143
|
+
# Return a copy of this simple sequence with `sources` merged into the
|
144
|
+
# {#sources} set.
|
145
|
+
#
|
146
|
+
# @param sources [Set<Sequence>]
|
147
|
+
# @return [SimpleSequence]
|
148
|
+
def with_more_sources(sources)
|
149
|
+
sseq = dup
|
150
|
+
sseq.members = members.dup
|
151
|
+
sseq.sources.merge sources
|
152
|
+
sseq
|
153
|
+
end
|
154
|
+
|
124
155
|
private
|
125
156
|
|
126
157
|
def _hash
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# A namespace for the `@supports` condition parse tree.
|
2
|
+
module Sass::Supports
|
3
|
+
# The abstract superclass of all Supports conditions.
|
4
|
+
class Condition
|
5
|
+
# Runs the SassScript in the supports condition.
|
6
|
+
#
|
7
|
+
# @param env [Sass::Environment] The environment in which to run the script.
|
8
|
+
def perform(environment); Sass::Util.abstract(self); end
|
9
|
+
|
10
|
+
# Returns the CSS for this condition.
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
def to_css; Sass::Util.abstract(self); end
|
14
|
+
|
15
|
+
# Returns the Sass/CSS code for this condition.
|
16
|
+
#
|
17
|
+
# @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}).
|
18
|
+
# @return [String]
|
19
|
+
def to_src(options); Sass::Util.abstract(self); end
|
20
|
+
|
21
|
+
# Returns a deep copy of this condition and all its children.
|
22
|
+
#
|
23
|
+
# @return [Condition]
|
24
|
+
def deep_copy; Sass::Util.abstract(self); end
|
25
|
+
|
26
|
+
# Sets the options hash for the script nodes in the supports condition.
|
27
|
+
#
|
28
|
+
# @param options [{Symbol => Object}] The options has to set.
|
29
|
+
def options=(options); Sass::Util.abstract(self); end
|
30
|
+
end
|
31
|
+
|
32
|
+
# An operator condition (e.g. `CONDITION1 and CONDITION2`).
|
33
|
+
class Operator < Condition
|
34
|
+
# The left-hand condition.
|
35
|
+
#
|
36
|
+
# @return [Sass::Supports::Condition]
|
37
|
+
attr_accessor :left
|
38
|
+
|
39
|
+
# The right-hand condition.
|
40
|
+
#
|
41
|
+
# @return [Sass::Supports::Condition]
|
42
|
+
attr_accessor :right
|
43
|
+
|
44
|
+
# The operator ("and" or "or").
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
attr_accessor :op
|
48
|
+
|
49
|
+
def initialize(left, right, op)
|
50
|
+
@left = left
|
51
|
+
@right = right
|
52
|
+
@op = op
|
53
|
+
end
|
54
|
+
|
55
|
+
def perform(env)
|
56
|
+
@left.perform(env)
|
57
|
+
@right.perform(env)
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_css
|
61
|
+
"#{left_parens @left.to_css} #{op} #{right_parens @right.to_css}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_src(options)
|
65
|
+
"#{left_parens @left.to_src(options)} #{op} #{right_parens @right.to_src(options)}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def deep_copy
|
69
|
+
copy = dup
|
70
|
+
copy.left = @left.deep_copy
|
71
|
+
copy.right = @right.deep_copy
|
72
|
+
copy
|
73
|
+
end
|
74
|
+
|
75
|
+
def options=(options)
|
76
|
+
@left.options = options
|
77
|
+
@right.options = options
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def left_parens(str)
|
83
|
+
return "(#{str})" if @left.is_a?(Negation)
|
84
|
+
return str
|
85
|
+
end
|
86
|
+
|
87
|
+
def right_parens(str)
|
88
|
+
return "(#{str})" if @right.is_a?(Negation) || @right.is_a?(Operator)
|
89
|
+
return str
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# A negation condition (`not CONDITION`).
|
94
|
+
class Negation < Condition
|
95
|
+
# The condition being negated.
|
96
|
+
#
|
97
|
+
# @return [Sass::Supports::Condition]
|
98
|
+
attr_accessor :condition
|
99
|
+
|
100
|
+
def initialize(condition)
|
101
|
+
@condition = condition
|
102
|
+
end
|
103
|
+
|
104
|
+
def perform(env)
|
105
|
+
@condition.perform(env)
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_css
|
109
|
+
"not #{parens @condition.to_css}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_src(options)
|
113
|
+
"not #{parens @condition.to_src(options)}"
|
114
|
+
end
|
115
|
+
|
116
|
+
def deep_copy
|
117
|
+
copy = dup
|
118
|
+
copy.condition = condition.deep_copy
|
119
|
+
copy
|
120
|
+
end
|
121
|
+
|
122
|
+
def options=(options)
|
123
|
+
condition.options = options
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def parens(str)
|
129
|
+
return "(#{str})" if @condition.is_a?(Negation) || @condition.is_a?(Operator)
|
130
|
+
return str
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# A declaration condition (e.g. `(feature: value)`).
|
135
|
+
class Declaration < Condition
|
136
|
+
# The feature name.
|
137
|
+
#
|
138
|
+
# @param [Sass::Script::Node]
|
139
|
+
attr_accessor :name
|
140
|
+
|
141
|
+
# The name of the feature after any SassScript has been resolved.
|
142
|
+
# Only set once \{Tree::Visitors::Perform} has been run.
|
143
|
+
#
|
144
|
+
# @return [String]
|
145
|
+
attr_accessor :resolved_name
|
146
|
+
|
147
|
+
# The feature value.
|
148
|
+
#
|
149
|
+
# @param [Sass::Script::Node]
|
150
|
+
attr_accessor :value
|
151
|
+
|
152
|
+
# The value of the feature after any SassScript has been resolved.
|
153
|
+
# Only set once \{Tree::Visitors::Perform} has been run.
|
154
|
+
#
|
155
|
+
# @return [String]
|
156
|
+
attr_accessor :resolved_value
|
157
|
+
|
158
|
+
def initialize(name, value)
|
159
|
+
@name = name
|
160
|
+
@value = value
|
161
|
+
end
|
162
|
+
|
163
|
+
def perform(env)
|
164
|
+
@resolved_name = name.perform(env)
|
165
|
+
@resolved_value = value.perform(env)
|
166
|
+
end
|
167
|
+
|
168
|
+
def to_css
|
169
|
+
"(#{@resolved_name}: #{@resolved_value})"
|
170
|
+
end
|
171
|
+
|
172
|
+
def to_src(options)
|
173
|
+
"(#{@name.to_sass(options)}: #{@value.to_sass(options)})"
|
174
|
+
end
|
175
|
+
|
176
|
+
def deep_copy
|
177
|
+
copy = dup
|
178
|
+
copy.name = @name.deep_copy
|
179
|
+
copy.value = @value.deep_copy
|
180
|
+
copy
|
181
|
+
end
|
182
|
+
|
183
|
+
def options=(options)
|
184
|
+
@name.options = options
|
185
|
+
@value.options = options
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# An interpolation condition (e.g. `#{$var}`).
|
190
|
+
class Interpolation < Condition
|
191
|
+
# The SassScript expression in the interpolation.
|
192
|
+
#
|
193
|
+
# @param [Sass::Script::Node]
|
194
|
+
attr_accessor :value
|
195
|
+
|
196
|
+
# The value of the expression after it's been resolved.
|
197
|
+
# Only set once \{Tree::Visitors::Perform} has been run.
|
198
|
+
#
|
199
|
+
# @return [String]
|
200
|
+
attr_accessor :resolved_value
|
201
|
+
|
202
|
+
def initialize(value)
|
203
|
+
@value = value
|
204
|
+
end
|
205
|
+
|
206
|
+
def perform(env)
|
207
|
+
val = value.perform(env)
|
208
|
+
@resolved_value = val.is_a?(Sass::Script::String) ? val.value : val.to_s
|
209
|
+
end
|
210
|
+
|
211
|
+
def to_css
|
212
|
+
@resolved_value
|
213
|
+
end
|
214
|
+
|
215
|
+
def to_src(options)
|
216
|
+
"\#{#{@value.to_sass(options)}}"
|
217
|
+
end
|
218
|
+
|
219
|
+
def deep_copy
|
220
|
+
copy = dup
|
221
|
+
copy.value = @value.deep_copy
|
222
|
+
copy
|
223
|
+
end
|
224
|
+
|
225
|
+
def options=(options)
|
226
|
+
@value.options = options
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|