haml-edge 2.3.245 → 2.3.246
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/haml/util.rb +15 -29
- data/lib/sass/scss/parser.rb +12 -1
- data/lib/sass/selector/sequence.rb +24 -6
- data/test/haml/util_test.rb +5 -8
- data/test/sass/extend_test.rb +90 -0
- data/test/sass/scss/scss_test.rb +18 -3
- metadata +2 -2
data/EDGE_GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.246
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.246
|
data/lib/haml/util.rb
CHANGED
@@ -199,22 +199,16 @@ module Haml
|
|
199
199
|
#
|
200
200
|
# @param x [Array]
|
201
201
|
# @param y [Array]
|
202
|
+
# @yield [a, b] An optional block to use in place of a check for equality
|
203
|
+
# between elements of `x` and `y`.
|
204
|
+
# @yieldreturn [Object, nil] If the two values register as equal,
|
205
|
+
# this will return the value to use in the LCS array.
|
202
206
|
# @return [Array] The LCS
|
203
|
-
def lcs(x, y)
|
207
|
+
def lcs(x, y, &block)
|
204
208
|
x = [nil, *x]
|
205
209
|
y = [nil, *y]
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
# Computes all single longest common subsequences for `x` and `y`.
|
210
|
-
#
|
211
|
-
# @param x [Array]
|
212
|
-
# @param y [Array]
|
213
|
-
# @return [Set<Array>] The LCSes
|
214
|
-
def lcs_all(x, y)
|
215
|
-
x = [nil, *x]
|
216
|
-
y = [nil, *y]
|
217
|
-
lcs_backtrace_all(lcs_table(x, y), x, y, x.size-1, y.size-1)
|
210
|
+
block ||= proc {|a, b| a == b && a}
|
211
|
+
lcs_backtrace(lcs_table(x, y, &block), x, y, x.size-1, y.size-1, &block)
|
218
212
|
end
|
219
213
|
|
220
214
|
# Returns information about the caller of the previous method.
|
@@ -600,7 +594,7 @@ METHOD
|
|
600
594
|
(1...x.size).each do |i|
|
601
595
|
(1...y.size).each do |j|
|
602
596
|
c[i][j] =
|
603
|
-
if x[i]
|
597
|
+
if yield x[i], y[j]
|
604
598
|
c[i-1][j-1] + 1
|
605
599
|
else
|
606
600
|
[c[i][j-1], c[i-1][j]].max
|
@@ -612,22 +606,14 @@ METHOD
|
|
612
606
|
|
613
607
|
# Computes a single longest common subsequence for arrays x and y.
|
614
608
|
# Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS)
|
615
|
-
def lcs_backtrace(c, x, y, i, j)
|
609
|
+
def lcs_backtrace(c, x, y, i, j, &block)
|
616
610
|
return [] if i == 0 || j == 0
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
# Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_all_LCSs)
|
624
|
-
def lcs_backtrace_all(c, x, y, i, j)
|
625
|
-
return Set[[]] if i == 0 || j == 0
|
626
|
-
return lcs_backtrace_all(c, x, y, i-1, j-1).map {|z| z << x[i]}.to_set if x[i] == y[j]
|
627
|
-
r = Set.new
|
628
|
-
r.merge(lcs_backtrace_all(c, x, y, i, j-1)) if c[i][j-1] >= c[i-1][j]
|
629
|
-
r.merge(lcs_backtrace_all(c, x, y, i-1, j)) if c[i-1][j] >= c[i][j-1]
|
630
|
-
r
|
611
|
+
if v = yield(x[i], y[j])
|
612
|
+
return lcs_backtrace(c, x, y, i-1, j-1, &block) << v
|
613
|
+
end
|
614
|
+
|
615
|
+
return lcs_backtrace(c, x, y, i, j-1, &block) if c[i][j-1] > c[i-1][j]
|
616
|
+
return lcs_backtrace(c, x, y, i-1, j, &block)
|
631
617
|
end
|
632
618
|
end
|
633
619
|
end
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -411,7 +411,18 @@ module Sass
|
|
411
411
|
(tok(/\*/) && Selector::Universal.new(nil))
|
412
412
|
res << v
|
413
413
|
end
|
414
|
-
|
414
|
+
|
415
|
+
if tok?(/&/)
|
416
|
+
begin
|
417
|
+
expected('"{"')
|
418
|
+
rescue Sass::SyntaxError => e
|
419
|
+
e.message << "\n\n" << <<MESSAGE
|
420
|
+
In Sass 3, the parent selector & can only be used where element names are valid,
|
421
|
+
since it could potentially be replaced by an element name.
|
422
|
+
MESSAGE
|
423
|
+
raise e
|
424
|
+
end
|
425
|
+
end
|
415
426
|
|
416
427
|
Selector::SimpleSequence.new(res)
|
417
428
|
end
|
@@ -163,11 +163,16 @@ module Sass
|
|
163
163
|
|
164
164
|
seq1 = group_selectors(seq1)
|
165
165
|
seq2 = group_selectors(seq2)
|
166
|
-
lcs = Haml::Util.lcs(seq2, seq1)
|
166
|
+
lcs = Haml::Util.lcs(seq2, seq1) do |s1, s2|
|
167
|
+
next s1 if s1 == s2
|
168
|
+
next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence)
|
169
|
+
next s2 if subweave_superselector?(s1, s2)
|
170
|
+
next s1 if subweave_superselector?(s2, s1)
|
171
|
+
end
|
167
172
|
|
168
173
|
diff = []
|
169
174
|
until lcs.empty?
|
170
|
-
diff << chunks(seq1, seq2) {|s| s.first
|
175
|
+
diff << chunks(seq1, seq2) {|s| subweave_superselector?(s.first, lcs.first)} << [lcs.shift]
|
171
176
|
seq1.shift
|
172
177
|
seq2.shift
|
173
178
|
end
|
@@ -201,10 +206,23 @@ module Sass
|
|
201
206
|
return newseq
|
202
207
|
end
|
203
208
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
207
|
-
|
209
|
+
def subweave_superselector?(sseq1, sseq2)
|
210
|
+
if sseq1.size > 1
|
211
|
+
# More complex selectors are never superselectors of less complex ones
|
212
|
+
return unless sseq2.size > 1
|
213
|
+
# .foo ~ .bar is a superselector of .foo + .bar
|
214
|
+
return unless sseq1[1] == "~" ? sseq2[1] != ">" : sseq2[1] == sseq1[1]
|
215
|
+
return unless sseq1.first.superselector?(sseq2.first)
|
216
|
+
return true if sseq1.size == 2
|
217
|
+
return false if sseq2.size == 2
|
218
|
+
return subweave_superselector?(sseq1[2..-1], sseq2[2..-1])
|
219
|
+
elsif sseq2.size > 1
|
220
|
+
return true if sseq2[1] == ">" && sseq1.first.superselector?(sseq2.first)
|
221
|
+
return false if sseq2.size == 2
|
222
|
+
return subweave_superselector?(sseq1, sseq2[2..-1])
|
223
|
+
else
|
224
|
+
sseq1.first.superselector?(sseq2.first)
|
225
|
+
end
|
208
226
|
end
|
209
227
|
|
210
228
|
def _hash
|
data/test/haml/util_test.rb
CHANGED
@@ -110,14 +110,11 @@ class UtilTest < Test::Unit::TestCase
|
|
110
110
|
assert_equal([1, 2], lcs([1, 2, 3, 4], [3, 4, 1, 2]))
|
111
111
|
end
|
112
112
|
|
113
|
-
def
|
114
|
-
assert_equal(
|
115
|
-
|
116
|
-
assert_equal(
|
117
|
-
|
118
|
-
|
119
|
-
assert_equal(Set[[1], [2], [3], [4]], lcs_all([1, 2, 3, 4], [4, 3, 2, 1]))
|
120
|
-
assert_equal(Set[[1, 2], [3, 4]], lcs_all([1, 2, 3, 4], [3, 4, 1, 2]))
|
113
|
+
def test_lcs_with_block
|
114
|
+
assert_equal(["1", "2", "3"],
|
115
|
+
lcs([1, 4, 2, 5, 3], [1, 2, 3]) {|a, b| a == b && a.to_s})
|
116
|
+
assert_equal([-4, 2, 8],
|
117
|
+
lcs([-5, 3, 2, 8], [-4, 1, 8]) {|a, b| (a - b).abs <= 1 && [a, b].max})
|
121
118
|
end
|
122
119
|
|
123
120
|
def test_silence_warnings
|
data/test/sass/extend_test.rb
CHANGED
@@ -1024,6 +1024,26 @@ CSS
|
|
1024
1024
|
SCSS
|
1025
1025
|
end
|
1026
1026
|
|
1027
|
+
def test_nested_extender_counts_extended_subselectors
|
1028
|
+
assert_equal <<CSS, render(<<SCSS)
|
1029
|
+
.a .bip.bop .foo, .a .b .bip.bop .bar, .b .a .bip.bop .bar {
|
1030
|
+
a: b; }
|
1031
|
+
CSS
|
1032
|
+
.a .bip.bop .foo {a: b}
|
1033
|
+
.b .bip .bar {@extend .foo}
|
1034
|
+
SCSS
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def test_nested_extender_counts_extended_superselectors
|
1038
|
+
assert_equal <<CSS, render(<<SCSS)
|
1039
|
+
.a .bip .foo, .a .b .bip.bop .bar, .b .a .bip.bop .bar {
|
1040
|
+
a: b; }
|
1041
|
+
CSS
|
1042
|
+
.a .bip .foo {a: b}
|
1043
|
+
.b .bip.bop .bar {@extend .foo}
|
1044
|
+
SCSS
|
1045
|
+
end
|
1046
|
+
|
1027
1047
|
def test_nested_extender_with_child_selector
|
1028
1048
|
assert_equal <<CSS, render(<<SCSS)
|
1029
1049
|
.baz .foo, .baz foo > bar {
|
@@ -1034,6 +1054,76 @@ foo > bar {@extend .foo}
|
|
1034
1054
|
SCSS
|
1035
1055
|
end
|
1036
1056
|
|
1057
|
+
def test_nested_extender_finds_common_selectors_around_child_selector
|
1058
|
+
assert_equal <<CSS, render(<<SCSS)
|
1059
|
+
a > b c .c1, a > b c .c2 {
|
1060
|
+
a: b; }
|
1061
|
+
CSS
|
1062
|
+
a > b c .c1 {a: b}
|
1063
|
+
a c .c2 {@extend .c1}
|
1064
|
+
SCSS
|
1065
|
+
|
1066
|
+
assert_equal <<CSS, render(<<SCSS)
|
1067
|
+
a > b c .c1, a > b c .c2 {
|
1068
|
+
a: b; }
|
1069
|
+
CSS
|
1070
|
+
a > b c .c1 {a: b}
|
1071
|
+
b c .c2 {@extend .c1}
|
1072
|
+
SCSS
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
def test_nested_extender_doesnt_find_common_selectors_around_adjacent_sibling_selector
|
1076
|
+
assert_equal <<CSS, render(<<SCSS)
|
1077
|
+
a + b c .c1, a + b a c .c2, a a + b c .c2 {
|
1078
|
+
a: b; }
|
1079
|
+
CSS
|
1080
|
+
a + b c .c1 {a: b}
|
1081
|
+
a c .c2 {@extend .c1}
|
1082
|
+
SCSS
|
1083
|
+
|
1084
|
+
assert_equal <<CSS, render(<<SCSS)
|
1085
|
+
a + b c .c1, a a + b c .c2 {
|
1086
|
+
a: b; }
|
1087
|
+
CSS
|
1088
|
+
a + b c .c1 {a: b}
|
1089
|
+
a b .c2 {@extend .c1}
|
1090
|
+
SCSS
|
1091
|
+
|
1092
|
+
assert_equal <<CSS, render(<<SCSS)
|
1093
|
+
a + b c .c1, a + b c .c2 {
|
1094
|
+
a: b; }
|
1095
|
+
CSS
|
1096
|
+
a + b c .c1 {a: b}
|
1097
|
+
b c .c2 {@extend .c1}
|
1098
|
+
SCSS
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
def test_nested_extender_doesnt_find_common_selectors_around_sibling_selector
|
1102
|
+
assert_equal <<CSS, render(<<SCSS)
|
1103
|
+
a ~ b c .c1, a ~ b a c .c2, a a ~ b c .c2 {
|
1104
|
+
a: b; }
|
1105
|
+
CSS
|
1106
|
+
a ~ b c .c1 {a: b}
|
1107
|
+
a c .c2 {@extend .c1}
|
1108
|
+
SCSS
|
1109
|
+
|
1110
|
+
assert_equal <<CSS, render(<<SCSS)
|
1111
|
+
a ~ b c .c1, a a ~ b c .c2 {
|
1112
|
+
a: b; }
|
1113
|
+
CSS
|
1114
|
+
a ~ b c .c1 {a: b}
|
1115
|
+
a b .c2 {@extend .c1}
|
1116
|
+
SCSS
|
1117
|
+
|
1118
|
+
assert_equal <<CSS, render(<<SCSS)
|
1119
|
+
a ~ b c .c1, a ~ b c .c2 {
|
1120
|
+
a: b; }
|
1121
|
+
CSS
|
1122
|
+
a ~ b c .c1 {a: b}
|
1123
|
+
b c .c2 {@extend .c1}
|
1124
|
+
SCSS
|
1125
|
+
end
|
1126
|
+
|
1037
1127
|
def test_nested_extender_with_early_child_selectors_doesnt_subseq_them
|
1038
1128
|
assert_equal <<CSS, render(<<SCSS)
|
1039
1129
|
.bip > .bap .foo, .bip > .bap .grip > .bap .bar, .grip > .bap .bip > .bap .bar {
|
data/test/sass/scss/scss_test.rb
CHANGED
@@ -950,7 +950,12 @@ SCSS
|
|
950
950
|
end
|
951
951
|
|
952
952
|
def test_parent_in_mid_selector_error
|
953
|
-
assert_raise(Sass::SyntaxError,
|
953
|
+
assert_raise(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
|
954
|
+
Invalid CSS after ".foo": expected "{", was "&.bar"
|
955
|
+
|
956
|
+
In Sass 3, the parent selector & can only be used where element names are valid,
|
957
|
+
since it could potentially be replaced by an element name.
|
958
|
+
MESSAGE
|
954
959
|
flim {
|
955
960
|
.foo&.bar {a: b}
|
956
961
|
}
|
@@ -958,7 +963,12 @@ SCSS
|
|
958
963
|
end
|
959
964
|
|
960
965
|
def test_parent_in_mid_selector_error
|
961
|
-
assert_raise(Sass::SyntaxError,
|
966
|
+
assert_raise(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
|
967
|
+
Invalid CSS after ".foo.bar": expected "{", was "&"
|
968
|
+
|
969
|
+
In Sass 3, the parent selector & can only be used where element names are valid,
|
970
|
+
since it could potentially be replaced by an element name.
|
971
|
+
MESSAGE
|
962
972
|
flim {
|
963
973
|
.foo.bar& {a: b}
|
964
974
|
}
|
@@ -966,7 +976,12 @@ SCSS
|
|
966
976
|
end
|
967
977
|
|
968
978
|
def test_double_parent_selector_error
|
969
|
-
assert_raise(Sass::SyntaxError,
|
979
|
+
assert_raise(Sass::SyntaxError, <<MESSAGE) {render <<SCSS}
|
980
|
+
Invalid CSS after "&": expected "{", was "&"
|
981
|
+
|
982
|
+
In Sass 3, the parent selector & can only be used where element names are valid,
|
983
|
+
since it could potentially be replaced by an element name.
|
984
|
+
MESSAGE
|
970
985
|
flim {
|
971
986
|
&& {a: b}
|
972
987
|
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml-edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.246
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Weizenbaum
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-05-
|
13
|
+
date: 2010-05-08 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|