sass 3.3.0.alpha.382 → 3.3.0.alpha.388
Sign up to get free protection for your applications and to get access to all the features.
- data/REVISION +1 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/lib/sass/engine.rb +10 -2
- data/lib/sass/environment.rb +2 -20
- data/lib/sass/script/functions.rb +12 -13
- data/lib/sass/script/value/helpers.rb +9 -0
- data/lib/sass/scss/parser.rb +42 -4
- data/lib/sass/scss/static_parser.rb +17 -0
- data/lib/sass/tree/at_root_node.rb +67 -0
- data/lib/sass/tree/directive_node.rb +11 -0
- data/lib/sass/tree/media_node.rb +0 -10
- data/lib/sass/tree/supports_node.rb +0 -13
- data/lib/sass/tree/visitors/convert.rb +6 -4
- data/lib/sass/tree/visitors/cssize.rb +52 -12
- data/lib/sass/tree/visitors/perform.rb +16 -7
- data/test/sass/conversion_test.rb +28 -0
- data/test/sass/engine_test.rb +13 -0
- data/test/sass/extend_test.rb +0 -1
- data/test/sass/scss/css_test.rb +0 -2
- data/test/sass/scss/scss_test.rb +316 -66
- metadata +3 -3
data/REVISION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4c629cf45c1d7ea2712bd73d16dbc5e96deda2a3
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.3.0.alpha.
|
1
|
+
3.3.0.alpha.388
|
data/VERSION_DATE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
11 October 2013 22:
|
1
|
+
11 October 2013 22:21:38 GMT
|
data/lib/sass/engine.rb
CHANGED
@@ -878,9 +878,17 @@ WARNING
|
|
878
878
|
end
|
879
879
|
|
880
880
|
def parse_at_root_directive(parent, line, root, value, offset)
|
881
|
-
|
882
|
-
return at_root_node unless value
|
881
|
+
return Sass::Tree::AtRootNode.new unless value
|
883
882
|
|
883
|
+
if value.start_with?('(')
|
884
|
+
parser = Sass::SCSS::Parser.new(value,
|
885
|
+
@options[:filename], @options[:importer],
|
886
|
+
@line, to_parser_offset(@offset))
|
887
|
+
offset = line.offset + line.text.index('at-root').to_i - 1
|
888
|
+
return Tree::AtRootNode.new(parser.parse_at_root_query)
|
889
|
+
end
|
890
|
+
|
891
|
+
at_root_node = Tree::AtRootNode.new
|
884
892
|
parsed = parse_interp(value, offset)
|
885
893
|
rule_node = Tree::RuleNode.new(parsed, full_line_range(line))
|
886
894
|
|
data/lib/sass/environment.rb
CHANGED
@@ -57,6 +57,7 @@ module Sass
|
|
57
57
|
|
58
58
|
attr_writer :caller
|
59
59
|
attr_writer :content
|
60
|
+
attr_writer :selector
|
60
61
|
|
61
62
|
# variable
|
62
63
|
# Script::Value
|
@@ -100,26 +101,7 @@ module Sass
|
|
100
101
|
# @return [Selector::CommaSequence?] The current selector, with any
|
101
102
|
# nesting fully resolved.
|
102
103
|
def selector
|
103
|
-
|
104
|
-
return @selector if @selector
|
105
|
-
return @caller.selector if @caller
|
106
|
-
return @parent.selector if @parent
|
107
|
-
nil
|
108
|
-
end
|
109
|
-
|
110
|
-
def selector=(value)
|
111
|
-
@selector = value
|
112
|
-
@no_selector = false
|
113
|
-
end
|
114
|
-
|
115
|
-
# Mark this environment as having no selector information. Unlike setting
|
116
|
-
# {#selector} to nil, this indicates that this environment should not
|
117
|
-
# inherit its {#parent}'s or {#caller}'s selector.
|
118
|
-
#
|
119
|
-
# This will be overwritten if {#selector} is set.
|
120
|
-
def no_selector!
|
121
|
-
@selector = nil
|
122
|
-
@no_selector = true
|
104
|
+
@selector || (@caller && @caller.selector) || (@parent && @parent.selector)
|
123
105
|
end
|
124
106
|
|
125
107
|
# The top-level Environment object.
|
@@ -1704,7 +1704,7 @@ module Sass::Script
|
|
1704
1704
|
index = n.to_i > 0 ? n.to_i - 1 : n.to_i
|
1705
1705
|
new_list = list.to_a.dup
|
1706
1706
|
new_list[index] = value
|
1707
|
-
|
1707
|
+
list(new_list, list.separator)
|
1708
1708
|
end
|
1709
1709
|
declare :set_nth, [:list, :n, :value]
|
1710
1710
|
|
@@ -1892,7 +1892,7 @@ module Sass::Script
|
|
1892
1892
|
# @raise [ArgumentError] if `$map` is not a map
|
1893
1893
|
def map_get(map, key)
|
1894
1894
|
assert_type map, :Map
|
1895
|
-
to_h(map)[key] ||
|
1895
|
+
to_h(map)[key] || null
|
1896
1896
|
end
|
1897
1897
|
declare :map_get, [:map, :key]
|
1898
1898
|
|
@@ -1916,7 +1916,7 @@ module Sass::Script
|
|
1916
1916
|
def map_merge(map1, map2)
|
1917
1917
|
assert_type map1, :Map
|
1918
1918
|
assert_type map2, :Map
|
1919
|
-
|
1919
|
+
map(to_h(map1).merge(to_h(map2)))
|
1920
1920
|
end
|
1921
1921
|
declare :map_get, [:map1, :map2]
|
1922
1922
|
|
@@ -1930,7 +1930,7 @@ module Sass::Script
|
|
1930
1930
|
# @raise [ArgumentError] if `$map` is not a map
|
1931
1931
|
def map_keys(map)
|
1932
1932
|
assert_type map, :Map
|
1933
|
-
|
1933
|
+
list(to_h(map).keys, :comma)
|
1934
1934
|
end
|
1935
1935
|
declare :map_keys, [:map]
|
1936
1936
|
|
@@ -1946,7 +1946,7 @@ module Sass::Script
|
|
1946
1946
|
# @raise [ArgumentError] if `$map` is not a map
|
1947
1947
|
def map_values(map)
|
1948
1948
|
assert_type map, :Map
|
1949
|
-
|
1949
|
+
list(to_h(map).values, :comma)
|
1950
1950
|
end
|
1951
1951
|
declare :map_values, [:map]
|
1952
1952
|
|
@@ -1962,7 +1962,7 @@ module Sass::Script
|
|
1962
1962
|
# @raise [ArgumentError] if `$map` is not a map
|
1963
1963
|
def map_has_key(map, key)
|
1964
1964
|
assert_type map, :Map
|
1965
|
-
|
1965
|
+
bool(to_h(map).has_key?(key))
|
1966
1966
|
end
|
1967
1967
|
declare :map_has_key, [:map, :key]
|
1968
1968
|
|
@@ -1982,8 +1982,7 @@ module Sass::Script
|
|
1982
1982
|
# @raise [ArgumentError] if `$args` isn't a variable argument list
|
1983
1983
|
def keywords(args)
|
1984
1984
|
assert_type args, :ArgList
|
1985
|
-
Sass::Script::
|
1986
|
-
Sass::Util.map_keys(args.keywords) {|k| Sass::Script::String.new(k)})
|
1985
|
+
map(Sass::Util.map_keys(args.keywords) {|k| Sass::Script::String.new(k)})
|
1987
1986
|
end
|
1988
1987
|
declare :keywords, [:args]
|
1989
1988
|
|
@@ -2078,7 +2077,7 @@ module Sass::Script
|
|
2078
2077
|
# @overload counters($args...)
|
2079
2078
|
# @return [String]
|
2080
2079
|
def counters(*args)
|
2081
|
-
|
2080
|
+
identifier("counters(#{args.map {|a| a.to_s(options)}.join(',')})")
|
2082
2081
|
end
|
2083
2082
|
declare :counters, [], :var_args => true
|
2084
2083
|
|
@@ -2096,7 +2095,7 @@ module Sass::Script
|
|
2096
2095
|
# the current scope.
|
2097
2096
|
def variable_exists(name)
|
2098
2097
|
assert_type name, :String
|
2099
|
-
|
2098
|
+
bool(environment.caller.var(name.value))
|
2100
2099
|
end
|
2101
2100
|
declare :variable_exists, [:name]
|
2102
2101
|
|
@@ -2117,7 +2116,7 @@ module Sass::Script
|
|
2117
2116
|
# the global scope.
|
2118
2117
|
def global_variable_exists(name)
|
2119
2118
|
assert_type name, :String
|
2120
|
-
|
2119
|
+
bool(environment.global_env.var(name.value))
|
2121
2120
|
end
|
2122
2121
|
declare :global_variable_exists, [:name]
|
2123
2122
|
|
@@ -2135,7 +2134,7 @@ module Sass::Script
|
|
2135
2134
|
assert_type name, :String
|
2136
2135
|
exists = Sass::Script::Functions.callable?(name.value.tr("-", "_"))
|
2137
2136
|
exists ||= environment.function(name.value)
|
2138
|
-
|
2137
|
+
bool(exists)
|
2139
2138
|
end
|
2140
2139
|
declare :function_exists, [:name]
|
2141
2140
|
|
@@ -2151,7 +2150,7 @@ module Sass::Script
|
|
2151
2150
|
# @return [Sass::Script::Bool] Whether the mixin is defined.
|
2152
2151
|
def mixin_exists(name)
|
2153
2152
|
assert_type name, :String
|
2154
|
-
|
2153
|
+
bool(environment.mixin(name.value))
|
2155
2154
|
end
|
2156
2155
|
declare :mixin_exists, [:name]
|
2157
2156
|
|
@@ -88,6 +88,15 @@ module Sass::Script::Value
|
|
88
88
|
Sass::Script::Value::List.new(elements, separator)
|
89
89
|
end
|
90
90
|
|
91
|
+
# Construct a Sass map.
|
92
|
+
#
|
93
|
+
# @param hash [Hash<Sass::Script::Value::Base,
|
94
|
+
# Sass::Script::Value::Base>] A Ruby map to convert to a Sass map.
|
95
|
+
# @return [Sass::Script::Value::Map] The map.
|
96
|
+
def map(hash)
|
97
|
+
Map.new(hash)
|
98
|
+
end
|
99
|
+
|
91
100
|
# Create a sass null value.
|
92
101
|
#
|
93
102
|
# @return [Sass::Script::Value::Null]
|
data/lib/sass/scss/parser.rb
CHANGED
@@ -67,6 +67,18 @@ module Sass
|
|
67
67
|
ql
|
68
68
|
end
|
69
69
|
|
70
|
+
# Parses an at-root query.
|
71
|
+
#
|
72
|
+
# @return [Array<String, Sass::Script;:Tree::Node>] The interpolated query.
|
73
|
+
# @raise [Sass::SyntaxError] if there's a syntax error in the query,
|
74
|
+
# or if it doesn't take up the entire input string.
|
75
|
+
def parse_at_root_query
|
76
|
+
init_scanner!
|
77
|
+
query = at_root_query
|
78
|
+
expected("@at-root query list") unless @scanner.eos?
|
79
|
+
query
|
80
|
+
end
|
81
|
+
|
70
82
|
# Parses a supports query condition.
|
71
83
|
#
|
72
84
|
# @return [Sass::Supports::Condition] The parsed condition
|
@@ -435,7 +447,7 @@ module Sass
|
|
435
447
|
query
|
436
448
|
end
|
437
449
|
|
438
|
-
def
|
450
|
+
def query_expr
|
439
451
|
interp = interpolation
|
440
452
|
return interp if interp
|
441
453
|
return unless tok(/\(/)
|
@@ -453,6 +465,11 @@ module Sass
|
|
453
465
|
res
|
454
466
|
end
|
455
467
|
|
468
|
+
# Aliases allow us to use different descriptions if the same
|
469
|
+
# expression fails in different contexts.
|
470
|
+
alias_method :media_expr, :query_expr
|
471
|
+
alias_method :at_root_query, :query_expr
|
472
|
+
|
456
473
|
def charset_directive(start_pos)
|
457
474
|
tok! STRING
|
458
475
|
name = @scanner[1] || @scanner[2]
|
@@ -490,6 +507,10 @@ module Sass
|
|
490
507
|
end
|
491
508
|
|
492
509
|
def at_root_directive(start_pos)
|
510
|
+
if tok?(/\(/) && (expr = at_root_query)
|
511
|
+
return block(node(Sass::Tree::AtRootNode.new(expr), start_pos), :directive)
|
512
|
+
end
|
513
|
+
|
493
514
|
at_root_node = node(Sass::Tree::AtRootNode.new, start_pos)
|
494
515
|
rule_node = ruleset
|
495
516
|
return block(at_root_node, :stylesheet) unless rule_node
|
@@ -497,6 +518,17 @@ module Sass
|
|
497
518
|
at_root_node
|
498
519
|
end
|
499
520
|
|
521
|
+
def at_root_directive_list
|
522
|
+
return unless (first = tok(IDENT))
|
523
|
+
arr = [first]
|
524
|
+
ss
|
525
|
+
while (e = tok(IDENT))
|
526
|
+
arr << e
|
527
|
+
ss
|
528
|
+
end
|
529
|
+
arr
|
530
|
+
end
|
531
|
+
|
500
532
|
# http://www.w3.org/TR/css3-conditional/
|
501
533
|
def supports_directive(name, start_pos)
|
502
534
|
condition = expr!(:supports_condition)
|
@@ -1146,6 +1178,8 @@ MESSAGE
|
|
1146
1178
|
:media_query => "media query (e.g. print, screen, print and screen)",
|
1147
1179
|
:media_query_list => "media query (e.g. print, screen, print and screen)",
|
1148
1180
|
:media_expr => "media expression (e.g. (min-device-width: 800px))",
|
1181
|
+
:at_root_query => "@at-root query (e.g. (without: media))",
|
1182
|
+
:at_root_directive_list => '* or identifier',
|
1149
1183
|
:pseudo_arg => "expression (e.g. fr, 2n+1)",
|
1150
1184
|
:interp_ident => "identifier",
|
1151
1185
|
:interp_name => "identifier",
|
@@ -1160,9 +1194,13 @@ MESSAGE
|
|
1160
1194
|
:supports_condition_in_parens => "@supports condition (e.g. (display: flexbox))",
|
1161
1195
|
}
|
1162
1196
|
|
1163
|
-
TOK_NAMES = Sass::Util.to_hash(
|
1164
|
-
|
1165
|
-
|
1197
|
+
TOK_NAMES = Sass::Util.to_hash(Sass::SCSS::RX.constants.map do |c|
|
1198
|
+
[Sass::SCSS::RX.const_get(c), c.downcase]
|
1199
|
+
end).merge(
|
1200
|
+
IDENT => "identifier",
|
1201
|
+
/[;}]/ => '";"',
|
1202
|
+
/\b(without|with)\b/ => '"with" or "without"'
|
1203
|
+
)
|
1166
1204
|
|
1167
1205
|
def tok?(rx)
|
1168
1206
|
@scanner.match?(rx)
|
@@ -24,6 +24,23 @@ module Sass
|
|
24
24
|
seq
|
25
25
|
end
|
26
26
|
|
27
|
+
# Parses a static at-root query.
|
28
|
+
#
|
29
|
+
# @return [(Symbol, Array<String>)] The type of the query
|
30
|
+
# (`:with` or `:without`) and the values that are being filtered.
|
31
|
+
# @raise [Sass::SyntaxError] if there's a syntax error in the query,
|
32
|
+
# or if it doesn't take up the entire input string.
|
33
|
+
def parse_static_at_root_query
|
34
|
+
init_scanner!
|
35
|
+
tok!(/\(/); ss
|
36
|
+
type = tok!(/\b(without|with)\b/).to_sym; ss
|
37
|
+
tok!(/:/); ss
|
38
|
+
directives = expr!(:at_root_directive_list); ss
|
39
|
+
tok!(/\)/)
|
40
|
+
expected("@at-root query list") unless @scanner.eos?
|
41
|
+
return type, directives
|
42
|
+
end
|
43
|
+
|
27
44
|
private
|
28
45
|
|
29
46
|
def moz_document_function
|
@@ -7,6 +7,73 @@ module Sass
|
|
7
7
|
#
|
8
8
|
# @see Sass::Tree
|
9
9
|
class AtRootNode < Node
|
10
|
+
# The query for this node (e.g. `(without: media)`),
|
11
|
+
# interspersed with {Sass::Script::Tree::Node}s representing
|
12
|
+
# `#{}`-interpolation. Any adjacent strings will be merged
|
13
|
+
# together.
|
14
|
+
#
|
15
|
+
# This will be nil if the directive didn't have a query. In this
|
16
|
+
# case, {#resolved\_type} will automatically be set to
|
17
|
+
# `:without` and {#resolved\_rule} will automatically be set to `["rule"]`.
|
18
|
+
#
|
19
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
20
|
+
attr_accessor :query
|
21
|
+
|
22
|
+
# The resolved type of this directive. `:with` or `:without`.
|
23
|
+
#
|
24
|
+
# @return [Symbol]
|
25
|
+
attr_accessor :resolved_type
|
26
|
+
|
27
|
+
# The resolved value of this directive -- a list of directives
|
28
|
+
# to either include or exclude.
|
29
|
+
#
|
30
|
+
# @return [Array<String>]
|
31
|
+
attr_accessor :resolved_value
|
32
|
+
|
33
|
+
# The number of additional tabs that the contents of this node
|
34
|
+
# should be indented.
|
35
|
+
#
|
36
|
+
# @return [Number]
|
37
|
+
attr_accessor :tabs
|
38
|
+
|
39
|
+
# Whether the last child of this node should be considered the
|
40
|
+
# end of a group.
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
attr_accessor :group_end
|
44
|
+
|
45
|
+
def initialize(query = nil)
|
46
|
+
super()
|
47
|
+
@query = Sass::Util.strip_string_array(Sass::Util.merge_adjacent_strings(query)) if query
|
48
|
+
@tabs = 0
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns whether or not the given directive is excluded by this
|
52
|
+
# node. `directive` may be "rule", which indicates whether
|
53
|
+
# normal CSS rules should be excluded.
|
54
|
+
#
|
55
|
+
# @param directive [String]
|
56
|
+
# @return [Boolean]
|
57
|
+
def exclude?(directive)
|
58
|
+
if resolved_type == :with
|
59
|
+
return false if resolved_value.include?('all')
|
60
|
+
!resolved_value.include?(directive)
|
61
|
+
else # resolved_type == :without
|
62
|
+
return true if resolved_value.include?('all')
|
63
|
+
resolved_value.include?(directive)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns whether the given node is excluded by this node.
|
68
|
+
#
|
69
|
+
# @param node [Sass::Tree::Node]
|
70
|
+
# @return [Boolean]
|
71
|
+
def exclude_node?(node)
|
72
|
+
return exclude?(node.name.gsub(/^@/, '')) if node.is_a?(Sass::Tree::DirectiveNode)
|
73
|
+
exclude?(node.class.to_s.gsub(/.*::(.*)Node$/, '\1').downcase)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @see Node#bubbles?
|
10
77
|
def bubbles?
|
11
78
|
true
|
12
79
|
end
|
@@ -20,9 +20,16 @@ module Sass::Tree
|
|
20
20
|
# @return [String]
|
21
21
|
attr_accessor :resolved_value
|
22
22
|
|
23
|
+
# @see RuleNode#tabs
|
24
|
+
attr_accessor :tabs
|
25
|
+
|
26
|
+
# @see RuleNode#group_end
|
27
|
+
attr_accessor :group_end
|
28
|
+
|
23
29
|
# @param value [Array<String, Sass::Script::Tree::Node>] See \{#value}
|
24
30
|
def initialize(value)
|
25
31
|
@value = value
|
32
|
+
@tabs = 0
|
26
33
|
super()
|
27
34
|
end
|
28
35
|
|
@@ -38,5 +45,9 @@ module Sass::Tree
|
|
38
45
|
def name
|
39
46
|
value.first.gsub(/ .*$/, '')
|
40
47
|
end
|
48
|
+
|
49
|
+
def bubbles?
|
50
|
+
has_children
|
51
|
+
end
|
41
52
|
end
|
42
53
|
end
|
data/lib/sass/tree/media_node.rb
CHANGED
@@ -21,16 +21,9 @@ module Sass::Tree
|
|
21
21
|
# @return [Sass::Media::QueryList]
|
22
22
|
attr_accessor :resolved_query
|
23
23
|
|
24
|
-
# @see RuleNode#tabs
|
25
|
-
attr_accessor :tabs
|
26
|
-
|
27
|
-
# @see RuleNode#group_end
|
28
|
-
attr_accessor :group_end
|
29
|
-
|
30
24
|
# @param query [Array<String, Sass::Script::Tree::Node>] See \{#query}
|
31
25
|
def initialize(query)
|
32
26
|
@query = query
|
33
|
-
@tabs = 0
|
34
27
|
super('')
|
35
28
|
end
|
36
29
|
|
@@ -51,8 +44,5 @@ module Sass::Tree
|
|
51
44
|
def invisible?
|
52
45
|
children.all? {|c| c.invisible?}
|
53
46
|
end
|
54
|
-
|
55
|
-
# @see Node#bubbles?
|
56
|
-
def bubbles?; true; end
|
57
47
|
end
|
58
48
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
module Sass::Tree
|
2
2
|
# A static node representing a `@supports` rule.
|
3
|
-
# `@supports` rules behave differently from other directives
|
4
|
-
# in that when they're nested within rules,
|
5
|
-
# they bubble up to top-level.
|
6
3
|
#
|
7
4
|
# @see Sass::Tree
|
8
5
|
class SupportsNode < DirectiveNode
|
@@ -16,17 +13,10 @@ module Sass::Tree
|
|
16
13
|
# @return [Sass::Supports::Condition]
|
17
14
|
attr_accessor :condition
|
18
15
|
|
19
|
-
# @see RuleNode#tabs
|
20
|
-
attr_accessor :tabs
|
21
|
-
|
22
|
-
# @see RuleNode#group_end
|
23
|
-
attr_accessor :group_end
|
24
|
-
|
25
16
|
# @param condition [Sass::Supports::Condition] See \{#condition}
|
26
17
|
def initialize(name, condition)
|
27
18
|
@name = name
|
28
19
|
@condition = condition
|
29
|
-
@tabs = 0
|
30
20
|
super('')
|
31
21
|
end
|
32
22
|
|
@@ -44,8 +34,5 @@ module Sass::Tree
|
|
44
34
|
def invisible?
|
45
35
|
children.all? {|c| c.invisible?}
|
46
36
|
end
|
47
|
-
|
48
|
-
# @see Node#bubbles?
|
49
|
-
def bubbles?; true; end
|
50
37
|
end
|
51
38
|
end
|
@@ -156,7 +156,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
156
156
|
end
|
157
157
|
|
158
158
|
def visit_media(node)
|
159
|
-
"#{tab_str}@media #{
|
159
|
+
"#{tab_str}@media #{query_interp_to_src(node.query)}#{yield}"
|
160
160
|
end
|
161
161
|
|
162
162
|
def visit_supports(node)
|
@@ -265,7 +265,9 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
265
265
|
end
|
266
266
|
|
267
267
|
def visit_atroot(node)
|
268
|
-
if node.
|
268
|
+
if node.query
|
269
|
+
"#{tab_str}@at-root #{query_interp_to_src(node.query)}#{yield}"
|
270
|
+
elsif node.children.length == 1 && node.children.first.is_a?(Sass::Tree::RuleNode)
|
269
271
|
rule = node.children.first
|
270
272
|
"#{tab_str}@at-root #{selector_to_src(rule.rule)}#{visit_children(rule)}"
|
271
273
|
else
|
@@ -283,8 +285,8 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
283
285
|
end
|
284
286
|
|
285
287
|
# Like interp_to_src, but removes the unnecessary `#{}` around the keys and
|
286
|
-
# values in
|
287
|
-
def
|
288
|
+
# values in query expressions.
|
289
|
+
def query_interp_to_src(interp)
|
288
290
|
Sass::Util.enum_with_index(interp).map do |r, i|
|
289
291
|
next r if r.is_a?(String)
|
290
292
|
before, after = interp[i - 1], interp[i + 1]
|
@@ -27,11 +27,20 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
27
27
|
# Keeps track of the current parent node.
|
28
28
|
def visit_children(parent)
|
29
29
|
with_parent parent do
|
30
|
-
parent.children =
|
30
|
+
parent.children = visit_children_without_parent(parent)
|
31
31
|
parent
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# Like {#visit\_children}, but doesn't set {#parent}.
|
36
|
+
#
|
37
|
+
# @param node [Sass::Tree::Node]
|
38
|
+
# @return [Array<Sass::Tree::Node>] the flattened results of
|
39
|
+
# visiting all the children of `node`
|
40
|
+
def visit_children_without_parent(node)
|
41
|
+
node.children.map {|c| visit(c)}.flatten
|
42
|
+
end
|
43
|
+
|
35
44
|
MERGEABLE_DIRECTIVES = [Sass::Tree::MediaNode]
|
36
45
|
|
37
46
|
# Runs a block of code with the current parent node
|
@@ -138,8 +147,7 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
138
147
|
|
139
148
|
# Modifies exception backtraces to include the imported file.
|
140
149
|
def visit_import(node)
|
141
|
-
|
142
|
-
node.children.map {|c| visit(c)}.flatten
|
150
|
+
visit_children_without_parent(node)
|
143
151
|
rescue Sass::SyntaxError => e
|
144
152
|
e.modify_backtrace(:filename => node.children.first.filename)
|
145
153
|
e.add_backtrace(:filename => node.filename, :line => node.line)
|
@@ -150,28 +158,46 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
150
158
|
# and merges it with other `@media` directives.
|
151
159
|
def visit_media(node)
|
152
160
|
yield unless bubble(node)
|
153
|
-
|
154
|
-
node.children.
|
155
|
-
|
156
|
-
|
161
|
+
|
162
|
+
bubbled = node.children.select do |n|
|
163
|
+
n.is_a?(Sass::Tree::AtRootNode) || n.is_a?(Sass::Tree::MediaNode)
|
164
|
+
end
|
165
|
+
node.children -= bubbled
|
166
|
+
|
167
|
+
bubbled = bubbled.map do |n|
|
168
|
+
next visit(n) if n.is_a?(Sass::Tree::AtRootNode)
|
169
|
+
# Otherwise, n should be a MediaNode.
|
170
|
+
next [] unless n.resolved_query = n.resolved_query.merge(node.resolved_query)
|
171
|
+
n
|
172
|
+
end.flatten
|
173
|
+
|
174
|
+
(node.children.empty? ? [] : [node]) + bubbled
|
157
175
|
end
|
158
176
|
|
159
177
|
# Bubbles the `@supports` directive up through RuleNodes.
|
160
178
|
def visit_supports(node)
|
161
|
-
|
162
|
-
node
|
179
|
+
visit_directive(node) {yield}
|
163
180
|
end
|
164
181
|
|
165
182
|
# Asserts that all the traced children are valid in their new location.
|
166
183
|
def visit_trace(node)
|
167
|
-
|
168
|
-
node.children.map {|c| visit(c)}.flatten
|
184
|
+
visit_children_without_parent(node)
|
169
185
|
rescue Sass::SyntaxError => e
|
170
186
|
e.modify_backtrace(:mixin => node.name, :filename => node.filename, :line => node.line)
|
171
187
|
e.add_backtrace(:filename => node.filename, :line => node.line)
|
172
188
|
raise e
|
173
189
|
end
|
174
190
|
|
191
|
+
# Bubbles a directive up through RuleNodes.
|
192
|
+
def visit_directive(node)
|
193
|
+
return yield unless node.has_children
|
194
|
+
yield unless (bubbled = bubble(node))
|
195
|
+
at_roots = node.children.select {|n| n.is_a?(Sass::Tree::AtRootNode)}
|
196
|
+
node.children -= at_roots
|
197
|
+
at_roots.map! {|n| visit(n)}.flatten
|
198
|
+
(bubbled && node.children.empty? ? [] : [node]) + at_roots
|
199
|
+
end
|
200
|
+
|
175
201
|
# Converts nested properties into flat properties
|
176
202
|
# and updates the indentation of the prop node based on the nesting level.
|
177
203
|
def visit_prop(node)
|
@@ -199,6 +225,8 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
199
225
|
rules = node.children.select {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles?}
|
200
226
|
props = node.children.reject {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles? || c.invisible?}
|
201
227
|
|
228
|
+
rules.map {|c| c.is_a?(Sass::Tree::AtRootNode) ? visit(c) : c}.flatten
|
229
|
+
|
202
230
|
unless props.empty?
|
203
231
|
node.children = props
|
204
232
|
rules.each {|r| r.tabs += 1} if node.style == :nested
|
@@ -211,7 +239,19 @@ class Sass::Tree::Visitors::Cssize < Sass::Tree::Visitors::Base
|
|
211
239
|
end
|
212
240
|
|
213
241
|
def visit_atroot(node)
|
214
|
-
|
242
|
+
if @parent_directives.any? {|n| node.exclude_node?(n)}
|
243
|
+
return node if node.exclude_node?(parent)
|
244
|
+
|
245
|
+
new_rule = parent.dup
|
246
|
+
new_rule.children = node.children
|
247
|
+
node.children = [new_rule]
|
248
|
+
return node
|
249
|
+
end
|
250
|
+
|
251
|
+
results = visit_children_without_parent(node)
|
252
|
+
results.each {|n| n.tabs += node.tabs}
|
253
|
+
results.last.group_end = node.group_end unless results.empty?
|
254
|
+
results
|
215
255
|
end
|
216
256
|
|
217
257
|
private
|
@@ -380,11 +380,12 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
380
380
|
# Runs SassScript interpolation in the selector,
|
381
381
|
# and then parses the result into a {Sass::Selector::CommaSequence}.
|
382
382
|
def visit_rule(node)
|
383
|
-
|
383
|
+
old_at_root_without_rule, @at_root_without_rule = @at_root_without_rule, false
|
384
384
|
parser = Sass::SCSS::StaticParser.new(run_interp(node.rule),
|
385
385
|
node.filename, node.options[:importer], node.line)
|
386
386
|
node.parsed_rules ||= parser.parse_selector
|
387
|
-
node.resolved_rules = node.parsed_rules.resolve_parent_refs(
|
387
|
+
node.resolved_rules = node.parsed_rules.resolve_parent_refs(
|
388
|
+
@environment.selector, !old_at_root_without_rule)
|
388
389
|
node.stack_trace = @environment.stack.to_s if node.options[:trace_selectors]
|
389
390
|
with_environment Sass::Environment.new(@environment, node.options) do
|
390
391
|
@environment.selector = node.resolved_rules
|
@@ -392,16 +393,25 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
392
393
|
end
|
393
394
|
node
|
394
395
|
ensure
|
395
|
-
@
|
396
|
+
@at_root_without_rule = old_at_root_without_rule
|
396
397
|
end
|
397
398
|
|
398
399
|
# Sets a variable that indicates that the first level of rule nodes
|
399
400
|
# shouldn't include the parent selector by default.
|
400
401
|
def visit_atroot(node)
|
401
|
-
|
402
|
-
|
402
|
+
if node.query
|
403
|
+
parser = Sass::SCSS::StaticParser.new(run_interp(node.query),
|
404
|
+
node.filename, node.options[:importer], node.line)
|
405
|
+
node.resolved_type, node.resolved_value = parser.parse_static_at_root_query
|
406
|
+
else
|
407
|
+
node.resolved_type, node.resolved_value = :without, ['rule']
|
408
|
+
end
|
409
|
+
|
410
|
+
old_at_root_without_rule = @at_root_without_rule
|
411
|
+
@at_root_without_rule = true if node.exclude?('rule')
|
412
|
+
yield
|
403
413
|
ensure
|
404
|
-
@
|
414
|
+
@at_root_without_rule = old_at_root_without_rule
|
405
415
|
end
|
406
416
|
|
407
417
|
# Loads the new variable value into the environment.
|
@@ -440,7 +450,6 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
|
|
440
450
|
def visit_directive(node)
|
441
451
|
node.resolved_value = run_interp(node.value)
|
442
452
|
with_environment Sass::Environment.new(@environment) do
|
443
|
-
@environment.no_selector!
|
444
453
|
node.children = node.children.map {|c| visit(c)}.flatten
|
445
454
|
node
|
446
455
|
end
|
@@ -1726,6 +1726,34 @@ SASS
|
|
1726
1726
|
SCSS
|
1727
1727
|
end
|
1728
1728
|
|
1729
|
+
def test_at_root_without
|
1730
|
+
assert_scss_to_sass <<SASS, <<SCSS
|
1731
|
+
.foo
|
1732
|
+
@at-root (without: media rule)
|
1733
|
+
a: b
|
1734
|
+
SASS
|
1735
|
+
.foo {
|
1736
|
+
@at-root (without: media rule) {
|
1737
|
+
a: b;
|
1738
|
+
}
|
1739
|
+
}
|
1740
|
+
SCSS
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
def test_at_root_with
|
1744
|
+
assert_scss_to_sass <<SASS, <<SCSS
|
1745
|
+
.foo
|
1746
|
+
@at-root (with: media rule)
|
1747
|
+
a: b
|
1748
|
+
SASS
|
1749
|
+
.foo {
|
1750
|
+
@at-root (with: media rule) {
|
1751
|
+
a: b;
|
1752
|
+
}
|
1753
|
+
}
|
1754
|
+
SCSS
|
1755
|
+
end
|
1756
|
+
|
1729
1757
|
def test_function_var_kwargs_with_list
|
1730
1758
|
assert_scss_to_sass <<SASS, <<SCSS
|
1731
1759
|
@function foo($a: b, $c: d)
|
data/test/sass/engine_test.rb
CHANGED
@@ -2476,6 +2476,19 @@ CSS
|
|
2476
2476
|
SASS
|
2477
2477
|
end
|
2478
2478
|
|
2479
|
+
def test_at_root_with_query
|
2480
|
+
assert_equal <<CSS, render(<<SASS)
|
2481
|
+
.foo .bar {
|
2482
|
+
a: b; }
|
2483
|
+
CSS
|
2484
|
+
.foo
|
2485
|
+
@media screen
|
2486
|
+
@at-root (without: media)
|
2487
|
+
.bar
|
2488
|
+
a: b
|
2489
|
+
SASS
|
2490
|
+
end
|
2491
|
+
|
2479
2492
|
# Regression tests
|
2480
2493
|
|
2481
2494
|
def test_list_separator_with_arg_list
|
data/test/sass/extend_test.rb
CHANGED
data/test/sass/scss/css_test.rb
CHANGED
data/test/sass/scss/scss_test.rb
CHANGED
@@ -563,6 +563,20 @@ foo bar {
|
|
563
563
|
SCSS
|
564
564
|
end
|
565
565
|
|
566
|
+
def test_unknown_directive_bubbling
|
567
|
+
assert_equal(<<CSS, render(<<SCSS, :style => :nested))
|
568
|
+
@fblthp {
|
569
|
+
.foo .bar {
|
570
|
+
a: b; } }
|
571
|
+
CSS
|
572
|
+
.foo {
|
573
|
+
@fblthp {
|
574
|
+
.bar {a: b}
|
575
|
+
}
|
576
|
+
}
|
577
|
+
SCSS
|
578
|
+
end
|
579
|
+
|
566
580
|
## Namespace Properties
|
567
581
|
|
568
582
|
def test_namespace_properties
|
@@ -2153,21 +2167,6 @@ CSS
|
|
2153
2167
|
SCSS
|
2154
2168
|
end
|
2155
2169
|
|
2156
|
-
def test_at_root_in_nested_unknown_directive
|
2157
|
-
assert_equal <<CSS, render(<<SCSS)
|
2158
|
-
.foo {
|
2159
|
-
@fblthp {
|
2160
|
-
.bar {
|
2161
|
-
a: b; } } }
|
2162
|
-
CSS
|
2163
|
-
.foo {
|
2164
|
-
@fblthp {
|
2165
|
-
@at-root .bar {a: b}
|
2166
|
-
}
|
2167
|
-
}
|
2168
|
-
SCSS
|
2169
|
-
end
|
2170
|
-
|
2171
2170
|
def test_at_root_with_parent_ref
|
2172
2171
|
assert_equal <<CSS, render(<<SCSS)
|
2173
2172
|
.foo {
|
@@ -2213,6 +2212,308 @@ CSS
|
|
2213
2212
|
SCSS
|
2214
2213
|
end
|
2215
2214
|
|
2215
|
+
## @at-root (...)
|
2216
|
+
|
2217
|
+
def test_at_root_without_media
|
2218
|
+
assert_equal <<CSS, render(<<SCSS)
|
2219
|
+
.foo .bar {
|
2220
|
+
a: b; }
|
2221
|
+
CSS
|
2222
|
+
.foo {
|
2223
|
+
@media screen {
|
2224
|
+
@at-root (without: media) {
|
2225
|
+
.bar {
|
2226
|
+
a: b;
|
2227
|
+
}
|
2228
|
+
}
|
2229
|
+
}
|
2230
|
+
}
|
2231
|
+
SCSS
|
2232
|
+
end
|
2233
|
+
|
2234
|
+
def test_at_root_without_supports
|
2235
|
+
assert_equal <<CSS, render(<<SCSS)
|
2236
|
+
.foo .bar {
|
2237
|
+
a: b; }
|
2238
|
+
CSS
|
2239
|
+
.foo {
|
2240
|
+
@supports (foo: bar) {
|
2241
|
+
@at-root (without: supports) {
|
2242
|
+
.bar {
|
2243
|
+
a: b;
|
2244
|
+
}
|
2245
|
+
}
|
2246
|
+
}
|
2247
|
+
}
|
2248
|
+
SCSS
|
2249
|
+
end
|
2250
|
+
|
2251
|
+
def test_at_root_without_rule
|
2252
|
+
assert_equal <<CSS, render(<<SCSS)
|
2253
|
+
@media screen {
|
2254
|
+
.bar {
|
2255
|
+
a: b; } }
|
2256
|
+
CSS
|
2257
|
+
.foo {
|
2258
|
+
@media screen {
|
2259
|
+
@at-root (without: rule) {
|
2260
|
+
.bar {
|
2261
|
+
a: b;
|
2262
|
+
}
|
2263
|
+
}
|
2264
|
+
}
|
2265
|
+
}
|
2266
|
+
SCSS
|
2267
|
+
end
|
2268
|
+
|
2269
|
+
def test_at_root_without_unknown_directive
|
2270
|
+
assert_equal <<CSS, render(<<SCSS)
|
2271
|
+
.foo .bar {
|
2272
|
+
a: b; }
|
2273
|
+
CSS
|
2274
|
+
.foo {
|
2275
|
+
@fblthp {
|
2276
|
+
@at-root (without: fblthp) {
|
2277
|
+
.bar {
|
2278
|
+
a: b;
|
2279
|
+
}
|
2280
|
+
}
|
2281
|
+
}
|
2282
|
+
}
|
2283
|
+
SCSS
|
2284
|
+
end
|
2285
|
+
|
2286
|
+
def test_at_root_without_multiple
|
2287
|
+
assert_equal <<CSS, render(<<SCSS)
|
2288
|
+
@supports (foo: bar) {
|
2289
|
+
.bar {
|
2290
|
+
a: b; } }
|
2291
|
+
CSS
|
2292
|
+
.foo {
|
2293
|
+
@media screen {
|
2294
|
+
@supports (foo: bar) {
|
2295
|
+
@at-root (without: media rule) {
|
2296
|
+
.bar {
|
2297
|
+
a: b;
|
2298
|
+
}
|
2299
|
+
}
|
2300
|
+
}
|
2301
|
+
}
|
2302
|
+
}
|
2303
|
+
SCSS
|
2304
|
+
end
|
2305
|
+
|
2306
|
+
def test_at_root_without_all
|
2307
|
+
assert_equal <<CSS, render(<<SCSS)
|
2308
|
+
.bar {
|
2309
|
+
a: b; }
|
2310
|
+
CSS
|
2311
|
+
.foo {
|
2312
|
+
@supports (foo: bar) {
|
2313
|
+
@fblthp {
|
2314
|
+
@at-root (without: all) {
|
2315
|
+
.bar {
|
2316
|
+
a: b;
|
2317
|
+
}
|
2318
|
+
}
|
2319
|
+
}
|
2320
|
+
}
|
2321
|
+
}
|
2322
|
+
SCSS
|
2323
|
+
end
|
2324
|
+
|
2325
|
+
def test_at_root_with_media
|
2326
|
+
assert_equal <<CSS, render(<<SCSS)
|
2327
|
+
@media screen {
|
2328
|
+
.bar {
|
2329
|
+
a: b; } }
|
2330
|
+
CSS
|
2331
|
+
.foo {
|
2332
|
+
@media screen {
|
2333
|
+
@fblthp {
|
2334
|
+
@supports (foo: bar) {
|
2335
|
+
@at-root (with: media) {
|
2336
|
+
.bar {
|
2337
|
+
a: b;
|
2338
|
+
}
|
2339
|
+
}
|
2340
|
+
}
|
2341
|
+
}
|
2342
|
+
}
|
2343
|
+
}
|
2344
|
+
SCSS
|
2345
|
+
end
|
2346
|
+
|
2347
|
+
def test_at_root_with_rule
|
2348
|
+
assert_equal <<CSS, render(<<SCSS)
|
2349
|
+
.foo .bar {
|
2350
|
+
a: b; }
|
2351
|
+
CSS
|
2352
|
+
.foo {
|
2353
|
+
@media screen {
|
2354
|
+
@fblthp {
|
2355
|
+
@supports (foo: bar) {
|
2356
|
+
@at-root (with: rule) {
|
2357
|
+
.bar {
|
2358
|
+
a: b;
|
2359
|
+
}
|
2360
|
+
}
|
2361
|
+
}
|
2362
|
+
}
|
2363
|
+
}
|
2364
|
+
}
|
2365
|
+
SCSS
|
2366
|
+
end
|
2367
|
+
|
2368
|
+
def test_at_root_with_supports
|
2369
|
+
assert_equal <<CSS, render(<<SCSS)
|
2370
|
+
@supports (foo: bar) {
|
2371
|
+
.bar {
|
2372
|
+
a: b; } }
|
2373
|
+
CSS
|
2374
|
+
.foo {
|
2375
|
+
@media screen {
|
2376
|
+
@fblthp {
|
2377
|
+
@supports (foo: bar) {
|
2378
|
+
@at-root (with: supports) {
|
2379
|
+
.bar {
|
2380
|
+
a: b;
|
2381
|
+
}
|
2382
|
+
}
|
2383
|
+
}
|
2384
|
+
}
|
2385
|
+
}
|
2386
|
+
}
|
2387
|
+
SCSS
|
2388
|
+
end
|
2389
|
+
|
2390
|
+
def test_at_root_with_unknown_directive
|
2391
|
+
assert_equal <<CSS, render(<<SCSS)
|
2392
|
+
@fblthp {
|
2393
|
+
.bar {
|
2394
|
+
a: b; } }
|
2395
|
+
CSS
|
2396
|
+
.foo {
|
2397
|
+
@media screen {
|
2398
|
+
@fblthp {
|
2399
|
+
@supports (foo: bar) {
|
2400
|
+
@at-root (with: fblthp) {
|
2401
|
+
.bar {
|
2402
|
+
a: b;
|
2403
|
+
}
|
2404
|
+
}
|
2405
|
+
}
|
2406
|
+
}
|
2407
|
+
}
|
2408
|
+
}
|
2409
|
+
SCSS
|
2410
|
+
end
|
2411
|
+
|
2412
|
+
def test_at_root_with_multiple
|
2413
|
+
assert_equal <<CSS, render(<<SCSS)
|
2414
|
+
@media screen {
|
2415
|
+
.foo .bar {
|
2416
|
+
a: b; } }
|
2417
|
+
CSS
|
2418
|
+
.foo {
|
2419
|
+
@media screen {
|
2420
|
+
@fblthp {
|
2421
|
+
@supports (foo: bar) {
|
2422
|
+
@at-root (with: media rule) {
|
2423
|
+
.bar {
|
2424
|
+
a: b;
|
2425
|
+
}
|
2426
|
+
}
|
2427
|
+
}
|
2428
|
+
}
|
2429
|
+
}
|
2430
|
+
}
|
2431
|
+
SCSS
|
2432
|
+
end
|
2433
|
+
|
2434
|
+
def test_at_root_with_all
|
2435
|
+
assert_equal <<CSS, render(<<SCSS)
|
2436
|
+
@media screen {
|
2437
|
+
@fblthp {
|
2438
|
+
@supports (foo: bar) {
|
2439
|
+
.foo .bar {
|
2440
|
+
a: b; } } } }
|
2441
|
+
CSS
|
2442
|
+
.foo {
|
2443
|
+
@media screen {
|
2444
|
+
@fblthp {
|
2445
|
+
@supports (foo: bar) {
|
2446
|
+
@at-root (with: all) {
|
2447
|
+
.bar {
|
2448
|
+
a: b;
|
2449
|
+
}
|
2450
|
+
}
|
2451
|
+
}
|
2452
|
+
}
|
2453
|
+
}
|
2454
|
+
}
|
2455
|
+
SCSS
|
2456
|
+
end
|
2457
|
+
|
2458
|
+
def test_at_root_dynamic_values
|
2459
|
+
assert_equal <<CSS, render(<<SCSS)
|
2460
|
+
@media screen {
|
2461
|
+
.bar {
|
2462
|
+
a: b; } }
|
2463
|
+
CSS
|
2464
|
+
$key: with;
|
2465
|
+
$value: media;
|
2466
|
+
.foo {
|
2467
|
+
@media screen {
|
2468
|
+
@at-root ($key: $value) {
|
2469
|
+
.bar {
|
2470
|
+
a: b;
|
2471
|
+
}
|
2472
|
+
}
|
2473
|
+
}
|
2474
|
+
}
|
2475
|
+
SCSS
|
2476
|
+
end
|
2477
|
+
|
2478
|
+
def test_at_root_interpolated_query
|
2479
|
+
assert_equal <<CSS, render(<<SCSS)
|
2480
|
+
@media screen {
|
2481
|
+
.bar {
|
2482
|
+
a: b; } }
|
2483
|
+
CSS
|
2484
|
+
.foo {
|
2485
|
+
@media screen {
|
2486
|
+
@at-root (\#{"with: media"}) {
|
2487
|
+
.bar {
|
2488
|
+
a: b;
|
2489
|
+
}
|
2490
|
+
}
|
2491
|
+
}
|
2492
|
+
}
|
2493
|
+
SCSS
|
2494
|
+
end
|
2495
|
+
|
2496
|
+
def test_at_root_plus_extend
|
2497
|
+
assert_equal <<CSS, render(<<SCSS)
|
2498
|
+
.foo .bar {
|
2499
|
+
a: b; }
|
2500
|
+
CSS
|
2501
|
+
%base {
|
2502
|
+
a: b;
|
2503
|
+
}
|
2504
|
+
|
2505
|
+
.foo {
|
2506
|
+
@media screen {
|
2507
|
+
@at-root (without: media) {
|
2508
|
+
.bar {
|
2509
|
+
@extend %base;
|
2510
|
+
}
|
2511
|
+
}
|
2512
|
+
}
|
2513
|
+
}
|
2514
|
+
SCSS
|
2515
|
+
end
|
2516
|
+
|
2216
2517
|
## Selector Script
|
2217
2518
|
|
2218
2519
|
def test_selector_script
|
@@ -2602,57 +2903,6 @@ SCSS
|
|
2602
2903
|
|
2603
2904
|
# Regression
|
2604
2905
|
|
2605
|
-
def test_nested_unknown_directive
|
2606
|
-
assert_equal(<<CSS, render(<<SCSS, :style => :nested))
|
2607
|
-
.foo {
|
2608
|
-
@fblthp {
|
2609
|
-
.bar {
|
2610
|
-
a: b; } } }
|
2611
|
-
CSS
|
2612
|
-
.foo {
|
2613
|
-
@fblthp {
|
2614
|
-
.bar {a: b}
|
2615
|
-
}
|
2616
|
-
}
|
2617
|
-
SCSS
|
2618
|
-
|
2619
|
-
assert_equal(<<CSS, render(<<SCSS, :style => :compressed))
|
2620
|
-
.foo{@fblthp{.bar{a:b}}}
|
2621
|
-
CSS
|
2622
|
-
.foo {
|
2623
|
-
@fblthp {
|
2624
|
-
.bar {a: b}
|
2625
|
-
}
|
2626
|
-
}
|
2627
|
-
SCSS
|
2628
|
-
|
2629
|
-
assert_equal(<<CSS, render(<<SCSS, :style => :compact))
|
2630
|
-
.foo { @fblthp { .bar { a: b; } } }
|
2631
|
-
CSS
|
2632
|
-
.foo {
|
2633
|
-
@fblthp {
|
2634
|
-
.bar {a: b}
|
2635
|
-
}
|
2636
|
-
}
|
2637
|
-
SCSS
|
2638
|
-
|
2639
|
-
assert_equal(<<CSS, render(<<SCSS, :style => :expanded))
|
2640
|
-
.foo {
|
2641
|
-
@fblthp {
|
2642
|
-
.bar {
|
2643
|
-
a: b;
|
2644
|
-
}
|
2645
|
-
}
|
2646
|
-
}
|
2647
|
-
CSS
|
2648
|
-
.foo {
|
2649
|
-
@fblthp {
|
2650
|
-
.bar {a: b}
|
2651
|
-
}
|
2652
|
-
}
|
2653
|
-
SCSS
|
2654
|
-
end
|
2655
|
-
|
2656
2906
|
def test_loud_comment_in_compressed_mode
|
2657
2907
|
assert_equal(<<CSS, render(<<SCSS))
|
2658
2908
|
/*! foo */
|
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:
|
4
|
+
hash: 592302085
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 3
|
9
9
|
- 0
|
10
10
|
- alpha
|
11
|
-
-
|
12
|
-
version: 3.3.0.alpha.
|
11
|
+
- 388
|
12
|
+
version: 3.3.0.alpha.388
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Nathan Weizenbaum
|