sass 3.2.7 → 3.3.0.rc.1
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/MIT-LICENSE +2 -2
- data/README.md +14 -2
- data/Rakefile +25 -1
- data/VERSION +1 -1
- data/VERSION_DATE +1 -1
- data/VERSION_NAME +1 -1
- data/lib/sass/cache_stores/base.rb +4 -2
- data/lib/sass/cache_stores/chain.rb +2 -1
- data/lib/sass/cache_stores/filesystem.rb +2 -6
- data/lib/sass/cache_stores/memory.rb +1 -1
- data/lib/sass/cache_stores/null.rb +2 -2
- data/lib/sass/callbacks.rb +1 -0
- data/lib/sass/css.rb +10 -10
- data/lib/sass/engine.rb +403 -150
- data/lib/sass/environment.rb +136 -57
- data/lib/sass/error.rb +7 -7
- data/lib/sass/exec.rb +123 -39
- data/lib/sass/features.rb +41 -0
- data/lib/sass/importers/base.rb +33 -2
- data/lib/sass/importers/deprecated_path.rb +45 -0
- data/lib/sass/importers/filesystem.rb +25 -14
- data/lib/sass/importers.rb +1 -0
- data/lib/sass/logger/base.rb +3 -3
- data/lib/sass/logger/log_level.rb +4 -6
- data/lib/sass/media.rb +19 -19
- data/lib/sass/plugin/compiler.rb +141 -101
- data/lib/sass/plugin/configuration.rb +18 -22
- data/lib/sass/plugin/merb.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +24 -8
- data/lib/sass/plugin.rb +4 -2
- data/lib/sass/repl.rb +3 -3
- data/lib/sass/script/css_lexer.rb +9 -4
- data/lib/sass/script/css_parser.rb +6 -2
- data/lib/sass/script/functions.rb +1343 -590
- data/lib/sass/script/lexer.rb +84 -52
- data/lib/sass/script/parser.rb +217 -97
- data/lib/sass/script/tree/funcall.rb +290 -0
- data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +34 -13
- data/lib/sass/script/tree/list_literal.rb +80 -0
- data/lib/sass/script/tree/literal.rb +47 -0
- data/lib/sass/script/tree/map_literal.rb +64 -0
- data/lib/sass/script/{node.rb → tree/node.rb} +22 -12
- data/lib/sass/script/{operation.rb → tree/operation.rb} +17 -25
- data/lib/sass/script/tree/selector.rb +30 -0
- data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +5 -4
- data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +14 -9
- data/lib/sass/script/tree/variable.rb +57 -0
- data/lib/sass/script/tree.rb +16 -0
- data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +4 -24
- data/lib/sass/script/value/base.rb +248 -0
- data/lib/sass/script/value/bool.rb +36 -0
- data/lib/sass/script/{color.rb → value/color.rb} +239 -195
- data/lib/sass/script/value/helpers.rb +155 -0
- data/lib/sass/script/value/list.rb +119 -0
- data/lib/sass/script/value/map.rb +70 -0
- data/lib/sass/script/value/null.rb +45 -0
- data/lib/sass/script/{number.rb → value/number.rb} +91 -65
- data/lib/sass/script/{string.rb → value/string.rb} +9 -11
- data/lib/sass/script/value.rb +11 -0
- data/lib/sass/script.rb +35 -8
- data/lib/sass/scss/css_parser.rb +2 -1
- data/lib/sass/scss/parser.rb +338 -170
- data/lib/sass/scss/rx.rb +5 -6
- data/lib/sass/scss/script_lexer.rb +1 -0
- data/lib/sass/scss/script_parser.rb +1 -0
- data/lib/sass/scss/static_parser.rb +23 -6
- data/lib/sass/selector/abstract_sequence.rb +2 -2
- data/lib/sass/selector/comma_sequence.rb +21 -16
- data/lib/sass/selector/sequence.rb +60 -34
- data/lib/sass/selector/simple.rb +11 -12
- data/lib/sass/selector/simple_sequence.rb +55 -33
- data/lib/sass/selector.rb +52 -48
- data/lib/sass/source/map.rb +211 -0
- data/lib/sass/source/position.rb +39 -0
- data/lib/sass/source/range.rb +41 -0
- data/lib/sass/stack.rb +120 -0
- data/lib/sass/supports.rb +12 -13
- data/lib/sass/tree/at_root_node.rb +82 -0
- data/lib/sass/tree/comment_node.rb +3 -3
- data/lib/sass/tree/css_import_node.rb +11 -11
- data/lib/sass/tree/debug_node.rb +2 -2
- data/lib/sass/tree/directive_node.rb +13 -2
- data/lib/sass/tree/each_node.rb +8 -8
- data/lib/sass/tree/extend_node.rb +13 -6
- data/lib/sass/tree/for_node.rb +4 -4
- data/lib/sass/tree/function_node.rb +5 -4
- data/lib/sass/tree/if_node.rb +1 -1
- data/lib/sass/tree/import_node.rb +4 -5
- data/lib/sass/tree/media_node.rb +4 -14
- data/lib/sass/tree/mixin_def_node.rb +4 -4
- data/lib/sass/tree/mixin_node.rb +21 -8
- data/lib/sass/tree/node.rb +29 -12
- data/lib/sass/tree/prop_node.rb +38 -18
- data/lib/sass/tree/return_node.rb +3 -2
- data/lib/sass/tree/root_node.rb +19 -3
- data/lib/sass/tree/rule_node.rb +25 -17
- data/lib/sass/tree/supports_node.rb +0 -13
- data/lib/sass/tree/trace_node.rb +2 -1
- data/lib/sass/tree/variable_node.rb +9 -3
- data/lib/sass/tree/visitors/base.rb +6 -6
- data/lib/sass/tree/visitors/check_nesting.rb +12 -9
- data/lib/sass/tree/visitors/convert.rb +63 -38
- data/lib/sass/tree/visitors/cssize.rb +63 -23
- data/lib/sass/tree/visitors/deep_copy.rb +6 -5
- data/lib/sass/tree/visitors/extend.rb +7 -7
- data/lib/sass/tree/visitors/perform.rb +256 -151
- data/lib/sass/tree/visitors/set_options.rb +6 -6
- data/lib/sass/tree/visitors/to_css.rb +231 -81
- data/lib/sass/tree/warn_node.rb +2 -2
- data/lib/sass/tree/while_node.rb +2 -2
- data/lib/sass/util/multibyte_string_scanner.rb +2 -0
- data/lib/sass/util/normalized_map.rb +65 -0
- data/lib/sass/util/ordered_hash.rb +188 -0
- data/lib/sass/util/subset_map.rb +3 -2
- data/lib/sass/util/test.rb +9 -0
- data/lib/sass/util.rb +220 -34
- data/lib/sass/version.rb +9 -9
- data/lib/sass.rb +14 -7
- data/test/sass/compiler_test.rb +213 -0
- data/test/sass/conversion_test.rb +235 -9
- data/test/sass/engine_test.rb +230 -60
- data/test/sass/exec_test.rb +86 -0
- data/test/sass/extend_test.rb +215 -147
- data/test/sass/functions_test.rb +584 -99
- data/test/sass/importer_test.rb +165 -17
- data/test/sass/plugin_test.rb +19 -13
- data/test/sass/script_conversion_test.rb +40 -0
- data/test/sass/script_test.rb +231 -21
- data/test/sass/scss/css_test.rb +14 -5
- data/test/sass/scss/scss_test.rb +1266 -66
- data/test/sass/source_map_test.rb +879 -0
- data/test/sass/templates/bork5.sass +3 -0
- data/test/sass/util/normalized_map_test.rb +30 -0
- data/test/sass/util_test.rb +90 -0
- data/test/sass/value_helpers_test.rb +181 -0
- data/test/test_helper.rb +7 -2
- metadata +316 -291
- data/lib/sass/script/bool.rb +0 -18
- data/lib/sass/script/funcall.rb +0 -231
- data/lib/sass/script/list.rb +0 -84
- data/lib/sass/script/literal.rb +0 -239
- data/lib/sass/script/null.rb +0 -34
- data/lib/sass/script/variable.rb +0 -58
- data/test/Gemfile +0 -3
- data/vendor/listen/CHANGELOG.md +0 -221
- data/vendor/listen/CONTRIBUTING.md +0 -38
- data/vendor/listen/Gemfile +0 -30
- data/vendor/listen/Guardfile +0 -8
- data/vendor/listen/LICENSE +0 -20
- data/vendor/listen/README.md +0 -315
- data/vendor/listen/Rakefile +0 -47
- data/vendor/listen/Vagrantfile +0 -96
- data/vendor/listen/lib/listen/adapter.rb +0 -214
- data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
- data/vendor/listen/lib/listen/adapters/darwin.rb +0 -85
- data/vendor/listen/lib/listen/adapters/linux.rb +0 -113
- data/vendor/listen/lib/listen/adapters/polling.rb +0 -67
- data/vendor/listen/lib/listen/adapters/windows.rb +0 -87
- data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
- data/vendor/listen/lib/listen/directory_record.rb +0 -371
- data/vendor/listen/lib/listen/listener.rb +0 -225
- data/vendor/listen/lib/listen/multi_listener.rb +0 -143
- data/vendor/listen/lib/listen/turnstile.rb +0 -28
- data/vendor/listen/lib/listen/version.rb +0 -3
- data/vendor/listen/lib/listen.rb +0 -40
- data/vendor/listen/listen.gemspec +0 -22
- data/vendor/listen/spec/listen/adapter_spec.rb +0 -183
- data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
- data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
- data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
- data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
- data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1225
- data/vendor/listen/spec/listen/listener_spec.rb +0 -169
- data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
- data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/vendor/listen/spec/listen_spec.rb +0 -73
- data/vendor/listen/spec/spec_helper.rb +0 -21
- data/vendor/listen/spec/support/adapter_helper.rb +0 -629
- data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
- data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/vendor/listen/spec/support/listeners_helper.rb +0 -156
- data/vendor/listen/spec/support/platform_helper.rb +0 -15
data/lib/sass/tree/prop_node.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
module Sass::Tree
|
|
2
|
-
# A static node
|
|
2
|
+
# A static node representing a CSS property.
|
|
3
3
|
#
|
|
4
4
|
# @see Sass::Tree
|
|
5
5
|
class PropNode < Node
|
|
6
6
|
# The name of the property,
|
|
7
|
-
# interspersed with {Sass::Script::Node}s
|
|
7
|
+
# interspersed with {Sass::Script::Tree::Node}s
|
|
8
8
|
# representing `#{}`-interpolation.
|
|
9
9
|
# Any adjacent strings will be merged together.
|
|
10
10
|
#
|
|
11
|
-
# @return [Array<String, Sass::Script::Node>]
|
|
11
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
|
12
12
|
attr_accessor :name
|
|
13
13
|
|
|
14
14
|
# The name of the property
|
|
@@ -20,7 +20,7 @@ module Sass::Tree
|
|
|
20
20
|
|
|
21
21
|
# The value of the property.
|
|
22
22
|
#
|
|
23
|
-
# @return [Sass::Script::Node]
|
|
23
|
+
# @return [Sass::Script::Tree::Node]
|
|
24
24
|
attr_accessor :value
|
|
25
25
|
|
|
26
26
|
# The value of the property
|
|
@@ -42,8 +42,18 @@ module Sass::Tree
|
|
|
42
42
|
# @return [Fixnum]
|
|
43
43
|
attr_accessor :tabs
|
|
44
44
|
|
|
45
|
-
#
|
|
46
|
-
#
|
|
45
|
+
# The source range in which the property name appears.
|
|
46
|
+
#
|
|
47
|
+
# @return [Sass::Source::Range]
|
|
48
|
+
attr_accessor :name_source_range
|
|
49
|
+
|
|
50
|
+
# The source range in which the property value appears.
|
|
51
|
+
#
|
|
52
|
+
# @return [Sass::Source::Range]
|
|
53
|
+
attr_accessor :value_source_range
|
|
54
|
+
|
|
55
|
+
# @param name [Array<String, Sass::Script::Tree::Node>] See \{#name}
|
|
56
|
+
# @param value [Sass::Script::Tree::Node] See \{#value}
|
|
47
57
|
# @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
|
|
48
58
|
# `:old` if it uses `:a b`-style syntax
|
|
49
59
|
def initialize(name, value, prop_syntax)
|
|
@@ -70,7 +80,13 @@ module Sass::Tree
|
|
|
70
80
|
#
|
|
71
81
|
# @return [String] The message
|
|
72
82
|
def pseudo_class_selector_message
|
|
73
|
-
|
|
83
|
+
if @prop_syntax == :new ||
|
|
84
|
+
!value.is_a?(Sass::Script::Tree::Literal) ||
|
|
85
|
+
!value.value.is_a?(Sass::Script::Value::String) ||
|
|
86
|
+
!value.value.value.empty?
|
|
87
|
+
return ""
|
|
88
|
+
end
|
|
89
|
+
|
|
74
90
|
"\nIf #{declaration.dump} should be a selector, use \"\\#{declaration}\" instead."
|
|
75
91
|
end
|
|
76
92
|
|
|
@@ -83,7 +99,8 @@ module Sass::Tree
|
|
|
83
99
|
def declaration(opts = {:old => @prop_syntax == :old}, fmt = :sass)
|
|
84
100
|
name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass(opts)}}"}.join
|
|
85
101
|
if name[0] == ?:
|
|
86
|
-
raise Sass::SyntaxError.new("The \"#{name}: #{self.class.val_to_sass(value, opts)}\"
|
|
102
|
+
raise Sass::SyntaxError.new("The \"#{name}: #{self.class.val_to_sass(value, opts)}\"" +
|
|
103
|
+
" hack is not allowed in the Sass indented syntax")
|
|
87
104
|
end
|
|
88
105
|
|
|
89
106
|
old = opts[:old] && fmt == :sass
|
|
@@ -104,7 +121,8 @@ module Sass::Tree
|
|
|
104
121
|
def check!
|
|
105
122
|
if @options[:property_syntax] && @options[:property_syntax] != @prop_syntax
|
|
106
123
|
raise Sass::SyntaxError.new(
|
|
107
|
-
"Illegal property syntax: can't use #{@prop_syntax} syntax when
|
|
124
|
+
"Illegal property syntax: can't use #{@prop_syntax} syntax when " +
|
|
125
|
+
":property_syntax => #{@options[:property_syntax].inspect} is set.")
|
|
108
126
|
end
|
|
109
127
|
end
|
|
110
128
|
|
|
@@ -117,34 +135,36 @@ module Sass::Tree
|
|
|
117
135
|
private
|
|
118
136
|
|
|
119
137
|
def val_to_sass_comma(node, opts)
|
|
120
|
-
return node unless node.is_a?(Sass::Script::Operation)
|
|
138
|
+
return node unless node.is_a?(Sass::Script::Tree::Operation)
|
|
121
139
|
return val_to_sass_concat(node, opts) unless node.operator == :comma
|
|
122
140
|
|
|
123
|
-
Sass::Script::Operation.new(
|
|
141
|
+
Sass::Script::Tree::Operation.new(
|
|
124
142
|
val_to_sass_concat(node.operand1, opts),
|
|
125
143
|
val_to_sass_comma(node.operand2, opts),
|
|
126
144
|
node.operator)
|
|
127
145
|
end
|
|
128
146
|
|
|
129
147
|
def val_to_sass_concat(node, opts)
|
|
130
|
-
return node unless node.is_a?(Sass::Script::Operation)
|
|
148
|
+
return node unless node.is_a?(Sass::Script::Tree::Operation)
|
|
131
149
|
return val_to_sass_div(node, opts) unless node.operator == :space
|
|
132
150
|
|
|
133
|
-
Sass::Script::Operation.new(
|
|
151
|
+
Sass::Script::Tree::Operation.new(
|
|
134
152
|
val_to_sass_div(node.operand1, opts),
|
|
135
153
|
val_to_sass_concat(node.operand2, opts),
|
|
136
154
|
node.operator)
|
|
137
155
|
end
|
|
138
156
|
|
|
139
157
|
def val_to_sass_div(node, opts)
|
|
140
|
-
unless node.is_a?(Sass::Script::Operation) && node.operator == :div &&
|
|
141
|
-
node.operand1.is_a?(Sass::Script::
|
|
142
|
-
node.
|
|
143
|
-
|
|
158
|
+
unless node.is_a?(Sass::Script::Tree::Operation) && node.operator == :div &&
|
|
159
|
+
node.operand1.is_a?(Sass::Script::Tree::Literal) &&
|
|
160
|
+
node.operand1.value.is_a?(Sass::Script::Value::Number) &&
|
|
161
|
+
node.operand2.is_a?(Sass::Script::Tree::Literal) &&
|
|
162
|
+
node.operand2.value.is_a?(Sass::Script::Value::Number) &&
|
|
163
|
+
(!node.operand1.value.original || !node.operand2.value.original)
|
|
144
164
|
return node
|
|
145
165
|
end
|
|
146
166
|
|
|
147
|
-
Sass::Script::String.new("(#{node.to_sass(opts)})")
|
|
167
|
+
Sass::Script::Value::String.new("(#{node.to_sass(opts)})")
|
|
148
168
|
end
|
|
149
169
|
|
|
150
170
|
end
|
|
@@ -5,10 +5,11 @@ module Sass
|
|
|
5
5
|
# @see Sass::Tree
|
|
6
6
|
class ReturnNode < Node
|
|
7
7
|
# The expression to return.
|
|
8
|
-
#
|
|
8
|
+
#
|
|
9
|
+
# @return [Script::Tree::Node]
|
|
9
10
|
attr_accessor :expr
|
|
10
11
|
|
|
11
|
-
# @param expr [Script::Node] The expression to return
|
|
12
|
+
# @param expr [Script::Tree::Node] The expression to return
|
|
12
13
|
def initialize(expr)
|
|
13
14
|
@expr = expr
|
|
14
15
|
super()
|
data/lib/sass/tree/root_node.rb
CHANGED
|
@@ -13,15 +13,31 @@ module Sass
|
|
|
13
13
|
@template = template
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
# Runs the dynamic Sass code
|
|
17
|
-
#
|
|
16
|
+
# Runs the dynamic Sass code and computes the CSS for the tree.
|
|
17
|
+
#
|
|
18
|
+
# @return [String] The compiled CSS.
|
|
18
19
|
def render
|
|
20
|
+
css_tree.css
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Runs the dynamic Sass code and computes the CSS for the tree, along with
|
|
24
|
+
# the sourcemap.
|
|
25
|
+
#
|
|
26
|
+
# @return [(String, Sass::Source::Map)] The compiled CSS, as well as
|
|
27
|
+
# the source map. @see #render
|
|
28
|
+
def render_with_sourcemap
|
|
29
|
+
css_tree.css_with_sourcemap
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def css_tree
|
|
19
35
|
Visitors::CheckNesting.visit(self)
|
|
20
36
|
result = Visitors::Perform.visit(self)
|
|
21
37
|
Visitors::CheckNesting.visit(result) # Check again to validate mixins
|
|
22
38
|
result, extends = Visitors::Cssize.visit(result)
|
|
23
39
|
Visitors::Extend.visit(result, extends)
|
|
24
|
-
result
|
|
40
|
+
result
|
|
25
41
|
end
|
|
26
42
|
end
|
|
27
43
|
end
|
data/lib/sass/tree/rule_node.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'pathname'
|
|
2
|
-
require 'uri'
|
|
3
2
|
|
|
4
3
|
module Sass::Tree
|
|
5
4
|
# A static node reprenting a CSS rule.
|
|
@@ -10,24 +9,24 @@ module Sass::Tree
|
|
|
10
9
|
PARENT = '&'
|
|
11
10
|
|
|
12
11
|
# The CSS selector for this rule,
|
|
13
|
-
# interspersed with {Sass::Script::Node}s
|
|
12
|
+
# interspersed with {Sass::Script::Tree::Node}s
|
|
14
13
|
# representing `#{}`-interpolation.
|
|
15
14
|
# Any adjacent strings will be merged together.
|
|
16
15
|
#
|
|
17
|
-
# @return [Array<String, Sass::Script::Node>]
|
|
16
|
+
# @return [Array<String, Sass::Script::Tree::Node>]
|
|
18
17
|
attr_accessor :rule
|
|
19
18
|
|
|
20
|
-
# The CSS selector for this rule,
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
19
|
+
# The CSS selector for this rule, without any unresolved
|
|
20
|
+
# interpolation but with parent references still intact. It's only
|
|
21
|
+
# guaranteed to be set once {Tree::Visitors::Perform} has been
|
|
22
|
+
# run, but it may be set before then for optimization reasons.
|
|
24
23
|
#
|
|
25
24
|
# @return [Selector::CommaSequence]
|
|
26
25
|
attr_accessor :parsed_rules
|
|
27
26
|
|
|
28
|
-
# The CSS selector for this rule,
|
|
29
|
-
#
|
|
30
|
-
#
|
|
27
|
+
# The CSS selector for this rule, without any unresolved
|
|
28
|
+
# interpolation or parent references. It's only set once
|
|
29
|
+
# {Tree::Visitors::Perform} has been run.
|
|
31
30
|
#
|
|
32
31
|
# @return [Selector::CommaSequence]
|
|
33
32
|
attr_accessor :resolved_rules
|
|
@@ -44,6 +43,10 @@ module Sass::Tree
|
|
|
44
43
|
# @return [Fixnum]
|
|
45
44
|
attr_accessor :tabs
|
|
46
45
|
|
|
46
|
+
# The entire selector source range for this rule.
|
|
47
|
+
# @return [Sass::Source::Range]
|
|
48
|
+
attr_accessor :selector_source_range
|
|
49
|
+
|
|
47
50
|
# Whether or not this rule is the last rule in a nested group.
|
|
48
51
|
# This is only set in a CSS tree.
|
|
49
52
|
#
|
|
@@ -54,14 +57,16 @@ module Sass::Tree
|
|
|
54
57
|
# This is only readable in a CSS tree as it is written during the perform step
|
|
55
58
|
# and only when the :trace_selectors option is set.
|
|
56
59
|
#
|
|
57
|
-
# @return [
|
|
60
|
+
# @return [String]
|
|
58
61
|
attr_accessor :stack_trace
|
|
59
62
|
|
|
60
|
-
# @param rule [Array<String, Sass::Script::Node>]
|
|
63
|
+
# @param rule [Array<String, Sass::Script::Tree::Node>]
|
|
64
|
+
# @param selector_source_range [Sass::Source::Range]
|
|
61
65
|
# The CSS rule. See \{#rule}
|
|
62
|
-
def initialize(rule)
|
|
66
|
+
def initialize(rule, selector_source_range = nil)
|
|
63
67
|
merged = Sass::Util.merge_adjacent_strings(rule)
|
|
64
68
|
@rule = Sass::Util.strip_string_array(merged)
|
|
69
|
+
@selector_source_range = selector_source_range
|
|
65
70
|
@tabs = 0
|
|
66
71
|
try_to_parse_non_interpolated_rules
|
|
67
72
|
super()
|
|
@@ -105,12 +110,13 @@ module Sass::Tree
|
|
|
105
110
|
|
|
106
111
|
# A hash that will be associated with this rule in the CSS document
|
|
107
112
|
# if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
|
|
108
|
-
# This data is used by e.g. [the FireSass Firebug
|
|
113
|
+
# This data is used by e.g. [the FireSass Firebug
|
|
114
|
+
# extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
|
|
109
115
|
#
|
|
110
116
|
# @return [{#to_s => #to_s}]
|
|
111
117
|
def debug_info
|
|
112
|
-
{:filename => filename && ("file://" +
|
|
113
|
-
:line =>
|
|
118
|
+
{:filename => filename && ("file://" + Sass::Util.escape_uri(File.expand_path(filename))),
|
|
119
|
+
:line => line}
|
|
114
120
|
end
|
|
115
121
|
|
|
116
122
|
# A rule node is invisible if it has only placeholder selectors.
|
|
@@ -124,8 +130,10 @@ module Sass::Tree
|
|
|
124
130
|
if @rule.all? {|t| t.kind_of?(String)}
|
|
125
131
|
# We don't use real filename/line info because we don't have it yet.
|
|
126
132
|
# When we get it, we'll set it on the parsed rules if possible.
|
|
127
|
-
parser = Sass::SCSS::StaticParser.new(@rule.join.strip, '', 1)
|
|
133
|
+
parser = Sass::SCSS::StaticParser.new(@rule.join.strip, '', nil, 1)
|
|
134
|
+
# rubocop:disable RescueModifier
|
|
128
135
|
@parsed_rules = parser.parse_selector rescue nil
|
|
136
|
+
# rubocop:enable RescueModifier
|
|
129
137
|
end
|
|
130
138
|
end
|
|
131
139
|
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
|
data/lib/sass/tree/trace_node.rb
CHANGED
|
@@ -7,6 +7,7 @@ module Sass::Tree
|
|
|
7
7
|
# @see Sass::Tree
|
|
8
8
|
class TraceNode < Node
|
|
9
9
|
# The name of the trace entry to add.
|
|
10
|
+
#
|
|
10
11
|
# @return [String]
|
|
11
12
|
attr_reader :name
|
|
12
13
|
|
|
@@ -19,7 +20,7 @@ module Sass::Tree
|
|
|
19
20
|
|
|
20
21
|
# Initializes this node from an existing node.
|
|
21
22
|
# @param name [String] The name of the trace entry to add.
|
|
22
|
-
# @param
|
|
23
|
+
# @param node [Node] The node to copy information from.
|
|
23
24
|
# @return [TraceNode]
|
|
24
25
|
def self.from_node(name, node)
|
|
25
26
|
trace = new(name)
|
|
@@ -9,20 +9,26 @@ module Sass
|
|
|
9
9
|
attr_reader :name
|
|
10
10
|
|
|
11
11
|
# The parse tree for the variable value.
|
|
12
|
-
# @return [Script::Node]
|
|
12
|
+
# @return [Script::Tree::Node]
|
|
13
13
|
attr_accessor :expr
|
|
14
14
|
|
|
15
15
|
# Whether this is a guarded variable assignment (`!default`).
|
|
16
16
|
# @return [Boolean]
|
|
17
17
|
attr_reader :guarded
|
|
18
18
|
|
|
19
|
+
# Whether this is a global variable assignment (`!global`).
|
|
20
|
+
# @return [Boolean]
|
|
21
|
+
attr_reader :global
|
|
22
|
+
|
|
19
23
|
# @param name [String] The name of the variable
|
|
20
|
-
# @param expr [Script::Node] See \{#expr}
|
|
24
|
+
# @param expr [Script::Tree::Node] See \{#expr}
|
|
21
25
|
# @param guarded [Boolean] See \{#guarded}
|
|
22
|
-
|
|
26
|
+
# @param global [Boolean] See \{#global}
|
|
27
|
+
def initialize(name, expr, guarded, global)
|
|
23
28
|
@name = name
|
|
24
29
|
@expr = expr
|
|
25
30
|
@guarded = guarded
|
|
31
|
+
@global = global
|
|
26
32
|
super()
|
|
27
33
|
end
|
|
28
34
|
end
|
|
@@ -32,9 +32,9 @@ module Sass::Tree::Visitors
|
|
|
32
32
|
# @param node [Tree::Node] The node to visit.
|
|
33
33
|
# @return [Object] The return value of the `visit_*` method for this node.
|
|
34
34
|
def visit(node)
|
|
35
|
-
method = "visit_#{node_name node}"
|
|
36
|
-
if
|
|
37
|
-
|
|
35
|
+
method = "visit_#{self.class.node_name node}"
|
|
36
|
+
if respond_to?(method, true)
|
|
37
|
+
send(method, node) {visit_children(node)}
|
|
38
38
|
else
|
|
39
39
|
visit_children(node)
|
|
40
40
|
end
|
|
@@ -59,9 +59,9 @@ module Sass::Tree::Visitors
|
|
|
59
59
|
#
|
|
60
60
|
# @param [Tree::Node] node The node.
|
|
61
61
|
# @return [String] The name.
|
|
62
|
-
def node_name(node)
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
def self.node_name(node)
|
|
63
|
+
@node_names ||= {}
|
|
64
|
+
@node_names[node.class.name] ||= node.class.name.gsub(NODE_NAME_RE, '\\1').downcase
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# `yield`s, then runs the visitor on the `@else` clause if the node has one.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# A visitor for checking that all nodes are properly nested.
|
|
2
2
|
class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
3
|
+
|
|
3
4
|
protected
|
|
4
5
|
|
|
5
6
|
def initialize
|
|
@@ -7,9 +8,9 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def visit(node)
|
|
10
|
-
if error = @parent && (
|
|
11
|
-
try_send("invalid_#{node_name @parent}_child?", @parent, node) ||
|
|
12
|
-
try_send("invalid_#{node_name node}_parent?", @parent, node))
|
|
11
|
+
if (error = @parent && (
|
|
12
|
+
try_send("invalid_#{self.class.node_name @parent}_child?", @parent, node) ||
|
|
13
|
+
try_send("invalid_#{self.class.node_name node}_parent?", @parent, node)))
|
|
13
14
|
raise Sass::SyntaxError.new(error)
|
|
14
15
|
end
|
|
15
16
|
super
|
|
@@ -19,7 +20,7 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
CONTROL_NODES = [Sass::Tree::EachNode, Sass::Tree::ForNode, Sass::Tree::IfNode,
|
|
22
|
-
|
|
23
|
+
Sass::Tree::WhileNode, Sass::Tree::TraceNode]
|
|
23
24
|
SCRIPT_NODES = [Sass::Tree::ImportNode] + CONTROL_NODES
|
|
24
25
|
def visit_children(parent)
|
|
25
26
|
old_parent = @parent
|
|
@@ -110,7 +111,9 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
110
111
|
end
|
|
111
112
|
end
|
|
112
113
|
|
|
113
|
-
VALID_PROP_CHILDREN = [Sass::Tree::CommentNode,
|
|
114
|
+
VALID_PROP_CHILDREN = CONTROL_NODES + [Sass::Tree::CommentNode,
|
|
115
|
+
Sass::Tree::PropNode,
|
|
116
|
+
Sass::Tree::MixinNode]
|
|
114
117
|
def invalid_prop_child?(parent, child)
|
|
115
118
|
unless is_any_of?(child, VALID_PROP_CHILDREN)
|
|
116
119
|
"Illegal nesting: Only properties may be nested beneath properties."
|
|
@@ -122,7 +125,8 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
122
125
|
Sass::Tree::MixinNode]
|
|
123
126
|
def invalid_prop_parent?(parent, child)
|
|
124
127
|
unless is_any_of?(parent, VALID_PROP_PARENTS)
|
|
125
|
-
"Properties are only allowed within rules, directives, mixin includes, or other properties." +
|
|
128
|
+
"Properties are only allowed within rules, directives, mixin includes, or other properties." +
|
|
129
|
+
child.pseudo_class_selector_message
|
|
126
130
|
end
|
|
127
131
|
end
|
|
128
132
|
|
|
@@ -133,10 +137,10 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
133
137
|
private
|
|
134
138
|
|
|
135
139
|
def is_any_of?(val, classes)
|
|
136
|
-
|
|
140
|
+
classes.each do |c|
|
|
137
141
|
return true if val.is_a?(c)
|
|
138
142
|
end
|
|
139
|
-
|
|
143
|
+
false
|
|
140
144
|
end
|
|
141
145
|
|
|
142
146
|
def try_send(method, *args)
|
|
@@ -144,4 +148,3 @@ class Sass::Tree::Visitors::CheckNesting < Sass::Tree::Visitors::Base
|
|
|
144
148
|
send(method, *args)
|
|
145
149
|
end
|
|
146
150
|
end
|
|
147
|
-
|
|
@@ -23,7 +23,11 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
23
23
|
def visit_children(parent)
|
|
24
24
|
@tabs += 1
|
|
25
25
|
return @format == :sass ? "\n" : " {}\n" if parent.children.empty?
|
|
26
|
-
|
|
26
|
+
if @format == :sass
|
|
27
|
+
"\n" + super.join.rstrip + "\n"
|
|
28
|
+
else
|
|
29
|
+
" {\n" + super.join.rstrip + "\n#{ @tab_chars * (@tabs - 1)}}\n"
|
|
30
|
+
end
|
|
27
31
|
ensure
|
|
28
32
|
@tabs -= 1
|
|
29
33
|
end
|
|
@@ -52,7 +56,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
52
56
|
|
|
53
57
|
def visit_comment(node)
|
|
54
58
|
value = interp_to_src(node.value)
|
|
55
|
-
|
|
59
|
+
if @format == :sass
|
|
56
60
|
content = value.gsub(/\*\/$/, '').rstrip
|
|
57
61
|
if content =~ /\A[ \t]/
|
|
58
62
|
# Re-indent SCSS comments like this:
|
|
@@ -63,33 +67,28 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
63
67
|
content.sub!(/\A([ \t]*)\/\*/, '/*\1')
|
|
64
68
|
end
|
|
65
69
|
|
|
66
|
-
content
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
if content.include?("\n")
|
|
71
|
+
content.gsub!(%r{\n( \*|//)}, "\n ")
|
|
72
|
+
spaces = content.scan(/\n( *)/).map {|s| s.first.size}.min
|
|
73
|
+
sep = node.type == :silent ? "\n//" : "\n *"
|
|
74
|
+
if spaces >= 2
|
|
75
|
+
content.gsub!(/\n /, sep)
|
|
69
76
|
else
|
|
70
|
-
content.gsub!(/\n
|
|
71
|
-
spaces = content.scan(/\n( *)/).map {|s| s.first.size}.min
|
|
72
|
-
sep = node.type == :silent ? "\n//" : "\n *"
|
|
73
|
-
if spaces >= 2
|
|
74
|
-
content.gsub(/\n /, sep)
|
|
75
|
-
else
|
|
76
|
-
content.gsub(/\n#{' ' * spaces}/, sep)
|
|
77
|
-
end
|
|
77
|
+
content.gsub!(/\n#{' ' * spaces}/, sep)
|
|
78
78
|
end
|
|
79
|
+
end
|
|
79
80
|
|
|
80
81
|
content.gsub!(/\A\/\*/, '//') if node.type == :silent
|
|
81
82
|
content.gsub!(/^/, tab_str)
|
|
82
|
-
content.rstrip + "\n"
|
|
83
|
+
content = content.rstrip + "\n"
|
|
83
84
|
else
|
|
84
85
|
spaces = (@tab_chars * [@tabs - value[/^ */].size, 0].max)
|
|
85
86
|
content = if node.type == :silent
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
content
|
|
87
|
+
value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
|
|
88
|
+
else
|
|
89
|
+
value
|
|
90
|
+
end.gsub(/^/, spaces) + "\n"
|
|
91
91
|
end
|
|
92
|
-
content.sub!(%r{^\s*(/\*)}, '/*!') if node.type == :loud #'
|
|
93
92
|
content
|
|
94
93
|
end
|
|
95
94
|
|
|
@@ -99,17 +98,19 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
99
98
|
|
|
100
99
|
def visit_directive(node)
|
|
101
100
|
res = "#{tab_str}#{interp_to_src(node.value)}"
|
|
102
|
-
res.gsub!(/^@import \#\{(.*)\}([^}]*)$/, '@import \1\2')
|
|
101
|
+
res.gsub!(/^@import \#\{(.*)\}([^}]*)$/, '@import \1\2')
|
|
103
102
|
return res + "#{semi}\n" unless node.has_children
|
|
104
103
|
res + yield + "\n"
|
|
105
104
|
end
|
|
106
105
|
|
|
107
106
|
def visit_each(node)
|
|
108
|
-
|
|
107
|
+
vars = node.vars.map {|var| "$#{dasherize(var)}"}.join(", ")
|
|
108
|
+
"#{tab_str}@each #{vars} in #{node.list.to_sass(@options)}#{yield}"
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def visit_extend(node)
|
|
112
|
-
"#{tab_str}@extend #{selector_to_src(node.selector).lstrip}#{semi}
|
|
112
|
+
"#{tab_str}@extend #{selector_to_src(node.selector).lstrip}#{semi}" +
|
|
113
|
+
"#{" !optional" if node.optional?}\n"
|
|
113
114
|
end
|
|
114
115
|
|
|
115
116
|
def visit_for(node)
|
|
@@ -131,9 +132,12 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
131
132
|
|
|
132
133
|
def visit_if(node)
|
|
133
134
|
name =
|
|
134
|
-
if !@is_else
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
if !@is_else
|
|
136
|
+
"if"
|
|
137
|
+
elsif node.expr
|
|
138
|
+
"else if"
|
|
139
|
+
else
|
|
140
|
+
"else"
|
|
137
141
|
end
|
|
138
142
|
@is_else = false
|
|
139
143
|
str = "#{tab_str}@#{name}"
|
|
@@ -152,7 +156,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
152
156
|
end
|
|
153
157
|
|
|
154
158
|
def visit_media(node)
|
|
155
|
-
"#{tab_str}@media #{
|
|
159
|
+
"#{tab_str}@media #{query_interp_to_src(node.query)}#{yield}"
|
|
156
160
|
end
|
|
157
161
|
|
|
158
162
|
def visit_supports(node)
|
|
@@ -160,7 +164,7 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
160
164
|
end
|
|
161
165
|
|
|
162
166
|
def visit_cssimport(node)
|
|
163
|
-
if node.uri.is_a?(Sass::Script::Node)
|
|
167
|
+
if node.uri.is_a?(Sass::Script::Tree::Node)
|
|
164
168
|
str = "#{tab_str}@import #{node.uri.to_sass(@options)}"
|
|
165
169
|
else
|
|
166
170
|
str = "#{tab_str}@import #{node.uri}"
|
|
@@ -195,17 +199,26 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
def visit_mixin(node)
|
|
202
|
+
arg_to_sass = lambda do |arg|
|
|
203
|
+
sass = arg.to_sass(@options)
|
|
204
|
+
sass = "(#{sass})" if arg.is_a?(Sass::Script::Tree::ListLiteral) && arg.separator == :comma
|
|
205
|
+
sass
|
|
206
|
+
end
|
|
207
|
+
|
|
198
208
|
unless node.args.empty? && node.keywords.empty? && node.splat.nil?
|
|
199
|
-
args = node.args.map
|
|
209
|
+
args = node.args.map(&arg_to_sass)
|
|
200
210
|
keywords = Sass::Util.hash_to_a(node.keywords).
|
|
201
|
-
map {|k, v| "$#{dasherize(k)}: #{v
|
|
211
|
+
map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}
|
|
212
|
+
|
|
202
213
|
if node.splat
|
|
203
|
-
splat =
|
|
204
|
-
|
|
214
|
+
splat = "#{arg_to_sass[node.splat]}..."
|
|
215
|
+
kwarg_splat = "#{arg_to_sass[node.kwarg_splat]}..." if node.kwarg_splat
|
|
205
216
|
end
|
|
206
|
-
|
|
217
|
+
|
|
218
|
+
arglist = "(#{[args, splat, keywords, kwarg_splat].flatten.compact.join(', ')})"
|
|
207
219
|
end
|
|
208
|
-
"#{tab_str}#{@format == :sass ? '+' : '@include '}
|
|
220
|
+
"#{tab_str}#{@format == :sass ? '+' : '@include '}" +
|
|
221
|
+
"#{dasherize(node.name)}#{arglist}#{node.has_children ? yield : semi}\n"
|
|
209
222
|
end
|
|
210
223
|
|
|
211
224
|
def visit_content(node)
|
|
@@ -239,7 +252,8 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
239
252
|
end
|
|
240
253
|
|
|
241
254
|
def visit_variable(node)
|
|
242
|
-
"#{tab_str}$#{dasherize(node.name)}: #{node.expr.to_sass(@options)}
|
|
255
|
+
"#{tab_str}$#{dasherize(node.name)}: #{node.expr.to_sass(@options)}" +
|
|
256
|
+
"#{' !global' if node.global}#{' !default' if node.guarded}#{semi}\n"
|
|
243
257
|
end
|
|
244
258
|
|
|
245
259
|
def visit_warn(node)
|
|
@@ -250,6 +264,17 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
250
264
|
"#{tab_str}@while #{node.expr.to_sass(@options)}#{yield}"
|
|
251
265
|
end
|
|
252
266
|
|
|
267
|
+
def visit_atroot(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)
|
|
271
|
+
rule = node.children.first
|
|
272
|
+
"#{tab_str}@at-root #{selector_to_src(rule.rule)}#{visit_children(rule)}"
|
|
273
|
+
else
|
|
274
|
+
"#{tab_str}@at-root#{yield}"
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
253
278
|
private
|
|
254
279
|
|
|
255
280
|
def interp_to_src(interp)
|
|
@@ -260,11 +285,11 @@ class Sass::Tree::Visitors::Convert < Sass::Tree::Visitors::Base
|
|
|
260
285
|
end
|
|
261
286
|
|
|
262
287
|
# Like interp_to_src, but removes the unnecessary `#{}` around the keys and
|
|
263
|
-
# values in
|
|
264
|
-
def
|
|
288
|
+
# values in query expressions.
|
|
289
|
+
def query_interp_to_src(interp)
|
|
265
290
|
Sass::Util.enum_with_index(interp).map do |r, i|
|
|
266
291
|
next r if r.is_a?(String)
|
|
267
|
-
before, after = interp[i-1], interp[i+1]
|
|
292
|
+
before, after = interp[i - 1], interp[i + 1]
|
|
268
293
|
if before.is_a?(String) && after.is_a?(String) &&
|
|
269
294
|
((before[-1] == ?( && after[0] == ?:) ||
|
|
270
295
|
(before =~ /:\s*/ && after[0] == ?)))
|