sass 3.1.18 → 3.1.19

Sign up to get free protection for your applications and to get access to all the features.
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