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 CHANGED
@@ -1 +1 @@
1
- 2.3.245
1
+ 2.3.246
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.245
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
- lcs_backtrace(lcs_table(x, y), x, y, x.size-1, y.size-1)
207
- end
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] == y[j]
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
- return lcs_backtrace(c, x, y, i-1, j-1) << x[i] if x[i] == y[j]
618
- return lcs_backtrace(c, x, y, i, j-1) if c[i][j-1] > c[i-1][j]
619
- return lcs_backtrace(c, x, y, i-1, j)
620
- end
621
-
622
- # Computes all longest common subsequences for arrays x and y.
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
@@ -411,7 +411,18 @@ module Sass
411
411
  (tok(/\*/) && Selector::Universal.new(nil))
412
412
  res << v
413
413
  end
414
- expected('"{"') if tok?(/&/)
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 == lcs.first} << [lcs.shift]
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 unify_heads(sseq1, sseq2)
205
- return unless sseq2.size == 1 # Can't unify ".foo > .bar" and ".baz > .bang"
206
- unified = sseq1.last.unify(sseq2.last.members) unless sseq1.last.is_a?(String) || sseq2.last.is_a?(String)
207
- sseq1[0...-1] << unified if unified
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
@@ -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 test_lcs_all
114
- assert_equal(Set[[1, 2, 3]], lcs_all([1, 2, 3], [1, 2, 3]))
115
- assert_equal(Set[[]], lcs_all([], [1, 2, 3]))
116
- assert_equal(Set[[]], lcs_all([1, 2, 3], []))
117
- assert_equal(Set[[1, 2, 3]], lcs_all([5, 1, 4, 2, 3, 17], [0, 0, 1, 2, 6, 3]))
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
@@ -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 {
@@ -950,7 +950,12 @@ SCSS
950
950
  end
951
951
 
952
952
  def test_parent_in_mid_selector_error
953
- assert_raise(Sass::SyntaxError, 'Invalid CSS after ".foo": expected "{", was "&.bar"') {render <<SCSS}
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, 'Invalid CSS after ".foo.bar": expected "{", was "&"') {render <<SCSS}
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, 'Invalid CSS after "&": expected "{", was "&"') {render <<SCSS}
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.245
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-07 00:00:00 -04:00
13
+ date: 2010-05-08 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency