oreorenasass 3.4.4 → 3.4.5
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.
- 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
|