haml-edge 2.3.229 → 2.3.230
Sign up to get free protection for your applications and to get access to all the features.
- data/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/sass/selector/sequence.rb +2 -2
- data/lib/sass/selector/simple_sequence.rb +4 -34
- data/test/sass/extend_test.rb +55 -0
- metadata +1 -1
data/EDGE_GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.230
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.230
|
@@ -76,10 +76,10 @@ module Sass
|
|
76
76
|
# by extending this selector with `extends`.
|
77
77
|
# These correspond to a {CommaSequence}'s {CommaSequence#members members array}.
|
78
78
|
# @see CommaSequence#do_extend
|
79
|
-
def do_extend(extends,
|
79
|
+
def do_extend(extends, seen = Set.new)
|
80
80
|
paths = Haml::Util.paths(members.map do |sseq_or_op|
|
81
81
|
next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
|
82
|
-
extended = sseq_or_op.do_extend(extends,
|
82
|
+
extended = sseq_or_op.do_extend(extends, seen)
|
83
83
|
choices = extended.map {|seq| seq.members}
|
84
84
|
choices.unshift([sseq_or_op]) unless extended.any? {|seq| seq.superselector?(sseq_or_op)}
|
85
85
|
choices
|
@@ -61,7 +61,7 @@ module Sass
|
|
61
61
|
# @return [Array<Sequence>] A list of selectors generated
|
62
62
|
# by extending this selector with `extends`.
|
63
63
|
# @see CommaSequence#do_extend
|
64
|
-
def do_extend(extends,
|
64
|
+
def do_extend(extends, seen = Set.new)
|
65
65
|
extends.get(members.to_set).map do |seq, sels|
|
66
66
|
# If A {@extend B} and C {...},
|
67
67
|
# seq is A, sels is B, and self is C
|
@@ -69,13 +69,10 @@ module Sass
|
|
69
69
|
self_without_sel = self.members - sels
|
70
70
|
next unless unified = seq.members.last.unify(self_without_sel)
|
71
71
|
[sels, seq.members[0...-1] + [unified]]
|
72
|
-
end.compact.map
|
73
|
-
|
74
|
-
|
75
|
-
seqs
|
72
|
+
end.compact.map do |sels, seq|
|
73
|
+
seq = Sequence.new(seq)
|
74
|
+
seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
|
76
75
|
end.flatten.uniq
|
77
|
-
rescue SystemStackError
|
78
|
-
handle_extend_loop(supers)
|
79
76
|
end
|
80
77
|
|
81
78
|
# Unifies this selector with another {SimpleSequence}'s {SimpleSequence#members members array},
|
@@ -140,33 +137,6 @@ module Sass
|
|
140
137
|
other.class == self.class && other.base.eql?(self.base) &&
|
141
138
|
Haml::Util.set_eql?(other.rest, self.rest)
|
142
139
|
end
|
143
|
-
|
144
|
-
private
|
145
|
-
|
146
|
-
# Raise a {Sass::SyntaxError} describing a loop of `@extend` directives.
|
147
|
-
#
|
148
|
-
# @param supers [Array<Simple>] The stack of selectors that contains the loop,
|
149
|
-
# ordered from deepest to most shallow.
|
150
|
-
# @raise [Sass::SyntaxError] Describing the loop
|
151
|
-
def handle_extend_loop(supers)
|
152
|
-
supers.inject([]) do |sseqs, sseq|
|
153
|
-
next sseqs.push(sseq) unless sseqs.first.eql?(sseq)
|
154
|
-
conses = Haml::Util.enum_cons(sseqs.push(sseq), 2).to_a
|
155
|
-
_, i = Haml::Util.enum_with_index(conses).max do |((_, sseq1), _), ((_, sseq2), _)|
|
156
|
-
sseq1.first.line <=> sseq2.first.line
|
157
|
-
end
|
158
|
-
loop = (conses[i..-1] + conses[0...i]).map do |sseq1, sseq2|
|
159
|
-
sel1 = SimpleSequence.new(sseq1).inspect
|
160
|
-
sel2 = SimpleSequence.new(sseq2).inspect
|
161
|
-
str = " #{sel1} extends #{sel2} on line #{sseq2.first.line}"
|
162
|
-
str << " of " << sseq2.first.filename if sseq2.first.filename
|
163
|
-
str
|
164
|
-
end.join(",\n")
|
165
|
-
raise Sass::SyntaxError.new("An @extend loop was found:\n#{loop}")
|
166
|
-
end
|
167
|
-
# Should never get here
|
168
|
-
raise Sass::SyntaxError.new("An @extend loop exists, but the exact loop couldn't be found")
|
169
|
-
end
|
170
140
|
end
|
171
141
|
end
|
172
142
|
end
|
data/test/sass/extend_test.rb
CHANGED
@@ -1100,6 +1100,61 @@ CSS
|
|
1100
1100
|
SCSS
|
1101
1101
|
end
|
1102
1102
|
|
1103
|
+
# Loops
|
1104
|
+
|
1105
|
+
def test_extend_self_loop
|
1106
|
+
assert_equal <<CSS, render(<<SCSS)
|
1107
|
+
.foo {
|
1108
|
+
a: b; }
|
1109
|
+
CSS
|
1110
|
+
.foo {a: b; @extend .foo}
|
1111
|
+
SCSS
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
def test_basic_extend_loop
|
1115
|
+
assert_equal <<CSS, render(<<SCSS)
|
1116
|
+
.bar, .foo {
|
1117
|
+
a: b; }
|
1118
|
+
|
1119
|
+
.foo, .bar {
|
1120
|
+
c: d; }
|
1121
|
+
CSS
|
1122
|
+
.foo {a: b; @extend .bar}
|
1123
|
+
.bar {c: d; @extend .foo}
|
1124
|
+
SCSS
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
def test_three_level_extend_loop
|
1128
|
+
assert_equal <<CSS, render(<<SCSS)
|
1129
|
+
.baz, .bar, .foo {
|
1130
|
+
a: b; }
|
1131
|
+
|
1132
|
+
.foo, .baz, .bar {
|
1133
|
+
c: d; }
|
1134
|
+
|
1135
|
+
.bar, .foo, .baz {
|
1136
|
+
e: f; }
|
1137
|
+
CSS
|
1138
|
+
.foo {a: b; @extend .bar}
|
1139
|
+
.bar {c: d; @extend .baz}
|
1140
|
+
.baz {e: f; @extend .foo}
|
1141
|
+
SCSS
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
def test_nested_extend_loop
|
1145
|
+
assert_equal <<CSS, render(<<SCSS)
|
1146
|
+
.bar, .bar .foo {
|
1147
|
+
a: b; }
|
1148
|
+
.bar .foo, .bar .foo .foo {
|
1149
|
+
c: d; }
|
1150
|
+
CSS
|
1151
|
+
.bar {
|
1152
|
+
a: b;
|
1153
|
+
.foo {c: d; @extend .bar}
|
1154
|
+
}
|
1155
|
+
SCSS
|
1156
|
+
end
|
1157
|
+
|
1103
1158
|
def test_multiple_extender_merges_with_superset_selector
|
1104
1159
|
assert_equal <<CSS, render(<<SCSS)
|
1105
1160
|
a.bar.baz, a.foo {
|