sass 3.1.18 → 3.1.19

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/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.18
1
+ 3.1.19
@@ -25,6 +25,7 @@ require 'sass/tree/charset_node'
25
25
  require 'sass/tree/visitors/base'
26
26
  require 'sass/tree/visitors/perform'
27
27
  require 'sass/tree/visitors/cssize'
28
+ require 'sass/tree/visitors/extend'
28
29
  require 'sass/tree/visitors/convert'
29
30
  require 'sass/tree/visitors/to_css'
30
31
  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
 
@@ -584,7 +584,7 @@ END
584
584
  end
585
585
 
586
586
  ext = @options[:from]
587
- Sass::Util.glob("#{@options[:input]}/**/*.#{ext}") do |f|
587
+ ::Sass::Util.glob("#{@options[:input]}/**/*.#{ext}") do |f|
588
588
  output =
589
589
  if @options[:in_place]
590
590
  f
@@ -44,12 +44,17 @@ 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)
52
- CommaSequence.new(members.map {|seq| seq.do_extend(extends)}.flatten)
54
+ def do_extend(extends, parent_directives)
55
+ CommaSequence.new(members.map do |seq|
56
+ seq.do_extend(extends, parent_directives)
57
+ end.flatten)
53
58
  end
54
59
 
55
60
  # Returns a string representation of the sequence.
@@ -69,16 +69,19 @@ module Sass
69
69
  # (which should come from {Sass::Tree::Visitors::Cssize}).
70
70
  #
71
71
  # @overload def do_extend(extends)
72
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
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
  paths = Sass::Util.paths(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
@@ -54,23 +54,28 @@ module Sass
54
54
  # Non-destrucively extends this selector with the extensions specified in a hash
55
55
  # (which should come from {Sass::Tree::Visitors::Cssize}).
56
56
  #
57
- # @overload def do_extend(extends)
58
- # @param extends [{Selector::Simple => Selector::Sequence}]
57
+ # @overload def do_extend(extends, parent_directives)
58
+ # @param extends [{Selector::Simple =>
59
+ # Sass::Tree::Visitors::Cssize::Extend}]
59
60
  # The extensions to perform on this selector
61
+ # @param parent_directives [Array<Sass::Tree::DirectiveNode>]
62
+ # The directives containing this selector.
60
63
  # @return [Array<Sequence>] A list of selectors generated
61
64
  # by extending this selector with `extends`.
62
65
  # @see CommaSequence#do_extend
63
- def do_extend(extends, seen = Set.new)
64
- extends.get(members.to_set).map do |seq, sels|
66
+ def do_extend(extends, parent_directives, seen = Set.new)
67
+ extends.get(members.to_set).map do |ex, sels|
65
68
  # If A {@extend B} and C {...},
66
- # seq is A, sels is B, and self is C
69
+ # ex.extender is A, sels is B, and self is C
67
70
 
68
71
  self_without_sel = self.members - sels
69
- next unless unified = seq.members.last.unify(self_without_sel)
70
- [sels, seq.members[0...-1] + [unified]]
72
+ next unless unified = ex.extender.members.last.unify(self_without_sel)
73
+ next unless check_directives_match!(ex, parent_directives)
74
+ [sels, ex.extender.members[0...-1] + [unified]]
71
75
  end.compact.map do |sels, seq|
72
76
  seq = Sequence.new(seq)
73
- seen.include?(sels) ? [] : seq.do_extend(extends, seen + [sels])
77
+ next [] if seen.include?(sels)
78
+ seq.do_extend(extends, parent_directives, seen + [sels])
74
79
  end.flatten.uniq
75
80
  end
76
81
 
@@ -122,6 +127,21 @@ module Sass
122
127
 
123
128
  private
124
129
 
130
+ def check_directives_match!(extend, parent_directives)
131
+ dirs1 = extend.directives.map {|d| d.value}
132
+ dirs2 = parent_directives.map {|d| d.value}
133
+ return true if Sass::Util.subsequence?(dirs1, dirs2)
134
+
135
+ Sass::Util.sass_warn <<WARNING
136
+ DEPRECATION WARNING on line #{extend.node.line}#{" of #{extend.node.filename}" if extend.node.filename}:
137
+ @extending an outer selector from within #{extend.directives.last.name} is deprecated.
138
+ You may only @extend selectors within the same directive.
139
+ This will be an error in Sass 3.3.
140
+ It can only work once @extend is supported natively in the browser.
141
+ WARNING
142
+ return false
143
+ end
144
+
125
145
  def _hash
126
146
  [base, Sass::Util.set_hash(rest)].hash
127
147
  end
@@ -25,17 +25,5 @@ module Sass::Tree
25
25
  @selector = selector
26
26
  super()
27
27
  end
28
-
29
- # Disables this `@extend` due to it being inside a directive.
30
- def disable!
31
- @disabled = true
32
- end
33
-
34
- # Whether this `@extend` is disabled due to it being inside a directive.
35
- #
36
- # @return [Boolean]
37
- def disabled?
38
- @disabled
39
- end
40
28
  end
41
29
  end
@@ -140,27 +140,6 @@ module Sass
140
140
  "(#{self.class} #{children.map {|c| c.inspect}.join(' ')})"
141
141
  end
142
142
 
143
- # Converts a static CSS tree (e.g. the output of \{Tree::Visitors::Cssize})
144
- # into another static CSS tree,
145
- # with the given extensions applied to all relevant {RuleNode}s.
146
- #
147
- # @todo Link this to the reference documentation on `@extend`
148
- # when such a thing exists.
149
- #
150
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
151
- # The extensions to perform on this tree
152
- # @return [Tree::Node] The resulting tree of static CSS nodes.
153
- # @raise [Sass::SyntaxError] Only if there's a programmer error
154
- # and this is not a static CSS tree
155
- def do_extend(extends)
156
- node = dup
157
- node.children = children.map {|c| c.do_extend(extends)}
158
- node
159
- rescue Sass::SyntaxError => e
160
- e.modify_backtrace(:filename => filename, :line => line)
161
- raise e
162
- end
163
-
164
143
  # Iterates through each node in the tree rooted at this node
165
144
  # in a pre-order walk.
166
145
  #
@@ -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).
@@ -54,18 +54,6 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
54
54
  unless is_any_of?(parent, VALID_EXTEND_PARENTS)
55
55
  return "Extend directives may only be used within rules."
56
56
  end
57
-
58
- if !child.disabled? &&
59
- directive = @parents.find {|p| p.is_a?(Sass::Tree::DirectiveNode)}
60
- child.disable!
61
- Sass::Util.sass_warn <<WARNING
62
- DEPRECATION WARNING on line #{child.line}#{" of #{child.filename}" if child.filename}:
63
- Using @extend within directives (e.g. #{directive.name}) is deprecated.
64
- It will be an error in Sass 3.2.
65
- This will only work once @extend is supported natively in the browser.
66
- WARNING
67
- nil
68
- end
69
57
  end
70
58
 
71
59
  def invalid_function_parent?(parent, child)
@@ -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
 
@@ -80,9 +83,20 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
80
83
  raise e
81
84
  end
82
85
 
86
+ # A simple struct wrapping up information about a single `@extend` instance. A
87
+ # single [ExtendNode] can have multiple Extends if either the parent node or
88
+ # the extended selector is a comma sequence.
89
+ #
90
+ # @attr extender [Array<Sass::Selector::SimpleSequence, String>]
91
+ # The selector of the CSS rule containing the `@extend`.
92
+ # @attr target [Array<Sass::Selector::Simple>] The selector being `@extend`ed.
93
+ # @attr node [Sass::Tree::ExtendNode] The node that produced this extend.
94
+ # @attr directives [Array<Sass::Tree::DirectiveNode>]
95
+ # The directives containing the `@extend`.
96
+ Extend = Struct.new(:extender, :target, :node, :directives)
97
+
83
98
  # Registers an extension in the `@extends` subset map.
84
99
  def visit_extend(node)
85
- return [] if node.disabled?
86
100
  node.resolved_selector.members.each do |seq|
87
101
  if seq.members.size > 1
88
102
  raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: can't extend nested selectors")
@@ -99,7 +113,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
99
113
  raise Sass::SyntaxError.new("#{seq} can't extend: invalid selector")
100
114
  end
101
115
 
102
- @extends[sel] = seq
116
+ @extends[sel] = Extend.new(seq, sel, node, @parent_directives.dup)
103
117
  end
104
118
  end
105
119
 
@@ -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.value + ";" unless node.has_children
72
- return node.value + " {}" if node.children.empty?
71
+ tab_str = ' ' * @tabs
72
+ return tab_str + node.value + ";" unless node.has_children
73
+ return tab_str + node.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.value}{"
76
77
  else
77
- "#{' ' * @tabs}#{node.value} {" + (node.style == :compact ? ' ' : "\n")
78
+ "#{tab_str}#{node.value} {" + (node.style == :compact ? ' ' : "\n")
78
79
  end
79
80
  was_prop = false
80
81
  first = true
@@ -253,6 +253,23 @@ module Sass
253
253
  "#{name} #{str} must be between #{range.first}#{unit} and #{range.last}#{unit}")
254
254
  end
255
255
 
256
+ # Returns whether or not `seq1` is a subsequence of `seq2`. That is, whether
257
+ # or not `seq2` contains every element in `seq1` in the same order (and
258
+ # possibly more elements besides).
259
+ #
260
+ # @param seq1 [Array]
261
+ # @param seq2 [Array]
262
+ # @return [Boolean]
263
+ def subsequence?(seq1, seq2)
264
+ i = j = 0
265
+ loop do
266
+ return true if i == seq1.size
267
+ return false if j == seq2.size
268
+ i += 1 if seq1[i] == seq2[j]
269
+ j += 1
270
+ end
271
+ end
272
+
256
273
  # Returns information about the caller of the previous method.
257
274
  #
258
275
  # @param entry [String] An entry in the `#caller` list, or a similarly formatted string
@@ -2492,6 +2492,22 @@ SASS
2492
2492
  SASS
2493
2493
  end
2494
2494
 
2495
+ def test_nested_empty_directive
2496
+ assert_equal <<CSS, render(<<SASS)
2497
+ @media screen {
2498
+ .foo {
2499
+ a: b; }
2500
+
2501
+ @unknown-directive; }
2502
+ CSS
2503
+ @media screen
2504
+ .foo
2505
+ a: b
2506
+
2507
+ @unknown-directive
2508
+ SASS
2509
+ end
2510
+
2495
2511
  # Encodings
2496
2512
 
2497
2513
  unless Sass::Util.ruby1_8?
@@ -1369,13 +1369,13 @@ CSS
1369
1369
  SCSS
1370
1370
  end
1371
1371
 
1372
-
1373
- def test_extend_in_media
1372
+ def test_extend_out_of_media
1374
1373
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1375
- DEPRECATION WARNING on line 3 of test_extend_in_media_inline.sass:
1376
- Using @extend within directives (e.g. @media) is deprecated.
1377
- It will be an error in Sass 3.2.
1378
- This will only work once @extend is supported natively in the browser.
1374
+ DEPRECATION WARNING on line 3 of test_extend_out_of_media_inline.sass:
1375
+ @extending an outer selector from within @media is deprecated.
1376
+ You may only @extend selectors within the same directive.
1377
+ This will be an error in Sass 3.3.
1378
+ It can only work once @extend is supported natively in the browser.
1379
1379
  WARN
1380
1380
  .foo {
1381
1381
  a: b; }
@@ -1387,12 +1387,13 @@ CSS
1387
1387
  SCSS
1388
1388
  end
1389
1389
 
1390
- def test_extend_in_unknown_directive
1390
+ def test_extend_out_of_unknown_directive
1391
1391
  assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1392
- DEPRECATION WARNING on line 3 of test_extend_in_unknown_directive_inline.sass:
1393
- Using @extend within directives (e.g. @flooblehoof) is deprecated.
1394
- It will be an error in Sass 3.2.
1395
- This will only work once @extend is supported natively in the browser.
1392
+ DEPRECATION WARNING on line 3 of test_extend_out_of_unknown_directive_inline.sass:
1393
+ @extending an outer selector from within @flooblehoof is deprecated.
1394
+ You may only @extend selectors within the same directive.
1395
+ This will be an error in Sass 3.3.
1396
+ It can only work once @extend is supported natively in the browser.
1396
1397
  WARN
1397
1398
  .foo {
1398
1399
  a: b; }
@@ -1406,6 +1407,181 @@ CSS
1406
1407
  SCSS
1407
1408
  end
1408
1409
 
1410
+ def test_extend_out_of_nested_directives
1411
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1412
+ DEPRECATION WARNING on line 4 of test_extend_out_of_nested_directives_inline.sass:
1413
+ @extending an outer selector from within @flooblehoof is deprecated.
1414
+ You may only @extend selectors within the same directive.
1415
+ This will be an error in Sass 3.3.
1416
+ It can only work once @extend is supported natively in the browser.
1417
+ WARN
1418
+ @media screen {
1419
+ .foo {
1420
+ a: b; }
1421
+
1422
+ @flooblehoof {} }
1423
+ CSS
1424
+ @media screen {
1425
+ .foo {a: b}
1426
+ @flooblehoof {
1427
+ .bar {@extend .foo}
1428
+ }
1429
+ }
1430
+ SCSS
1431
+ end
1432
+
1433
+ def test_extend_within_media
1434
+ assert_equal(<<CSS, render(<<SCSS))
1435
+ @media screen {
1436
+ .foo, .bar {
1437
+ a: b; } }
1438
+ CSS
1439
+ @media screen {
1440
+ .foo {a: b}
1441
+ .bar {@extend .foo}
1442
+ }
1443
+ SCSS
1444
+ end
1445
+
1446
+ def test_extend_within_unknown_directive
1447
+ assert_equal(<<CSS, render(<<SCSS))
1448
+ @flooblehoof {
1449
+ .foo, .bar {
1450
+ a: b; } }
1451
+ CSS
1452
+ @flooblehoof {
1453
+ .foo {a: b}
1454
+ .bar {@extend .foo}
1455
+ }
1456
+ SCSS
1457
+ end
1458
+
1459
+ def test_extend_within_nested_directives
1460
+ assert_equal(<<CSS, render(<<SCSS))
1461
+ @media screen {
1462
+ @flooblehoof {
1463
+ .foo, .bar {
1464
+ a: b; } } }
1465
+ CSS
1466
+ @media screen {
1467
+ @flooblehoof {
1468
+ .foo {a: b}
1469
+ .bar {@extend .foo}
1470
+ }
1471
+ }
1472
+ SCSS
1473
+ end
1474
+
1475
+ def test_extend_within_disparate_media
1476
+ assert_equal(<<CSS, render(<<SCSS))
1477
+ @media screen {
1478
+ .foo, .bar {
1479
+ a: b; } }
1480
+ CSS
1481
+ @media screen {.foo {a: b}}
1482
+ @media screen {.bar {@extend .foo}}
1483
+ SCSS
1484
+ end
1485
+
1486
+ def test_extend_within_disparate_unknown_directive
1487
+ assert_equal(<<CSS, render(<<SCSS))
1488
+ @flooblehoof {
1489
+ .foo, .bar {
1490
+ a: b; } }
1491
+
1492
+ @flooblehoof {}
1493
+ CSS
1494
+ @flooblehoof {.foo {a: b}}
1495
+ @flooblehoof {.bar {@extend .foo}}
1496
+ SCSS
1497
+ end
1498
+
1499
+ def test_extend_within_disparate_nested_directives
1500
+ assert_equal(<<CSS, render(<<SCSS))
1501
+ @media screen {
1502
+ @flooblehoof {
1503
+ .foo, .bar {
1504
+ a: b; } } }
1505
+ @media screen {
1506
+ @flooblehoof {} }
1507
+ CSS
1508
+ @media screen {@flooblehoof {.foo {a: b}}}
1509
+ @media screen {@flooblehoof {.bar {@extend .foo}}}
1510
+ SCSS
1511
+ end
1512
+
1513
+ def test_extend_within_and_without_media
1514
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1515
+ DEPRECATION WARNING on line 4 of test_extend_within_and_without_media_inline.sass:
1516
+ @extending an outer selector from within @media is deprecated.
1517
+ You may only @extend selectors within the same directive.
1518
+ This will be an error in Sass 3.3.
1519
+ It can only work once @extend is supported natively in the browser.
1520
+ WARN
1521
+ .foo {
1522
+ a: b; }
1523
+
1524
+ @media screen {
1525
+ .foo, .bar {
1526
+ c: d; } }
1527
+ CSS
1528
+ .foo {a: b}
1529
+ @media screen {
1530
+ .foo {c: d}
1531
+ .bar {@extend .foo}
1532
+ }
1533
+ SCSS
1534
+ end
1535
+
1536
+ def test_extend_within_and_without_unknown_directive
1537
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1538
+ DEPRECATION WARNING on line 4 of test_extend_within_and_without_unknown_directive_inline.sass:
1539
+ @extending an outer selector from within @flooblehoof is deprecated.
1540
+ You may only @extend selectors within the same directive.
1541
+ This will be an error in Sass 3.3.
1542
+ It can only work once @extend is supported natively in the browser.
1543
+ WARN
1544
+ .foo {
1545
+ a: b; }
1546
+
1547
+ @flooblehoof {
1548
+ .foo, .bar {
1549
+ c: d; } }
1550
+ CSS
1551
+ .foo {a: b}
1552
+ @flooblehoof {
1553
+ .foo {c: d}
1554
+ .bar {@extend .foo}
1555
+ }
1556
+ SCSS
1557
+ end
1558
+
1559
+ def test_extend_within_and_without_nested_directives
1560
+ assert_warning(<<WARN) {assert_equal(<<CSS, render(<<SCSS))}
1561
+ DEPRECATION WARNING on line 5 of test_extend_within_and_without_nested_directives_inline.sass:
1562
+ @extending an outer selector from within @flooblehoof is deprecated.
1563
+ You may only @extend selectors within the same directive.
1564
+ This will be an error in Sass 3.3.
1565
+ It can only work once @extend is supported natively in the browser.
1566
+ WARN
1567
+ @media screen {
1568
+ .foo {
1569
+ a: b; }
1570
+
1571
+ @flooblehoof {
1572
+ .foo, .bar {
1573
+ c: d; } } }
1574
+ CSS
1575
+ @media screen {
1576
+ .foo {a: b}
1577
+ @flooblehoof {
1578
+ .foo {c: d}
1579
+ .bar {@extend .foo}
1580
+ }
1581
+ }
1582
+ SCSS
1583
+ end
1584
+
1409
1585
  # Regression Tests
1410
1586
 
1411
1587
  def test_duplicated_selector_with_newlines
@@ -120,6 +120,16 @@ class UtilTest < Test::Unit::TestCase
120
120
  lcs([-5, 3, 2, 8], [-4, 1, 8]) {|a, b| (a - b).abs <= 1 && [a, b].max})
121
121
  end
122
122
 
123
+ def test_subsequence
124
+ assert(subsequence?([1, 2, 3], [1, 2, 3]))
125
+ assert(subsequence?([1, 2, 3], [1, :a, 2, :b, 3]))
126
+ assert(subsequence?([1, 2, 3], [:a, 1, :b, :c, 2, :d, 3, :e, :f]))
127
+
128
+ assert(!subsequence?([1, 2, 3], [1, 2]))
129
+ assert(!subsequence?([1, 2, 3], [1, 3, 2]))
130
+ assert(!subsequence?([1, 2, 3], [3, 2, 1]))
131
+ end
132
+
123
133
  def test_silence_warnings
124
134
  old_stderr, $stderr = $stderr, StringIO.new
125
135
  warn "Out"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- hash: 39
4
+ hash: 37
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
8
  - 1
9
- - 18
10
- version: 3.1.18
9
+ - 19
10
+ version: 3.1.19
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nathan Weizenbaum
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2012-05-11 00:00:00 -07:00
20
+ date: 2012-05-25 00:00:00 -07:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -102,6 +102,7 @@ files:
102
102
  - lib/sass/tree/visitors/to_css.rb
103
103
  - lib/sass/tree/visitors/check_nesting.rb
104
104
  - lib/sass/tree/visitors/deep_copy.rb
105
+ - lib/sass/tree/visitors/extend.rb
105
106
  - lib/sass/tree/visitors/set_options.rb
106
107
  - lib/sass/tree/visitors/cssize.rb
107
108
  - lib/sass/tree/visitors/convert.rb