sass 3.2.0.alpha.237 → 3.2.0.alpha.240

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.
data/REVISION CHANGED
@@ -1 +1 @@
1
- 167ee67e6a16423e95cf074074aea80ff9c828ca
1
+ e215507545439a84c2b2bc01d454ebab722fe209
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.0.alpha.237
1
+ 3.2.0.alpha.240
@@ -29,6 +29,7 @@ require 'sass/tree/charset_node'
29
29
  require 'sass/tree/visitors/base'
30
30
  require 'sass/tree/visitors/perform'
31
31
  require 'sass/tree/visitors/cssize'
32
+ require 'sass/tree/visitors/extend'
32
33
  require 'sass/tree/visitors/convert'
33
34
  require 'sass/tree/visitors/to_css'
34
35
  require 'sass/tree/visitors/deep_copy'
@@ -452,7 +452,7 @@ MSG
452
452
  def probably_dest_dir?(path)
453
453
  return false unless path
454
454
  return false if colon_path?(path)
455
- return Sass::Util.glob(File.join(path, "*.s[ca]ss")).empty?
455
+ return ::Sass::Util.glob(File.join(path, "*.s[ca]ss")).empty?
456
456
  end
457
457
  end
458
458
 
@@ -595,7 +595,7 @@ END
595
595
  end
596
596
 
597
597
  ext = @options[:from]
598
- Sass::Util.glob("#{@options[:input]}/**/*.#{ext}") do |f|
598
+ ::Sass::Util.glob("#{@options[:input]}/**/*.#{ext}") do |f|
599
599
  output =
600
600
  if @options[:in_place]
601
601
  f
@@ -44,13 +44,16 @@ module Sass
44
44
  # @todo Link this to the reference documentation on `@extend`
45
45
  # when such a thing exists.
46
46
  #
47
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
47
+ # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
48
+ # Sass::Tree::Visitors::Cssize::Extend}]
48
49
  # The extensions to perform on this selector
50
+ # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
51
+ # The directives containing this selector.
49
52
  # @return [CommaSequence] A copy of this selector,
50
53
  # with extensions made according to `extends`
51
- def do_extend(extends)
54
+ def do_extend(extends, parent_directives)
52
55
  CommaSequence.new(members.map do |seq|
53
- extended = seq.do_extend(extends)
56
+ extended = seq.do_extend(extends, parent_directives)
54
57
  # First Law of Extend: the result of extending a selector should
55
58
  # always contain the base selector.
56
59
  #
@@ -68,17 +68,20 @@ module Sass
68
68
  # Non-destructively extends this selector with the extensions specified in a hash
69
69
  # (which should come from {Sass::Tree::Visitors::Cssize}).
70
70
  #
71
- # @overload def do_extend(extends)
72
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
71
+ # @overload def do_extend(extends, parent_directives)
72
+ # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
73
+ # Sass::Tree::Visitors::Cssize::Extend}]
73
74
  # The extensions to perform on this selector
75
+ # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
76
+ # The directives containing this selector.
74
77
  # @return [Array<Sequence>] A list of selectors generated
75
78
  # by extending this selector with `extends`.
76
79
  # These correspond to a {CommaSequence}'s {CommaSequence#members members array}.
77
80
  # @see CommaSequence#do_extend
78
- def do_extend(extends, seen = Set.new)
81
+ def do_extend(extends, parent_directives, seen = Set.new)
79
82
  extended_not_expanded = members.map do |sseq_or_op|
80
83
  next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence)
81
- extended = sseq_or_op.do_extend(extends, seen)
84
+ extended = sseq_or_op.do_extend(extends, parent_directives, seen)
82
85
  choices = extended.map {|seq| seq.members}
83
86
  choices.unshift([sseq_or_op]) unless extended.any? {|seq| seq.superselector?(sseq_or_op)}
84
87
  choices
@@ -72,25 +72,29 @@ module Sass
72
72
  # Non-destrucively extends this selector with the extensions specified in a hash
73
73
  # (which should come from {Sass::Tree::Visitors::Cssize}).
74
74
  #
75
- # @overload def do_extend(extends, sources)
76
- # @param extends [{Selector::Simple => Selector::Sequence}]
75
+ # @overload def do_extend(extends, parent_directives)
76
+ # @param extends [{Selector::Simple =>
77
+ # Sass::Tree::Visitors::Cssize::Extend}]
77
78
  # The extensions to perform on this selector
79
+ # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
80
+ # The directives containing this selector.
78
81
  # @return [Array<Sequence>] A list of selectors generated
79
82
  # by extending this selector with `extends`.
80
83
  # @see CommaSequence#do_extend
81
- def do_extend(extends, seen = Set.new)
82
- Sass::Util.group_by_to_a(extends.get(members.to_set)) {|seq, _| seq}.map do |seq, group|
84
+ def do_extend(extends, parent_directives, seen = Set.new)
85
+ Sass::Util.group_by_to_a(extends.get(members.to_set)) {|ex, _| ex.extender}.map do |seq, group|
83
86
  sels = group.map {|_, s| s}.flatten
84
87
  # If A {@extend B} and C {...},
85
88
  # seq is A, sels is B, and self is C
86
89
 
87
90
  self_without_sel = self.members - sels
88
91
  next unless unified = seq.members.last.unify(self_without_sel)
92
+ next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none?
89
93
  new_seq = Sequence.new(seq.members[0...-1] + [unified])
90
94
  new_seq.add_sources!(sources + [seq])
91
95
  [sels, new_seq]
92
96
  end.compact.map do |sels, seq|
93
- seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
97
+ seen.include?(sels) ? [] : seq.do_extend(extends, parent_directives, seen + [sels])
94
98
  end.flatten.uniq
95
99
  end
96
100
 
@@ -154,6 +158,21 @@ module Sass
154
158
 
155
159
  private
156
160
 
161
+ def check_directives_match!(extend, parent_directives)
162
+ dirs1 = extend.directives.map {|d| d.resolved_value}
163
+ dirs2 = parent_directives.map {|d| d.resolved_value}
164
+ return true if Sass::Util.subsequence?(dirs1, dirs2)
165
+
166
+ Sass::Util.sass_warn <<WARNING
167
+ DEPRECATION WARNING on line #{extend.node.line}#{" of #{extend.node.filename}" if extend.node.filename}:
168
+ @extending an outer selector from within #{extend.directives.last.name} is deprecated.
169
+ You may only @extend selectors within the same directive.
170
+ This will be an error in Sass 3.3.
171
+ It can only work once @extend is supported natively in the browser.
172
+ WARNING
173
+ return false
174
+ end
175
+
157
176
  def _hash
158
177
  [base, Sass::Util.set_hash(rest)].hash
159
178
  end
@@ -141,27 +141,6 @@ module Sass
141
141
  "(#{self.class} #{children.map {|c| c.inspect}.join(' ')})"
142
142
  end
143
143
 
144
- # Converts a static CSS tree (e.g. the output of \{Tree::Visitors::Cssize})
145
- # into another static CSS tree,
146
- # with the given extensions applied to all relevant {RuleNode}s.
147
- #
148
- # @todo Link this to the reference documentation on `@extend`
149
- # when such a thing exists.
150
- #
151
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
152
- # The extensions to perform on this tree
153
- # @return [Tree::Node] The resulting tree of static CSS nodes.
154
- # @raise [Sass::SyntaxError] Only if there's a programmer error
155
- # and this is not a static CSS tree
156
- def do_extend(extends)
157
- node = dup
158
- node.children = children.map {|c| c.do_extend(extends)}
159
- node
160
- rescue Sass::SyntaxError => e
161
- e.modify_backtrace(:filename => filename, :line => line)
162
- raise e
163
- end
164
-
165
144
  # Iterates through each node in the tree rooted at this node
166
145
  # in a pre-order walk.
167
146
  #
@@ -20,7 +20,7 @@ module Sass
20
20
  result = Visitors::Perform.visit(self)
21
21
  Visitors::CheckNesting.visit(result) # Check again to validate mixins
22
22
  result, extends = Visitors::Cssize.visit(result)
23
- result = result.do_extend(extends) unless extends.empty?
23
+ Visitors::Extend.visit(result, extends)
24
24
  result.to_s
25
25
  end
26
26
  end
@@ -103,15 +103,6 @@ module Sass::Tree
103
103
  last.is_a?(String) && last[-1] == ?,
104
104
  end
105
105
 
106
- # Extends this Rule's selector with the given `extends`.
107
- #
108
- # @see Node#do_extend
109
- def do_extend(extends)
110
- node = dup
111
- node.resolved_rules = resolved_rules.do_extend(extends)
112
- node
113
- end
114
-
115
106
  # A hash that will be associated with this rule in the CSS document
116
107
  # if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
117
108
  # This data is used by e.g. [the FireSass Firebug extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
@@ -71,14 +71,6 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
71
71
  unless is_any_of?(parent, VALID_EXTEND_PARENTS)
72
72
  return "Extend directives may only be used within rules."
73
73
  end
74
-
75
- if directive = @parents.find {|p| p.is_a?(Sass::Tree::DirectiveNode)}
76
- return <<ERR.rstrip
77
- @extend may not be used within directives (e.g. #{directive.name}).
78
-
79
- This will only work once @extend is supported natively in the browser.
80
- ERR
81
- end
82
74
  end
83
75
 
84
76
  def invalid_function_parent?(parent, child)
@@ -81,7 +81,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
81
81
  content.gsub!(/^/, tab_str)
82
82
  content.rstrip + "\n"
83
83
  else
84
- spaces = (' ' * [@tabs - value[/^ */].size, 0].max)
84
+ spaces = (@tab_chars * [@tabs - value[/^ */].size, 0].max)
85
85
  content = if node.type == :silent
86
86
  value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
87
87
  else
@@ -12,6 +12,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
12
12
  attr_reader :parent
13
13
 
14
14
  def initialize
15
+ @parent_directives = []
15
16
  @extends = Sass::Util::SubsetMap.new
16
17
  end
17
18
 
@@ -38,9 +39,11 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
38
39
  # @yield A block in which the parent is set to `parent`.
39
40
  # @return [Object] The return value of the block.
40
41
  def with_parent(parent)
42
+ @parent_directives.push parent if parent.is_a?(Sass::Tree::DirectiveNode)
41
43
  old_parent, @parent = @parent, parent
42
44
  yield
43
45
  ensure
46
+ @parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
44
47
  @parent = old_parent
45
48
  end
46
49
 
@@ -81,6 +84,18 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
81
84
  raise e
82
85
  end
83
86
 
87
+ # A simple struct wrapping up information about a single `@extend` instance. A
88
+ # single [ExtendNode] can have multiple Extends if either the parent node or
89
+ # the extended selector is a comma sequence.
90
+ #
91
+ # @attr extender [Array<Sass::Selector::SimpleSequence, String>]
92
+ # The selector of the CSS rule containing the `@extend`.
93
+ # @attr target [Array<Sass::Selector::Simple>] The selector being `@extend`ed.
94
+ # @attr node [Sass::Tree::ExtendNode] The node that produced this extend.
95
+ # @attr directives [Array<Sass::Tree::DirectiveNode>]
96
+ # The directives containing the `@extend`.
97
+ Extend = Struct.new(:extender, :target, :node, :directives)
98
+
84
99
  # Registers an extension in the `@extends` subset map.
85
100
  def visit_extend(node)
86
101
  node.resolved_selector.members.each do |seq|
@@ -101,7 +116,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
101
116
  raise Sass::SyntaxError.new("#{seq} can't extend: invalid selector")
102
117
  end
103
118
 
104
- @extends[sel] = seq
119
+ @extends[sel] = Extend.new(seq, sel, node, @parent_directives.dup)
105
120
  end
106
121
  end
107
122
 
@@ -0,0 +1,42 @@
1
+ # A visitor for performing selector inheritance on a static CSS tree.
2
+ #
3
+ # Destructively modifies the tree.
4
+ class Sass::Tree::Visitors::Extend < Sass::Tree::Visitors::Base
5
+ # @param root [Tree::Node] The root node of the tree to visit.
6
+ # @param extends [Sass::Util::SubsetMap{Selector::Simple =>
7
+ # Sass::Tree::Visitors::Cssize::Extend}]
8
+ # The extensions to perform on this tree.
9
+ # @return [Object] The return value of \{#visit} for the root node.
10
+ def self.visit(root, extends)
11
+ return if extends.empty?
12
+ new(extends).send(:visit, root)
13
+ end
14
+
15
+ protected
16
+
17
+ def initialize(extends)
18
+ @parent_directives = []
19
+ @extends = extends
20
+ end
21
+
22
+ # If an exception is raised, this adds proper metadata to the backtrace.
23
+ def visit(node)
24
+ super(node)
25
+ rescue Sass::SyntaxError => e
26
+ e.modify_backtrace(:filename => node.filename, :line => node.line)
27
+ raise e
28
+ end
29
+
30
+ # Keeps track of the current parent directives.
31
+ def visit_children(parent)
32
+ @parent_directives.push parent if parent.is_a?(Sass::Tree::DirectiveNode)
33
+ super
34
+ ensure
35
+ @parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
36
+ end
37
+
38
+ # Applies the extend to a single rule's selector.
39
+ def visit_rule(node)
40
+ node.resolved_rules = node.resolved_rules.do_extend(@extends, @parent_directives)
41
+ end
42
+ end
@@ -68,13 +68,14 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
68
68
 
69
69
  def visit_directive(node)
70
70
  was_in_directive = @in_directive
71
- return node.resolved_value + ";" unless node.has_children
72
- return node.resolved_value + " {}" if node.children.empty?
71
+ tab_str = ' ' * @tabs
72
+ return tab_str + node.resolved_value + ";" unless node.has_children
73
+ return tab_str + node.resolved_value + " {}" if node.children.empty?
73
74
  @in_directive = @in_directive || !node.is_a?(Sass::Tree::MediaNode)
74
75
  result = if node.style == :compressed
75
76
  "#{node.resolved_value}{"
76
77
  else
77
- "#{' ' * @tabs}#{node.resolved_value} {" + (node.style == :compact ? ' ' : "\n")
78
+ "#{tab_str}#{node.resolved_value} {" + (node.style == :compact ? ' ' : "\n")
78
79
  end
79
80
  was_prop = false
80
81
  first = true
@@ -276,6 +276,23 @@ module Sass
276
276
  "#{name} #{str} must be between #{range.first}#{unit} and #{range.last}#{unit}")
277
277
  end
278
278
 
279
+ # Returns whether or not `seq1` is a subsequence of `seq2`. That is, whether
280
+ # or not `seq2` contains every element in `seq1` in the same order (and
281
+ # possibly more elements besides).
282
+ #
283
+ # @param seq1 [Array]
284
+ # @param seq2 [Array]
285
+ # @return [Boolean]
286
+ def subsequence?(seq1, seq2)
287
+ i = j = 0
288
+ loop do
289
+ return true if i == seq1.size
290
+ return false if j == seq2.size
291
+ i += 1 if seq1[i] == seq2[j]
292
+ j += 1
293
+ end
294
+ end
295
+
279
296
  # Returns information about the caller of the previous method.
280
297
  #
281
298
  # @param entry [String] An entry in the `#caller` list, or a similarly formatted string
@@ -1558,6 +1558,21 @@ SASS
1558
1558
  SCSS
1559
1559
  end
1560
1560
 
1561
+ def test_comment_indentation
1562
+ assert_renders(<<SASS, <<SCSS, :indent => ' ')
1563
+ foo
1564
+ // bar
1565
+ /* baz
1566
+ a: b
1567
+ SASS
1568
+ foo {
1569
+ // bar
1570
+ /* baz */
1571
+ a: b;
1572
+ }
1573
+ SCSS
1574
+ end
1575
+
1561
1576
  private
1562
1577
 
1563
1578
  def assert_sass_to_sass(sass, options = {})
@@ -1580,7 +1595,7 @@ SCSS
1580
1595
  options ||= {}
1581
1596
 
1582
1597
  assert_equal(scss.rstrip, to_scss(in_scss, options.merge(:syntax => :scss)).rstrip,
1583
- "Expected SCSS to transform to #{scss == in_scss ? 'itself' : 'SCSS'}k")
1598
+ "Expected SCSS to transform to #{scss == in_scss ? 'itself' : 'SCSS'}")
1584
1599
  end
1585
1600
 
1586
1601
  def assert_sass_to_scss(scss, sass, options = {})
@@ -146,8 +146,6 @@ MSG
146
146
  "$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
147
147
  "@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
148
148
  "@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
149
- "@media screen\n .bar\n @extend .foo" => "@extend may not be used within directives (e.g. @media).\n\nThis will only work once @extend is supported natively in the browser.",
150
- "@flooblehoof\n .bar\n @extend .foo" => "@extend may not be used within directives (e.g. @flooblehoof).\n\nThis will only work once @extend is supported natively in the browser.",
151
149
  "foo\n &a\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"a\"\n\n\"a\" may only be used at the beginning of a selector.", 2],
152
150
  "foo\n &1\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"1\"\n\n\"1\" may only be used at the beginning of a selector.", 2],
153
151
  "foo %\n a: b" => ['Invalid CSS after "foo %": expected placeholder name, was ""', 1],
@@ -2724,6 +2722,22 @@ SASS
2724
2722
  SASS
2725
2723
  end
2726
2724
 
2725
+ def test_nested_empty_directive
2726
+ assert_equal <<CSS, render(<<SASS)
2727
+ @media screen {
2728
+ .foo {
2729
+ a: b; }
2730
+
2731
+ @unknown-directive; }
2732
+ CSS
2733
+ @media screen
2734
+ .foo
2735
+ a: b
2736
+
2737
+ @unknown-directive
2738
+ SASS
2739
+ end
2740
+
2727
2741
  # Encodings
2728
2742
 
2729
2743
  unless Sass::Util.ruby1_8?
@@ -795,6 +795,219 @@ CSS
795
795
  SCSS
796
796
  end
797
797
 
798
+ def test_extend_out_of_media
799
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
800
+ DEPRECATION WARNING on line 3 of test_extend_out_of_media_inline.sass:
801
+ @extending an outer selector from within @media is deprecated.
802
+ You may only @extend selectors within the same directive.
803
+ This will be an error in Sass 3.3.
804
+ It can only work once @extend is supported natively in the browser.
805
+ WARN
806
+ .foo {
807
+ a: b; }
808
+ CSS
809
+ .foo {a: b}
810
+ @media screen {
811
+ .bar {@extend .foo}
812
+ }
813
+ SCSS
814
+ end
815
+
816
+ def test_extend_out_of_unknown_directive
817
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
818
+ DEPRECATION WARNING on line 3 of test_extend_out_of_unknown_directive_inline.sass:
819
+ @extending an outer selector from within @flooblehoof is deprecated.
820
+ You may only @extend selectors within the same directive.
821
+ This will be an error in Sass 3.3.
822
+ It can only work once @extend is supported natively in the browser.
823
+ WARN
824
+ .foo {
825
+ a: b; }
826
+
827
+ @flooblehoof {}
828
+ CSS
829
+ .foo {a: b}
830
+ @flooblehoof {
831
+ .bar {@extend .foo}
832
+ }
833
+ SCSS
834
+ end
835
+
836
+ def test_extend_out_of_nested_directives
837
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
838
+ DEPRECATION WARNING on line 4 of test_extend_out_of_nested_directives_inline.sass:
839
+ @extending an outer selector from within @flooblehoof is deprecated.
840
+ You may only @extend selectors within the same directive.
841
+ This will be an error in Sass 3.3.
842
+ It can only work once @extend is supported natively in the browser.
843
+ WARN
844
+ @media screen {
845
+ .foo {
846
+ a: b; }
847
+
848
+ @flooblehoof {} }
849
+ CSS
850
+ @media screen {
851
+ .foo {a: b}
852
+ @flooblehoof {
853
+ .bar {@extend .foo}
854
+ }
855
+ }
856
+ SCSS
857
+ end
858
+
859
+ def test_extend_within_media
860
+ assert_equal(<<CSS, render(<<SCSS))
861
+ @media screen {
862
+ .foo, .bar {
863
+ a: b; } }
864
+ CSS
865
+ @media screen {
866
+ .foo {a: b}
867
+ .bar {@extend .foo}
868
+ }
869
+ SCSS
870
+ end
871
+
872
+ def test_extend_within_unknown_directive
873
+ assert_equal(<<CSS, render(<<SCSS))
874
+ @flooblehoof {
875
+ .foo, .bar {
876
+ a: b; } }
877
+ CSS
878
+ @flooblehoof {
879
+ .foo {a: b}
880
+ .bar {@extend .foo}
881
+ }
882
+ SCSS
883
+ end
884
+
885
+ def test_extend_within_nested_directives
886
+ assert_equal(<<CSS, render(<<SCSS))
887
+ @media screen {
888
+ @flooblehoof {
889
+ .foo, .bar {
890
+ a: b; } } }
891
+ CSS
892
+ @media screen {
893
+ @flooblehoof {
894
+ .foo {a: b}
895
+ .bar {@extend .foo}
896
+ }
897
+ }
898
+ SCSS
899
+ end
900
+
901
+ def test_extend_within_disparate_media
902
+ assert_equal(<<CSS, render(<<SCSS))
903
+ @media screen {
904
+ .foo, .bar {
905
+ a: b; } }
906
+ CSS
907
+ @media screen {.foo {a: b}}
908
+ @media screen {.bar {@extend .foo}}
909
+ SCSS
910
+ end
911
+
912
+ def test_extend_within_disparate_unknown_directive
913
+ assert_equal(<<CSS, render(<<SCSS))
914
+ @flooblehoof {
915
+ .foo, .bar {
916
+ a: b; } }
917
+
918
+ @flooblehoof {}
919
+ CSS
920
+ @flooblehoof {.foo {a: b}}
921
+ @flooblehoof {.bar {@extend .foo}}
922
+ SCSS
923
+ end
924
+
925
+ def test_extend_within_disparate_nested_directives
926
+ assert_equal(<<CSS, render(<<SCSS))
927
+ @media screen {
928
+ @flooblehoof {
929
+ .foo, .bar {
930
+ a: b; } } }
931
+ @media screen {
932
+ @flooblehoof {} }
933
+ CSS
934
+ @media screen {@flooblehoof {.foo {a: b}}}
935
+ @media screen {@flooblehoof {.bar {@extend .foo}}}
936
+ SCSS
937
+ end
938
+
939
+ def test_extend_within_and_without_media
940
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
941
+ DEPRECATION WARNING on line 4 of test_extend_within_and_without_media_inline.sass:
942
+ @extending an outer selector from within @media is deprecated.
943
+ You may only @extend selectors within the same directive.
944
+ This will be an error in Sass 3.3.
945
+ It can only work once @extend is supported natively in the browser.
946
+ WARN
947
+ .foo {
948
+ a: b; }
949
+
950
+ @media screen {
951
+ .foo, .bar {
952
+ c: d; } }
953
+ CSS
954
+ .foo {a: b}
955
+ @media screen {
956
+ .foo {c: d}
957
+ .bar {@extend .foo}
958
+ }
959
+ SCSS
960
+ end
961
+
962
+ def test_extend_within_and_without_unknown_directive
963
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
964
+ DEPRECATION WARNING on line 4 of test_extend_within_and_without_unknown_directive_inline.sass:
965
+ @extending an outer selector from within @flooblehoof is deprecated.
966
+ You may only @extend selectors within the same directive.
967
+ This will be an error in Sass 3.3.
968
+ It can only work once @extend is supported natively in the browser.
969
+ WARN
970
+ .foo {
971
+ a: b; }
972
+
973
+ @flooblehoof {
974
+ .foo, .bar {
975
+ c: d; } }
976
+ CSS
977
+ .foo {a: b}
978
+ @flooblehoof {
979
+ .foo {c: d}
980
+ .bar {@extend .foo}
981
+ }
982
+ SCSS
983
+ end
984
+
985
+ def test_extend_within_and_without_nested_directives
986
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
987
+ DEPRECATION WARNING on line 5 of test_extend_within_and_without_nested_directives_inline.sass:
988
+ @extending an outer selector from within @flooblehoof is deprecated.
989
+ You may only @extend selectors within the same directive.
990
+ This will be an error in Sass 3.3.
991
+ It can only work once @extend is supported natively in the browser.
992
+ WARN
993
+ @media screen {
994
+ .foo {
995
+ a: b; }
996
+
997
+ @flooblehoof {
998
+ .foo, .bar {
999
+ c: d; } } }
1000
+ CSS
1001
+ @media screen {
1002
+ .foo {a: b}
1003
+ @flooblehoof {
1004
+ .foo {c: d}
1005
+ .bar {@extend .foo}
1006
+ }
1007
+ }
1008
+ SCSS
1009
+ end
1010
+
798
1011
  # Regression Tests
799
1012
 
800
1013
  def test_newline_near_combinator
@@ -127,6 +127,16 @@ class UtilTest < Test::Unit::TestCase
127
127
  group_by_to_a(1..12) {|i| i % 3})
128
128
  end
129
129
 
130
+ def test_subsequence
131
+ assert(subsequence?([1, 2, 3], [1, 2, 3]))
132
+ assert(subsequence?([1, 2, 3], [1, :a, 2, :b, 3]))
133
+ assert(subsequence?([1, 2, 3], [:a, 1, :b, :c, 2, :d, 3, :e, :f]))
134
+
135
+ assert(!subsequence?([1, 2, 3], [1, 2]))
136
+ assert(!subsequence?([1, 2, 3], [1, 3, 2]))
137
+ assert(!subsequence?([1, 2, 3], [3, 2, 1]))
138
+ end
139
+
130
140
  def test_silence_warnings
131
141
  old_stderr, $stderr = $stderr, StringIO.new
132
142
  warn "Out"
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- hash: 592302791
4
+ hash: 592302845
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 3
8
8
  - 2
9
9
  - 0
10
10
  - alpha
11
- - 237
12
- version: 3.2.0.alpha.237
11
+ - 240
12
+ version: 3.2.0.alpha.240
13
13
  platform: ruby
14
14
  authors:
15
15
  - Nathan Weizenbaum
@@ -19,7 +19,7 @@ autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
21
 
22
- date: 2012-05-11 00:00:00 -04:00
22
+ date: 2012-05-25 00:00:00 -04:00
23
23
  default_executable:
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
@@ -162,6 +162,7 @@ files:
162
162
  - lib/sass/tree/visitors/perform.rb
163
163
  - lib/sass/tree/visitors/set_options.rb
164
164
  - lib/sass/tree/visitors/to_css.rb
165
+ - lib/sass/tree/visitors/extend.rb
165
166
  - lib/sass/tree/warn_node.rb
166
167
  - lib/sass/tree/while_node.rb
167
168
  - lib/sass/tree/supports_node.rb