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 +1 -1
- data/lib/sass/engine.rb +1 -0
- data/lib/sass/exec.rb +2 -2
- data/lib/sass/selector/comma_sequence.rb +8 -3
- data/lib/sass/selector/sequence.rb +6 -3
- data/lib/sass/selector/simple_sequence.rb +28 -8
- data/lib/sass/tree/extend_node.rb +0 -12
- data/lib/sass/tree/node.rb +0 -21
- data/lib/sass/tree/root_node.rb +1 -1
- data/lib/sass/tree/rule_node.rb +0 -9
- data/lib/sass/tree/visitors/check_nesting.rb +0 -12
- data/lib/sass/tree/visitors/cssize.rb +16 -2
- data/lib/sass/tree/visitors/extend.rb +42 -0
- data/lib/sass/tree/visitors/to_css.rb +4 -3
- data/lib/sass/util.rb +17 -0
- data/test/sass/engine_test.rb +16 -0
- data/test/sass/extend_test.rb +187 -11
- data/test/sass/util_test.rb +10 -0
- metadata +5 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.1.
|
1
|
+
3.1.19
|
data/lib/sass/engine.rb
CHANGED
@@ -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'
|
data/lib/sass/exec.rb
CHANGED
@@ -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 =>
|
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
|
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 =>
|
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 =>
|
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 |
|
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
|
-
#
|
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 =
|
70
|
-
|
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
|
-
|
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
|
data/lib/sass/tree/node.rb
CHANGED
@@ -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
|
#
|
data/lib/sass/tree/root_node.rb
CHANGED
@@ -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
|
23
|
+
Visitors::Extend.visit(result, extends)
|
24
24
|
result.to_s
|
25
25
|
end
|
26
26
|
end
|
data/lib/sass/tree/rule_node.rb
CHANGED
@@ -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
|
-
|
72
|
-
return node.value + "
|
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
|
-
"#{
|
78
|
+
"#{tab_str}#{node.value} {" + (node.style == :compact ? ' ' : "\n")
|
78
79
|
end
|
79
80
|
was_prop = false
|
80
81
|
first = true
|
data/lib/sass/util.rb
CHANGED
@@ -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
|
data/test/sass/engine_test.rb
CHANGED
@@ -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?
|
data/test/sass/extend_test.rb
CHANGED
@@ -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
|
1376
|
-
|
1377
|
-
|
1378
|
-
This will
|
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
|
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
|
1393
|
-
|
1394
|
-
|
1395
|
-
This will
|
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
|
data/test/sass/util_test.rb
CHANGED
@@ -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:
|
4
|
+
hash: 37
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 3.1.
|
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-
|
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
|