oreorenasass 3.4.4 → 3.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +50 -70
- data/Rakefile +5 -26
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/bin/sass +1 -1
- data/bin/scss +1 -1
- data/lib/sass.rb +12 -19
- data/lib/sass/cache_stores/base.rb +2 -2
- data/lib/sass/cache_stores/chain.rb +1 -2
- data/lib/sass/cache_stores/filesystem.rb +5 -1
- data/lib/sass/cache_stores/memory.rb +1 -1
- data/lib/sass/cache_stores/null.rb +2 -2
- data/lib/sass/callbacks.rb +0 -1
- data/lib/sass/css.rb +13 -11
- data/lib/sass/engine.rb +173 -424
- data/lib/sass/environment.rb +58 -148
- data/lib/sass/error.rb +14 -11
- data/lib/sass/exec.rb +703 -5
- data/lib/sass/importers/base.rb +6 -49
- data/lib/sass/importers/filesystem.rb +19 -44
- data/lib/sass/logger.rb +4 -1
- data/lib/sass/logger/base.rb +4 -2
- data/lib/sass/logger/log_level.rb +7 -3
- data/lib/sass/media.rb +23 -20
- data/lib/sass/plugin.rb +7 -7
- data/lib/sass/plugin/compiler.rb +145 -304
- data/lib/sass/plugin/configuration.rb +23 -18
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +3 -3
- data/lib/sass/repl.rb +3 -3
- data/lib/sass/script.rb +8 -35
- data/lib/sass/script/{value/arg_list.rb → arg_list.rb} +25 -9
- data/lib/sass/script/bool.rb +18 -0
- data/lib/sass/script/color.rb +606 -0
- data/lib/sass/script/css_lexer.rb +4 -8
- data/lib/sass/script/css_parser.rb +2 -5
- data/lib/sass/script/funcall.rb +245 -0
- data/lib/sass/script/functions.rb +408 -1491
- data/lib/sass/script/interpolation.rb +79 -0
- data/lib/sass/script/lexer.rb +68 -172
- data/lib/sass/script/list.rb +85 -0
- data/lib/sass/script/literal.rb +221 -0
- data/lib/sass/script/{tree/node.rb → node.rb} +12 -22
- data/lib/sass/script/{value/null.rb → null.rb} +7 -14
- data/lib/sass/script/{value/number.rb → number.rb} +75 -152
- data/lib/sass/script/{tree/operation.rb → operation.rb} +24 -17
- data/lib/sass/script/parser.rb +110 -245
- data/lib/sass/script/string.rb +51 -0
- data/lib/sass/script/{tree/string_interpolation.rb → string_interpolation.rb} +4 -5
- data/lib/sass/script/{tree/unary_operation.rb → unary_operation.rb} +6 -6
- data/lib/sass/script/variable.rb +58 -0
- data/lib/sass/scss/css_parser.rb +3 -9
- data/lib/sass/scss/parser.rb +421 -450
- data/lib/sass/scss/rx.rb +11 -19
- data/lib/sass/scss/static_parser.rb +7 -321
- data/lib/sass/selector.rb +194 -68
- data/lib/sass/selector/abstract_sequence.rb +14 -29
- data/lib/sass/selector/comma_sequence.rb +25 -108
- data/lib/sass/selector/sequence.rb +66 -159
- data/lib/sass/selector/simple.rb +25 -23
- data/lib/sass/selector/simple_sequence.rb +63 -173
- data/lib/sass/shared.rb +1 -1
- data/lib/sass/supports.rb +15 -13
- data/lib/sass/tree/charset_node.rb +1 -1
- data/lib/sass/tree/comment_node.rb +3 -3
- data/lib/sass/tree/css_import_node.rb +11 -11
- data/lib/sass/tree/debug_node.rb +2 -2
- data/lib/sass/tree/directive_node.rb +4 -21
- data/lib/sass/tree/each_node.rb +8 -8
- data/lib/sass/tree/extend_node.rb +7 -14
- data/lib/sass/tree/for_node.rb +4 -4
- data/lib/sass/tree/function_node.rb +4 -9
- data/lib/sass/tree/if_node.rb +1 -1
- data/lib/sass/tree/import_node.rb +5 -4
- data/lib/sass/tree/media_node.rb +14 -4
- data/lib/sass/tree/mixin_def_node.rb +4 -4
- data/lib/sass/tree/mixin_node.rb +8 -21
- data/lib/sass/tree/node.rb +12 -54
- data/lib/sass/tree/prop_node.rb +20 -39
- data/lib/sass/tree/return_node.rb +2 -3
- data/lib/sass/tree/root_node.rb +3 -19
- data/lib/sass/tree/rule_node.rb +22 -35
- data/lib/sass/tree/supports_node.rb +13 -0
- data/lib/sass/tree/trace_node.rb +1 -2
- data/lib/sass/tree/variable_node.rb +3 -9
- data/lib/sass/tree/visitors/base.rb +8 -5
- data/lib/sass/tree/visitors/check_nesting.rb +19 -49
- data/lib/sass/tree/visitors/convert.rb +56 -74
- data/lib/sass/tree/visitors/cssize.rb +74 -202
- data/lib/sass/tree/visitors/deep_copy.rb +5 -10
- data/lib/sass/tree/visitors/extend.rb +7 -7
- data/lib/sass/tree/visitors/perform.rb +185 -278
- data/lib/sass/tree/visitors/set_options.rb +6 -20
- data/lib/sass/tree/visitors/to_css.rb +81 -234
- data/lib/sass/tree/warn_node.rb +2 -2
- data/lib/sass/tree/while_node.rb +2 -2
- data/lib/sass/util.rb +152 -522
- data/lib/sass/util/multibyte_string_scanner.rb +0 -2
- data/lib/sass/util/subset_map.rb +3 -4
- data/lib/sass/util/test.rb +1 -0
- data/lib/sass/version.rb +22 -20
- data/test/Gemfile +3 -0
- data/test/Gemfile.lock +10 -0
- data/test/sass/cache_test.rb +20 -62
- data/test/sass/callbacks_test.rb +1 -1
- data/test/sass/conversion_test.rb +2 -296
- data/test/sass/css2sass_test.rb +4 -23
- data/test/sass/engine_test.rb +354 -411
- data/test/sass/exec_test.rb +2 -2
- data/test/sass/extend_test.rb +145 -324
- data/test/sass/functions_test.rb +86 -873
- data/test/sass/importer_test.rb +21 -241
- data/test/sass/logger_test.rb +1 -1
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/plugin_test.rb +26 -16
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +4 -4
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +1 -1
- data/test/sass/results/import_charset_ibm866.css +2 -2
- data/test/sass/results/mixins.css +17 -17
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +2 -2
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +1 -1
- data/test/sass/script_conversion_test.rb +7 -36
- data/test/sass/script_test.rb +53 -485
- data/test/sass/scss/css_test.rb +28 -143
- data/test/sass/scss/rx_test.rb +4 -4
- data/test/sass/scss/scss_test.rb +325 -2119
- data/test/sass/templates/scss_import.scss +1 -2
- data/test/sass/test_helper.rb +1 -1
- data/test/sass/util/multibyte_string_scanner_test.rb +1 -1
- data/test/sass/util/subset_map_test.rb +2 -2
- data/test/sass/util_test.rb +1 -86
- data/test/test_helper.rb +8 -37
- metadata +19 -66
- data/lib/sass/exec/base.rb +0 -187
- data/lib/sass/exec/sass_convert.rb +0 -264
- data/lib/sass/exec/sass_scss.rb +0 -424
- data/lib/sass/features.rb +0 -47
- data/lib/sass/script/tree.rb +0 -16
- data/lib/sass/script/tree/funcall.rb +0 -306
- data/lib/sass/script/tree/interpolation.rb +0 -118
- data/lib/sass/script/tree/list_literal.rb +0 -77
- data/lib/sass/script/tree/literal.rb +0 -45
- data/lib/sass/script/tree/map_literal.rb +0 -64
- data/lib/sass/script/tree/selector.rb +0 -26
- data/lib/sass/script/tree/variable.rb +0 -57
- data/lib/sass/script/value.rb +0 -11
- data/lib/sass/script/value/base.rb +0 -240
- data/lib/sass/script/value/bool.rb +0 -35
- data/lib/sass/script/value/color.rb +0 -680
- data/lib/sass/script/value/helpers.rb +0 -262
- data/lib/sass/script/value/list.rb +0 -113
- data/lib/sass/script/value/map.rb +0 -70
- data/lib/sass/script/value/string.rb +0 -97
- data/lib/sass/selector/pseudo.rb +0 -256
- data/lib/sass/source/map.rb +0 -210
- data/lib/sass/source/position.rb +0 -39
- data/lib/sass/source/range.rb +0 -41
- data/lib/sass/stack.rb +0 -120
- data/lib/sass/tree/at_root_node.rb +0 -83
- data/lib/sass/tree/error_node.rb +0 -18
- data/lib/sass/tree/keyframe_rule_node.rb +0 -15
- data/lib/sass/util/cross_platform_random.rb +0 -19
- data/lib/sass/util/normalized_map.rb +0 -130
- data/lib/sass/util/ordered_hash.rb +0 -192
- data/test/sass/compiler_test.rb +0 -232
- data/test/sass/encoding_test.rb +0 -219
- data/test/sass/source_map_test.rb +0 -977
- data/test/sass/superselector_test.rb +0 -191
- data/test/sass/util/normalized_map_test.rb +0 -51
- data/test/sass/value_helpers_test.rb +0 -179
data/lib/sass/selector/simple.rb
CHANGED
@@ -14,18 +14,29 @@ module Sass
|
|
14
14
|
# @return [String, nil]
|
15
15
|
attr_accessor :filename
|
16
16
|
|
17
|
-
#
|
17
|
+
# Returns a representation of the node
|
18
|
+
# as an array of strings and potentially {Sass::Script::Node}s
|
19
|
+
# (if there's interpolation in the selector).
|
20
|
+
# When the interpolation is resolved and the strings are joined together,
|
21
|
+
# this will be the string representation of this node.
|
22
|
+
#
|
23
|
+
# @return [Array<String, Sass::Script::Node>]
|
24
|
+
def to_a
|
25
|
+
Sass::Util.abstract(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns a string representation of the node.
|
29
|
+
# This is basically the selector string.
|
18
30
|
#
|
19
31
|
# @return [String]
|
20
32
|
def inspect
|
21
|
-
|
33
|
+
to_a.map {|e| e.is_a?(Sass::Script::Node) ? "\#{#{e.to_sass}}" : e}.join
|
22
34
|
end
|
23
35
|
|
24
|
-
#
|
25
|
-
#
|
36
|
+
# @see \{#inspect}
|
26
37
|
# @return [String]
|
27
38
|
def to_s
|
28
|
-
|
39
|
+
inspect
|
29
40
|
end
|
30
41
|
|
31
42
|
# Returns a hash code for this selector object.
|
@@ -36,7 +47,7 @@ module Sass
|
|
36
47
|
#
|
37
48
|
# @return [Fixnum]
|
38
49
|
def hash
|
39
|
-
@_hash ||=
|
50
|
+
@_hash ||= to_a.hash
|
40
51
|
end
|
41
52
|
|
42
53
|
# Checks equality between this and another object.
|
@@ -48,7 +59,7 @@ module Sass
|
|
48
59
|
# @param other [Object] The object to test equality against
|
49
60
|
# @return [Boolean] Whether or not this is equal to `other`
|
50
61
|
def eql?(other)
|
51
|
-
other.class == self.class && other.hash == hash && other.
|
62
|
+
other.class == self.class && other.hash == self.hash && other.to_a.eql?(to_a)
|
52
63
|
end
|
53
64
|
alias_method :==, :eql?
|
54
65
|
|
@@ -73,26 +84,17 @@ module Sass
|
|
73
84
|
return sels if sels.any? {|sel2| eql?(sel2)}
|
74
85
|
sels_with_ix = Sass::Util.enum_with_index(sels)
|
75
86
|
_, i =
|
76
|
-
if is_a?(Pseudo)
|
87
|
+
if self.is_a?(Pseudo) || self.is_a?(SelectorPseudoClass)
|
77
88
|
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) && (sels.last.type == :element)}
|
78
89
|
else
|
79
|
-
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo)}
|
90
|
+
sels_with_ix.find {|sel, _| sel.is_a?(Pseudo) || sel.is_a?(SelectorPseudoClass)}
|
80
91
|
end
|
81
92
|
return sels + [self] unless i
|
82
|
-
sels[0...i] + [self] + sels[i..-1]
|
93
|
+
return sels[0...i] + [self] + sels[i..-1]
|
83
94
|
end
|
84
95
|
|
85
96
|
protected
|
86
97
|
|
87
|
-
# Returns the key used for testing whether selectors are equal.
|
88
|
-
#
|
89
|
-
# This is a cached version of \{#to\_s}.
|
90
|
-
#
|
91
|
-
# @return [String]
|
92
|
-
def equality_key
|
93
|
-
@equality_key ||= to_s
|
94
|
-
end
|
95
|
-
|
96
98
|
# Unifies two namespaces,
|
97
99
|
# returning a namespace that works for both of them if possible.
|
98
100
|
#
|
@@ -107,10 +109,10 @@ module Sass
|
|
107
109
|
# could be found at all.
|
108
110
|
# If the second value is `false`, the first should be ignored.
|
109
111
|
def unify_namespaces(ns1, ns2)
|
110
|
-
return nil, false unless ns1 == ns2 || ns1.nil? || ns1 == '*' || ns2.nil? || ns2 == '*'
|
111
|
-
return ns2, true if ns1 == '*'
|
112
|
-
return ns1, true if ns2 == '*'
|
113
|
-
|
112
|
+
return nil, false unless ns1 == ns2 || ns1.nil? || ns1 == ['*'] || ns2.nil? || ns2 == ['*']
|
113
|
+
return ns2, true if ns1 == ['*']
|
114
|
+
return ns1, true if ns2 == ['*']
|
115
|
+
return ns1 || ns2, true
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|
@@ -21,16 +21,11 @@ module Sass
|
|
21
21
|
# and the generated selector `c.foo.bar.baz` has `{b.bar, c.baz}` as its
|
22
22
|
# `sources` set.
|
23
23
|
#
|
24
|
-
# This is populated during the {
|
24
|
+
# This is populated during the {#do_extend} process.
|
25
25
|
#
|
26
26
|
# @return {Set<Sequence>}
|
27
27
|
attr_accessor :sources
|
28
28
|
|
29
|
-
# This sequence source range.
|
30
|
-
#
|
31
|
-
# @return [Sass::Source::Range]
|
32
|
-
attr_accessor :source_range
|
33
|
-
|
34
29
|
# @see \{#subject?}
|
35
30
|
attr_writer :subject
|
36
31
|
|
@@ -43,16 +38,11 @@ module Sass
|
|
43
38
|
end
|
44
39
|
|
45
40
|
def pseudo_elements
|
46
|
-
@pseudo_elements ||= members
|
47
|
-
|
48
|
-
|
49
|
-
def selector_pseudo_classes
|
50
|
-
@selector_pseudo_classes ||= members.
|
51
|
-
select {|sel| sel.is_a?(Pseudo) && sel.type == :class && sel.selector}.
|
52
|
-
group_by {|sel| sel.normalized_name}
|
41
|
+
@pseudo_elements ||= (members - [base]).
|
42
|
+
select {|sel| sel.is_a?(Pseudo) && sel.type == :element}
|
53
43
|
end
|
54
44
|
|
55
|
-
# Returns the non-base, non-pseudo-
|
45
|
+
# Returns the non-base, non-pseudo-class selectors in this sequence.
|
56
46
|
#
|
57
47
|
# @return [Set<Simple>]
|
58
48
|
def rest
|
@@ -70,143 +60,74 @@ module Sass
|
|
70
60
|
|
71
61
|
# @param selectors [Array<Simple>] See \{#members}
|
72
62
|
# @param subject [Boolean] See \{#subject?}
|
73
|
-
# @param
|
74
|
-
def initialize(selectors, subject,
|
63
|
+
# @param sources [Set<Sequence>]
|
64
|
+
def initialize(selectors, subject, sources = Set.new)
|
75
65
|
@members = selectors
|
76
66
|
@subject = subject
|
77
|
-
@sources =
|
78
|
-
@source_range = source_range
|
67
|
+
@sources = sources
|
79
68
|
end
|
80
69
|
|
81
70
|
# Resolves the {Parent} selectors within this selector
|
82
71
|
# by replacing them with the given parent selector,
|
83
72
|
# handling commas appropriately.
|
84
73
|
#
|
85
|
-
# @param
|
86
|
-
# @return [
|
74
|
+
# @param super_seq [Sequence] The parent selector sequence
|
75
|
+
# @return [Array<SimpleSequence>] This selector, with parent references resolved.
|
76
|
+
# This is an array because the parent selector is itself a {Sequence}
|
87
77
|
# @raise [Sass::SyntaxError] If a parent selector is invalid
|
88
|
-
def resolve_parent_refs(
|
78
|
+
def resolve_parent_refs(super_seq)
|
89
79
|
# Parent selector only appears as the first selector in the sequence
|
90
|
-
|
91
|
-
return CommaSequence.new([Sequence.new([self])])
|
92
|
-
end
|
80
|
+
return [self] unless @members.first.is_a?(Parent)
|
93
81
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
|
101
|
-
super_seq.to_s + '"')
|
102
|
-
end
|
103
|
-
|
104
|
-
parent_sub = members.last.members
|
105
|
-
unless parent.suffix.nil?
|
106
|
-
parent_sub = parent_sub.dup
|
107
|
-
parent_sub[-1] = parent_sub.last.dup
|
108
|
-
case parent_sub.last
|
109
|
-
when Sass::Selector::Class, Sass::Selector::Id, Sass::Selector::Placeholder
|
110
|
-
parent_sub[-1] = parent_sub.last.class.new(parent_sub.last.name + parent.suffix)
|
111
|
-
when Sass::Selector::Element
|
112
|
-
parent_sub[-1] = parent_sub.last.class.new(
|
113
|
-
parent_sub.last.name + parent.suffix,
|
114
|
-
parent_sub.last.namespace)
|
115
|
-
when Sass::Selector::Pseudo
|
116
|
-
if parent_sub.last.arg || parent_sub.last.selector
|
117
|
-
raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
|
118
|
-
super_seq.to_s + '"')
|
119
|
-
end
|
120
|
-
parent_sub[-1] = Sass::Selector::Pseudo.new(
|
121
|
-
parent_sub.last.type,
|
122
|
-
parent_sub.last.name + parent.suffix,
|
123
|
-
nil, nil)
|
124
|
-
else
|
125
|
-
raise Sass::SyntaxError.new("Invalid parent selector for \"#{self}\": \"" +
|
126
|
-
super_seq.to_s + '"')
|
127
|
-
end
|
128
|
-
end
|
82
|
+
members = super_seq.members.dup
|
83
|
+
newline = members.pop if members.last == "\n"
|
84
|
+
return members if @members.size == 1
|
85
|
+
unless members.last.is_a?(SimpleSequence)
|
86
|
+
raise Sass::SyntaxError.new("Invalid parent selector: " + super_seq.to_a.join)
|
87
|
+
end
|
129
88
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end)
|
89
|
+
members[0...-1] +
|
90
|
+
[SimpleSequence.new(members.last.members + @members[1..-1], subject?)] +
|
91
|
+
[newline].compact
|
134
92
|
end
|
135
93
|
|
136
|
-
# Non-
|
94
|
+
# Non-destrucively extends this selector with the extensions specified in a hash
|
137
95
|
# (which should come from {Sass::Tree::Visitors::Cssize}).
|
138
96
|
#
|
97
|
+
# @overload def do_extend(extends, parent_directives)
|
139
98
|
# @param extends [{Selector::Simple =>
|
140
99
|
# Sass::Tree::Visitors::Cssize::Extend}]
|
141
100
|
# The extensions to perform on this selector
|
142
101
|
# @param parent_directives [Array<Sass::Tree::DirectiveNode>]
|
143
102
|
# The directives containing this selector.
|
144
|
-
# @param seen [Set<Array<Selector::Simple>>]
|
145
|
-
# The set of simple sequences that are currently being replaced.
|
146
|
-
# @param original [Boolean]
|
147
|
-
# Whether this is the original selector being extended, as opposed to
|
148
|
-
# the result of a previous extension that's being re-extended.
|
149
103
|
# @return [Array<Sequence>] A list of selectors generated
|
150
104
|
# by extending this selector with `extends`.
|
151
105
|
# @see CommaSequence#do_extend
|
152
|
-
def do_extend(extends, parent_directives,
|
153
|
-
|
154
|
-
|
155
|
-
modified_original = false
|
156
|
-
members = Sass::Util.enum_with_index(self.members).map do |sel, i|
|
157
|
-
next sel unless sel.is_a?(Pseudo) && sel.selector
|
158
|
-
next sel if seen.include?([sel])
|
159
|
-
extended = sel.selector.do_extend(extends, parent_directives, replace, seen, !:original)
|
160
|
-
next sel if extended == sel.selector
|
161
|
-
extended.members.reject! {|seq| seq.has_placeholder?}
|
162
|
-
modified_original = true
|
163
|
-
result = sel.with_selector(extended)
|
164
|
-
seen_with_pseudo_selectors << [result]
|
165
|
-
result
|
166
|
-
end
|
167
|
-
|
168
|
-
groups = Sass::Util.group_by_to_a(extends[members.to_set]) {|ex| ex.extender}
|
169
|
-
groups.map! do |seq, group|
|
170
|
-
sels = group.map {|e| e.target}.flatten
|
106
|
+
def do_extend(extends, parent_directives, seen = Set.new)
|
107
|
+
Sass::Util.group_by_to_a(extends.get(members.to_set)) {|ex, _| ex.extender}.map do |seq, group|
|
108
|
+
sels = group.map {|_, s| s}.flatten
|
171
109
|
# If A {@extend B} and C {...},
|
172
110
|
# seq is A, sels is B, and self is C
|
173
111
|
|
174
|
-
self_without_sel = Sass::Util.array_minus(members, sels)
|
175
|
-
group.each {|e| e.result = :failed_to_unify unless e.result == :succeeded}
|
176
|
-
unified = seq.members.last.unify(
|
177
|
-
|
178
|
-
group.
|
179
|
-
group.each {|e| check_directives_match!(e, parent_directives)}
|
112
|
+
self_without_sel = Sass::Util.array_minus(self.members, sels)
|
113
|
+
group.each {|e, _| e.result = :failed_to_unify unless e.result == :succeeded}
|
114
|
+
next unless unified = seq.members.last.unify(self_without_sel, subject?)
|
115
|
+
group.each {|e, _| e.result = :succeeded}
|
116
|
+
next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
|
180
117
|
new_seq = Sequence.new(seq.members[0...-1] + [unified])
|
181
118
|
new_seq.add_sources!(sources + [seq])
|
182
119
|
[sels, new_seq]
|
183
|
-
end
|
184
|
-
|
185
|
-
|
186
|
-
next [] if seen.include?(sels)
|
187
|
-
seq.do_extend(
|
188
|
-
extends, parent_directives, !:replace, seen_with_pseudo_selectors + [sels], !:original)
|
189
|
-
end
|
190
|
-
groups.flatten!
|
191
|
-
|
192
|
-
if modified_original || !replace || groups.empty?
|
193
|
-
# First Law of Extend: the result of extending a selector should
|
194
|
-
# (almost) always contain the base selector.
|
195
|
-
#
|
196
|
-
# See https://github.com/nex3/sass/issues/324.
|
197
|
-
original = Sequence.new([SimpleSequence.new(members, @subject, source_range)])
|
198
|
-
original.add_sources! sources
|
199
|
-
groups.unshift original
|
200
|
-
end
|
201
|
-
groups.uniq!
|
202
|
-
groups
|
120
|
+
end.compact.map do |sels, seq|
|
121
|
+
seen.include?(sels) ? [] : seq.do_extend(extends, parent_directives, seen + [sels])
|
122
|
+
end.flatten.uniq
|
203
123
|
end
|
204
124
|
|
205
|
-
# Unifies this selector with another {SimpleSequence},
|
206
|
-
# another `SimpleSequence`
|
207
|
-
#
|
125
|
+
# Unifies this selector with another {SimpleSequence}'s {SimpleSequence#members members array},
|
126
|
+
# returning another `SimpleSequence`
|
127
|
+
# that matches both this selector and the input selector.
|
208
128
|
#
|
209
|
-
# @param
|
129
|
+
# @param sels [Array<Simple>] A {SimpleSequence}'s {SimpleSequence#members members array}
|
130
|
+
# @param subject [Boolean] Whether the {SimpleSequence} being merged is a subject.
|
210
131
|
# @return [SimpleSequence, nil] A {SimpleSequence} matching both `sels` and this selector,
|
211
132
|
# or `nil` if this is impossible (e.g. unifying `#foo` and `#bar`)
|
212
133
|
# @raise [Sass::SyntaxError] If this selector cannot be unified.
|
@@ -215,13 +136,12 @@ module Sass
|
|
215
136
|
# Since these selectors should be resolved
|
216
137
|
# by the time extension and unification happen,
|
217
138
|
# this exception will only ever be raised as a result of programmer error
|
218
|
-
def unify(
|
219
|
-
sseq = members.inject(
|
139
|
+
def unify(sels, other_subject)
|
140
|
+
return unless sseq = members.inject(sels) do |member, sel|
|
220
141
|
return unless member
|
221
142
|
sel.unify(member)
|
222
143
|
end
|
223
|
-
|
224
|
-
SimpleSequence.new(sseq, other.subject? || subject?)
|
144
|
+
SimpleSequence.new(sseq, other_subject || subject?)
|
225
145
|
end
|
226
146
|
|
227
147
|
# Returns whether or not this selector matches all elements
|
@@ -230,44 +150,17 @@ module Sass
|
|
230
150
|
# @example
|
231
151
|
# (.foo).superselector?(.foo.bar) #=> true
|
232
152
|
# (.foo).superselector?(.bar) #=> false
|
233
|
-
# @param
|
234
|
-
# @param parents [Array<SimpleSequence, String>] The parent selectors of `their_sseq`, if any.
|
153
|
+
# @param sseq [SimpleSequence]
|
235
154
|
# @return [Boolean]
|
236
|
-
def superselector?(
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
their_spcs = their_sseq.selector_pseudo_classes
|
241
|
-
|
242
|
-
# Some psuedo-selectors can be subselectors of non-pseudo selectors.
|
243
|
-
# Pull those out here so we can efficiently check against them below.
|
244
|
-
their_subselector_pseudos = %w[matches any nth-child nth-last-child].
|
245
|
-
map {|name| their_spcs[name] || []}.flatten
|
246
|
-
|
247
|
-
# If `self`'s non-pseudo simple selectors aren't a subset of `their_sseq`'s,
|
248
|
-
# it's definitely not a superselector. This also considers being matched
|
249
|
-
# by `:matches` or `:any`.
|
250
|
-
return false unless rest.all? do |our_sel|
|
251
|
-
next true if our_sel.is_a?(Pseudo) && our_sel.selector
|
252
|
-
next true if their_sseq.rest.include?(our_sel)
|
253
|
-
their_subselector_pseudos.any? do |their_pseudo|
|
254
|
-
their_pseudo.selector.members.all? do |their_seq|
|
255
|
-
next false unless their_seq.members.length == 1
|
256
|
-
their_sseq = their_seq.members.first
|
257
|
-
next false unless their_sseq.is_a?(SimpleSequence)
|
258
|
-
their_sseq.rest.include?(our_sel)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
our_spcs.all? do |name, pseudos|
|
264
|
-
pseudos.all? {|pseudo| pseudo.superselector?(their_sseq, parents)}
|
265
|
-
end
|
155
|
+
def superselector?(sseq)
|
156
|
+
(base.nil? || base.eql?(sseq.base)) &&
|
157
|
+
pseudo_elements.eql?(sseq.pseudo_elements) &&
|
158
|
+
rest.subset?(sseq.rest)
|
266
159
|
end
|
267
160
|
|
268
|
-
# @see Simple#
|
269
|
-
def
|
270
|
-
res = @members.
|
161
|
+
# @see Simple#to_a
|
162
|
+
def to_a
|
163
|
+
res = @members.map {|sel| sel.to_a}.flatten
|
271
164
|
res << '!' if subject?
|
272
165
|
res
|
273
166
|
end
|
@@ -277,13 +170,11 @@ module Sass
|
|
277
170
|
#
|
278
171
|
# @return [String]
|
279
172
|
def inspect
|
280
|
-
|
281
|
-
res << '!' if subject?
|
282
|
-
res
|
173
|
+
members.map {|m| m.inspect}.join
|
283
174
|
end
|
284
175
|
|
285
176
|
# Return a copy of this simple sequence with `sources` merged into the
|
286
|
-
# {
|
177
|
+
# {#sources} set.
|
287
178
|
#
|
288
179
|
# @param sources [Set<Sequence>]
|
289
180
|
# @return [SimpleSequence]
|
@@ -299,17 +190,16 @@ module Sass
|
|
299
190
|
def check_directives_match!(extend, parent_directives)
|
300
191
|
dirs1 = extend.directives.map {|d| d.resolved_value}
|
301
192
|
dirs2 = parent_directives.map {|d| d.resolved_value}
|
302
|
-
return if Sass::Util.subsequence?(dirs1, dirs2)
|
303
|
-
line = extend.node.line
|
304
|
-
filename = extend.node.filename
|
193
|
+
return true if Sass::Util.subsequence?(dirs1, dirs2)
|
305
194
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
You may
|
310
|
-
|
311
|
-
|
312
|
-
|
195
|
+
Sass::Util.sass_warn <<WARNING
|
196
|
+
DEPRECATION WARNING on line #{extend.node.line}#{" of #{extend.node.filename}" if extend.node.filename}:
|
197
|
+
@extending an outer selector from within #{extend.directives.last.name} is deprecated.
|
198
|
+
You may only @extend selectors within the same directive.
|
199
|
+
This will be an error in Sass 3.3.
|
200
|
+
It can only work once @extend is supported natively in the browser.
|
201
|
+
WARNING
|
202
|
+
return false
|
313
203
|
end
|
314
204
|
|
315
205
|
def _hash
|
@@ -317,8 +207,8 @@ MESSAGE
|
|
317
207
|
end
|
318
208
|
|
319
209
|
def _eql?(other)
|
320
|
-
other.base.eql?(base) && other.pseudo_elements == pseudo_elements &&
|
321
|
-
Sass::Util.set_eql?(other.rest, rest) && other.subject? == subject?
|
210
|
+
other.base.eql?(self.base) && other.pseudo_elements == pseudo_elements &&
|
211
|
+
Sass::Util.set_eql?(other.rest, self.rest) && other.subject? == self.subject?
|
322
212
|
end
|
323
213
|
end
|
324
214
|
end
|
data/lib/sass/shared.rb
CHANGED
data/lib/sass/supports.rb
CHANGED
@@ -4,7 +4,7 @@ module Sass::Supports
|
|
4
4
|
class Condition
|
5
5
|
# Runs the SassScript in the supports condition.
|
6
6
|
#
|
7
|
-
# @param
|
7
|
+
# @param env [Sass::Environment] The environment in which to run the script.
|
8
8
|
def perform(environment); Sass::Util.abstract(self); end
|
9
9
|
|
10
10
|
# Returns the CSS for this condition.
|
@@ -81,12 +81,12 @@ module Sass::Supports
|
|
81
81
|
|
82
82
|
def left_parens(str)
|
83
83
|
return "(#{str})" if @left.is_a?(Negation)
|
84
|
-
str
|
84
|
+
return str
|
85
85
|
end
|
86
86
|
|
87
87
|
def right_parens(str)
|
88
88
|
return "(#{str})" if @right.is_a?(Negation) || @right.is_a?(Operator)
|
89
|
-
str
|
89
|
+
return str
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -127,25 +127,26 @@ module Sass::Supports
|
|
127
127
|
|
128
128
|
def parens(str)
|
129
129
|
return "(#{str})" if @condition.is_a?(Negation) || @condition.is_a?(Operator)
|
130
|
-
str
|
130
|
+
return str
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
134
|
# A declaration condition (e.g. `(feature: value)`).
|
135
135
|
class Declaration < Condition
|
136
|
-
#
|
136
|
+
# The feature name.
|
137
|
+
#
|
138
|
+
# @param [Sass::Script::Node]
|
137
139
|
attr_accessor :name
|
138
140
|
|
139
|
-
#
|
140
|
-
#
|
141
|
-
# Only set once \{Tree::Visitors::Perform} has been run.
|
141
|
+
# The name of the feature after any SassScript has been resolved.
|
142
|
+
# Only set once \{Tree::Visitors::Perform} has been run.
|
142
143
|
#
|
143
|
-
#
|
144
|
+
# @return [String]
|
144
145
|
attr_accessor :resolved_name
|
145
146
|
|
146
147
|
# The feature value.
|
147
148
|
#
|
148
|
-
# @
|
149
|
+
# @param [Sass::Script::Node]
|
149
150
|
attr_accessor :value
|
150
151
|
|
151
152
|
# The value of the feature after any SassScript has been resolved.
|
@@ -189,7 +190,7 @@ module Sass::Supports
|
|
189
190
|
class Interpolation < Condition
|
190
191
|
# The SassScript expression in the interpolation.
|
191
192
|
#
|
192
|
-
# @
|
193
|
+
# @param [Sass::Script::Node]
|
193
194
|
attr_accessor :value
|
194
195
|
|
195
196
|
# The value of the expression after it's been resolved.
|
@@ -203,7 +204,8 @@ module Sass::Supports
|
|
203
204
|
end
|
204
205
|
|
205
206
|
def perform(env)
|
206
|
-
|
207
|
+
val = value.perform(env)
|
208
|
+
@resolved_value = val.is_a?(Sass::Script::String) ? val.value : val.to_s
|
207
209
|
end
|
208
210
|
|
209
211
|
def to_css
|
@@ -211,7 +213,7 @@ module Sass::Supports
|
|
211
213
|
end
|
212
214
|
|
213
215
|
def to_src(options)
|
214
|
-
@value.to_sass(options)
|
216
|
+
"\#{#{@value.to_sass(options)}}"
|
215
217
|
end
|
216
218
|
|
217
219
|
def deep_copy
|