sass 3.2.0.alpha.96 → 3.2.0.alpha.99
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/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
|