haml-edge 2.3.179 → 2.3.180
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/EDGE_GEM_VERSION +1 -1
- data/README.md +88 -149
- data/VERSION +1 -1
- data/bin/css2sass +7 -1
- data/bin/sass-convert +7 -0
- data/lib/haml/exec.rb +95 -22
- data/lib/haml/template.rb +1 -1
- data/lib/haml/util.rb +50 -0
- data/lib/sass.rb +1 -1
- data/lib/sass/css.rb +38 -210
- data/lib/sass/engine.rb +121 -47
- data/lib/sass/files.rb +28 -19
- data/lib/sass/plugin.rb +32 -43
- data/lib/sass/repl.rb +1 -1
- data/lib/sass/script.rb +25 -6
- data/lib/sass/script/bool.rb +1 -0
- data/lib/sass/script/color.rb +2 -2
- data/lib/sass/script/css_lexer.rb +22 -0
- data/lib/sass/script/css_parser.rb +28 -0
- data/lib/sass/script/funcall.rb +17 -9
- data/lib/sass/script/functions.rb +46 -1
- data/lib/sass/script/interpolation.rb +42 -0
- data/lib/sass/script/lexer.rb +142 -34
- data/lib/sass/script/literal.rb +28 -12
- data/lib/sass/script/node.rb +57 -1
- data/lib/sass/script/number.rb +18 -3
- data/lib/sass/script/operation.rb +44 -8
- data/lib/sass/script/parser.rb +149 -24
- data/lib/sass/script/string.rb +50 -2
- data/lib/sass/script/unary_operation.rb +25 -10
- data/lib/sass/script/variable.rb +20 -11
- data/lib/sass/scss.rb +14 -0
- data/lib/sass/scss/css_parser.rb +39 -0
- data/lib/sass/scss/parser.rb +683 -0
- data/lib/sass/scss/rx.rb +112 -0
- data/lib/sass/scss/script_lexer.rb +13 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/tree/comment_node.rb +58 -16
- data/lib/sass/tree/debug_node.rb +7 -2
- data/lib/sass/tree/directive_node.rb +38 -34
- data/lib/sass/tree/for_node.rb +6 -0
- data/lib/sass/tree/if_node.rb +13 -0
- data/lib/sass/tree/import_node.rb +26 -7
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +16 -1
- data/lib/sass/tree/node.rb +98 -27
- data/lib/sass/tree/prop_node.rb +97 -20
- data/lib/sass/tree/root_node.rb +37 -0
- data/lib/sass/tree/rule_node.rb +88 -60
- data/lib/sass/tree/variable_node.rb +9 -5
- data/lib/sass/tree/while_node.rb +4 -0
- data/test/haml/results/filters.xhtml +1 -1
- data/test/haml/util_test.rb +28 -0
- data/test/sass/conversion_test.rb +884 -0
- data/test/sass/css2sass_test.rb +46 -21
- data/test/sass/engine_test.rb +680 -160
- data/test/sass/functions_test.rb +27 -0
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more_import.sass +3 -3
- data/test/sass/plugin_test.rb +28 -8
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +5 -5
- data/test/sass/results/compressed.css +1 -1
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +3 -1
- data/test/sass/results/mixins.css +12 -12
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +4 -4
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +15 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/script_conversion_test.rb +153 -0
- data/test/sass/script_test.rb +44 -54
- data/test/sass/scss/css_test.rb +811 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +871 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/templates/alt.sass +2 -2
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/import.sass +4 -4
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/line_numbers.sass +1 -1
- data/test/sass/templates/mixins.sass +2 -2
- data/test/sass/templates/nested_mixin_bork.sass +1 -1
- data/test/sass/templates/options.sass +1 -1
- data/test/sass/templates/parent_ref.sass +2 -2
- data/test/sass/templates/script.sass +69 -69
- data/test/sass/templates/scss_import.scss +10 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/units.sass +10 -10
- data/test/test_helper.rb +4 -4
- metadata +27 -2
@@ -16,6 +16,24 @@ module Sass
|
|
16
16
|
|
17
17
|
protected
|
18
18
|
|
19
|
+
def to_src(tabs, opts, fmt)
|
20
|
+
args =
|
21
|
+
if @args.empty?
|
22
|
+
""
|
23
|
+
else
|
24
|
+
'(' + @args.map do |v, d|
|
25
|
+
if d
|
26
|
+
"#{v.to_sass}: #{d.to_sass}"
|
27
|
+
else
|
28
|
+
v.to_sass
|
29
|
+
end
|
30
|
+
end.join(", ") + ')'
|
31
|
+
end
|
32
|
+
|
33
|
+
"#{' ' * tabs}#{fmt == :sass ? '=' : '@mixin '}#{@name}#{args}" +
|
34
|
+
children_to_src(tabs, opts, fmt)
|
35
|
+
end
|
36
|
+
|
19
37
|
# Loads the mixin into the environment.
|
20
38
|
#
|
21
39
|
# @param environment [Sass::Environment] The lexical environment containing
|
data/lib/sass/tree/mixin_node.rb
CHANGED
@@ -7,6 +7,12 @@ module Sass::Tree
|
|
7
7
|
#
|
8
8
|
# @see Sass::Tree
|
9
9
|
class MixinNode < Node
|
10
|
+
# @see Node#options=
|
11
|
+
def options=(opts)
|
12
|
+
super
|
13
|
+
@args.each {|a| a.context = :equals} if opts[:sass2]
|
14
|
+
end
|
15
|
+
|
10
16
|
# @param name [String] The name of the mixin
|
11
17
|
# @param args [Array<Script::Node>] The arguments to the mixin
|
12
18
|
def initialize(name, args)
|
@@ -22,6 +28,11 @@ module Sass::Tree
|
|
22
28
|
|
23
29
|
protected
|
24
30
|
|
31
|
+
def to_src(tabs, opts, fmt)
|
32
|
+
args = '(' + @args.map {|a| a.to_sass}.join(", ") + ')' unless @args.empty?
|
33
|
+
"#{' ' * tabs}#{fmt == :sass ? '+' : '@include '}#{@name}#{args}#{semi fmt}\n"
|
34
|
+
end
|
35
|
+
|
25
36
|
# @see Node#_cssize
|
26
37
|
def _cssize(parent)
|
27
38
|
children.map {|c| c.cssize(parent)}.flatten
|
@@ -52,7 +63,11 @@ END
|
|
52
63
|
if value
|
53
64
|
value.perform(environment)
|
54
65
|
elsif default
|
55
|
-
default.perform(env)
|
66
|
+
val = default.perform(env)
|
67
|
+
if default.context == :equals && val.is_a?(Sass::Script::String)
|
68
|
+
val = Sass::Script::String.new(val.value)
|
69
|
+
end
|
70
|
+
val
|
56
71
|
end)
|
57
72
|
raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter #{var.inspect}.") unless env.var(var.name)
|
58
73
|
env
|
data/lib/sass/tree/node.rb
CHANGED
@@ -26,11 +26,20 @@ module Sass
|
|
26
26
|
module Tree
|
27
27
|
# The abstract superclass of all parse-tree nodes.
|
28
28
|
class Node
|
29
|
+
include Enumerable
|
30
|
+
|
29
31
|
# The child nodes of this node.
|
30
32
|
#
|
31
33
|
# @return [Array<Tree::Node>]
|
32
34
|
attr_accessor :children
|
33
35
|
|
36
|
+
# Whether or not this node has child nodes.
|
37
|
+
# This may be true even when \{#children} is empty,
|
38
|
+
# in which case this node has an empty block (e.g. `{}`).
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
attr_accessor :has_children
|
42
|
+
|
34
43
|
# The line of the document on which this node appeared.
|
35
44
|
#
|
36
45
|
# @return [Fixnum]
|
@@ -60,6 +69,12 @@ module Sass
|
|
60
69
|
@options = options
|
61
70
|
end
|
62
71
|
|
72
|
+
# @private
|
73
|
+
def children=(children)
|
74
|
+
self.has_children ||= !children.empty?
|
75
|
+
@children = children
|
76
|
+
end
|
77
|
+
|
63
78
|
# The name of the document on which this node appeared.
|
64
79
|
#
|
65
80
|
# @return [String]
|
@@ -73,21 +88,14 @@ module Sass
|
|
73
88
|
# @raise [Sass::SyntaxError] if `child` is invalid
|
74
89
|
# @see #invalid_child?
|
75
90
|
def <<(child)
|
91
|
+
return if child.nil?
|
76
92
|
if msg = invalid_child?(child)
|
77
93
|
raise Sass::SyntaxError.new(msg, :line => child.line)
|
78
94
|
end
|
95
|
+
self.has_children = true
|
79
96
|
@children << child
|
80
97
|
end
|
81
98
|
|
82
|
-
# Return the last child node.
|
83
|
-
#
|
84
|
-
# We need this because {Tree::Node} duck types as an Array for {Sass::Engine}.
|
85
|
-
#
|
86
|
-
# @return [Tree::Node] The last child node
|
87
|
-
def last
|
88
|
-
children.last
|
89
|
-
end
|
90
|
-
|
91
99
|
# Compares this node and another object (only other {Tree::Node}s will be equal).
|
92
100
|
# This does a structural comparison;
|
93
101
|
# if the contents of the nodes and all the child nodes are equivalent,
|
@@ -180,6 +188,34 @@ module Sass
|
|
180
188
|
raise e
|
181
189
|
end
|
182
190
|
|
191
|
+
# Iterates through each node in the tree rooted at this node
|
192
|
+
# in a pre-order walk.
|
193
|
+
#
|
194
|
+
# @yield node
|
195
|
+
# @yieldparam node [Node] a node in the tree
|
196
|
+
def each(&block)
|
197
|
+
yield self
|
198
|
+
children.each {|c| c.each(&block)}
|
199
|
+
end
|
200
|
+
|
201
|
+
# Converts a node to Sass code that will generate it.
|
202
|
+
#
|
203
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the Sass code
|
204
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
205
|
+
# @return [String] The Sass code corresponding to the node
|
206
|
+
def to_sass(tabs = 0, opts = {})
|
207
|
+
to_src(tabs, opts, :sass)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Converts a node to SCSS code that will generate it.
|
211
|
+
#
|
212
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
|
213
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
214
|
+
# @return [String] The Sass code corresponding to the node
|
215
|
+
def to_scss(tabs = 0, opts = {})
|
216
|
+
to_src(tabs, opts, :scss)
|
217
|
+
end
|
218
|
+
|
183
219
|
protected
|
184
220
|
|
185
221
|
# Computes the CSS corresponding to this particular Sass node.
|
@@ -258,27 +294,21 @@ module Sass
|
|
258
294
|
children.map {|c| c.perform(environment)}.flatten
|
259
295
|
end
|
260
296
|
|
261
|
-
# Replaces SassScript in a chunk of text
|
297
|
+
# Replaces SassScript in a chunk of text
|
262
298
|
# with the resulting value.
|
263
299
|
#
|
264
|
-
# @param text [String] The text to interpolate
|
300
|
+
# @param text [Array<String, Sass::Script::Node>] The text to interpolate
|
265
301
|
# @param environment [Sass::Environment] The lexical environment containing
|
266
302
|
# variable and mixin values
|
267
303
|
# @return [String] The interpolated text
|
268
|
-
def
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
res << "\\" * [0, escapes - 1].max
|
277
|
-
res << Script::Parser.new(scan, line, scan.pos - scan.matched_size, filename).
|
278
|
-
parse_interpolated.perform(environment).to_s
|
279
|
-
end
|
280
|
-
end
|
281
|
-
res + rest
|
304
|
+
def run_interp(text, environment)
|
305
|
+
text.map do |r|
|
306
|
+
next r if r.is_a?(String)
|
307
|
+
val = r.perform(environment)
|
308
|
+
# Interpolated strings should never render with quotes
|
309
|
+
next val.value if val.is_a?(Sass::Script::String)
|
310
|
+
val.to_s
|
311
|
+
end.join.strip
|
282
312
|
end
|
283
313
|
|
284
314
|
# @see Haml::Shared.balance
|
@@ -292,7 +322,8 @@ module Sass
|
|
292
322
|
# Returns an error message if the given child node is invalid,
|
293
323
|
# and false otherwise.
|
294
324
|
#
|
295
|
-
# By default, all child nodes
|
325
|
+
# By default, all child nodes except those only allowed at root level
|
326
|
+
# ({Tree::MixinDefNode}, {Tree::ImportNode}) are valid.
|
296
327
|
# This is expected to be overriden by subclasses
|
297
328
|
# for which some children are invalid.
|
298
329
|
#
|
@@ -300,7 +331,47 @@ module Sass
|
|
300
331
|
# @return [Boolean, String] Whether or not the child node is valid,
|
301
332
|
# as well as the error message to display if it is invalid
|
302
333
|
def invalid_child?(child)
|
303
|
-
|
334
|
+
case child
|
335
|
+
when Tree::MixinDefNode
|
336
|
+
"Mixins may only be defined at the root of a document."
|
337
|
+
when Tree::ImportNode
|
338
|
+
"Import directives may only be used at the root of a document."
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# Converts a node to Sass or SCSS code that will generate it.
|
343
|
+
#
|
344
|
+
# This method is called by the default \{#to\_sass} and \{#to\_scss} methods,
|
345
|
+
# so that the same code can be used for both with minor variations.
|
346
|
+
#
|
347
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
|
348
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
349
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
350
|
+
# @return [String] The Sass or SCSS code corresponding to the node
|
351
|
+
def to_src(tabs, opts, fmt)
|
352
|
+
raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #to_#{fmt}.")
|
353
|
+
end
|
354
|
+
|
355
|
+
# Converts the children of this node to a Sass or SCSS string.
|
356
|
+
# This will return the trailing newline for the previous line,
|
357
|
+
# including brackets if this is SCSS.
|
358
|
+
#
|
359
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the Sass code
|
360
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
361
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
362
|
+
# @return [String] The Sass or CSS code corresponding to the children
|
363
|
+
def children_to_src(tabs, opts, fmt)
|
364
|
+
(fmt == :sass ? "\n" : " {\n") +
|
365
|
+
children.map {|c| c.send("to_#{fmt}", tabs + 1, opts)}.join.rstrip +
|
366
|
+
(fmt == :sass ? "\n" : " }\n")
|
367
|
+
end
|
368
|
+
|
369
|
+
# Returns a semicolon if this is SCSS, or an empty string if this is Sass.
|
370
|
+
#
|
371
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
372
|
+
# @return [String] A semicolon or the empty string
|
373
|
+
def semi(fmt)
|
374
|
+
fmt == :sass ? "" : ";"
|
304
375
|
end
|
305
376
|
end
|
306
377
|
end
|
data/lib/sass/tree/prop_node.rb
CHANGED
@@ -3,17 +3,33 @@ module Sass::Tree
|
|
3
3
|
#
|
4
4
|
# @see Sass::Tree
|
5
5
|
class PropNode < Node
|
6
|
-
# The name of the property
|
6
|
+
# The name of the property,
|
7
|
+
# interspersed with {Sass::Script::Node}s
|
8
|
+
# representing `#{}`-interpolation.
|
9
|
+
# Any adjacent strings will be merged together.
|
7
10
|
#
|
8
|
-
# @return [String]
|
11
|
+
# @return [Array<String, Sass::Script::Node>]
|
9
12
|
attr_accessor :name
|
10
13
|
|
11
|
-
# The
|
12
|
-
#
|
14
|
+
# The name of the property
|
15
|
+
# after any interpolated SassScript has been resolved.
|
16
|
+
# Only set once \{Tree::Node#perform} has been called.
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
attr_accessor :resolved_name
|
20
|
+
|
21
|
+
# The value of the property.
|
13
22
|
#
|
14
|
-
# @return [
|
23
|
+
# @return [Sass::Script::Node]
|
15
24
|
attr_accessor :value
|
16
25
|
|
26
|
+
# The value of the property
|
27
|
+
# after any interpolated SassScript has been resolved.
|
28
|
+
# Only set once \{Tree::Node#perform} has been called.
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
attr_accessor :resolved_value
|
32
|
+
|
17
33
|
# How deep this property is indented
|
18
34
|
# relative to a normal property.
|
19
35
|
# This is only greater than 0 in the case that:
|
@@ -26,12 +42,13 @@ module Sass::Tree
|
|
26
42
|
# @return [Fixnum]
|
27
43
|
attr_accessor :tabs
|
28
44
|
|
29
|
-
# @param name [String] See \{#name}
|
30
|
-
# @param value [
|
45
|
+
# @param name [Array<String, Sass::Script::Node>] See \{#name}
|
46
|
+
# @param value [Sass::Script::Node] See \{#value}
|
31
47
|
# @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
|
32
48
|
# `:old` if it uses `:a b`-style syntax
|
33
49
|
def initialize(name, value, prop_syntax)
|
34
|
-
@name =
|
50
|
+
@name = Haml::Util.strip_string_array(
|
51
|
+
Haml::Util.merge_adjacent_strings(name))
|
35
52
|
@value = value
|
36
53
|
@tabs = 0
|
37
54
|
@prop_syntax = prop_syntax
|
@@ -51,21 +68,33 @@ module Sass::Tree
|
|
51
68
|
# This only applies for old-style properties with no value,
|
52
69
|
# so returns the empty string if this is new-style.
|
53
70
|
#
|
71
|
+
# This should only be called once \{#perform} has been called.
|
72
|
+
#
|
54
73
|
# @return [String] The message
|
55
74
|
def pseudo_class_selector_message
|
56
|
-
return "" if @prop_syntax == :new || !
|
75
|
+
return "" if @prop_syntax == :new || !resolved_value.empty?
|
57
76
|
"\nIf #{declaration.dump} should be a selector, use \"\\#{declaration}\" instead."
|
58
77
|
end
|
59
78
|
|
60
79
|
protected
|
61
80
|
|
81
|
+
def to_src(tabs, opts, fmt)
|
82
|
+
name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass}}"}.join
|
83
|
+
old = opts[:old] && fmt == :sass
|
84
|
+
initial = old ? ':' : ''
|
85
|
+
mid = old ? '' : ':'
|
86
|
+
res = "#{' ' * tabs}#{initial}#{name}#{mid} #{self.class.val_to_sass(value)}"
|
87
|
+
return res + "#{semi fmt}\n" if children.empty?
|
88
|
+
res.rstrip + children_to_src(tabs, opts, fmt)
|
89
|
+
end
|
90
|
+
|
62
91
|
# Computes the CSS for the property.
|
63
92
|
#
|
64
93
|
# @param tabs [Fixnum] The level of indentation for the CSS
|
65
94
|
# @return [String] The resulting CSS
|
66
95
|
def _to_s(tabs)
|
67
|
-
to_return = ' ' * (tabs - 1 + self.tabs) +
|
68
|
-
(style == :compressed ? '' : ' ') +
|
96
|
+
to_return = ' ' * (tabs - 1 + self.tabs) + resolved_name + ":" +
|
97
|
+
(style == :compressed ? '' : ' ') + resolved_value + (style == :compressed ? "" : ";")
|
69
98
|
end
|
70
99
|
|
71
100
|
# Converts nested properties into flat properties.
|
@@ -76,7 +105,7 @@ module Sass::Tree
|
|
76
105
|
def _cssize(parent)
|
77
106
|
node = super
|
78
107
|
result = node.children.dup
|
79
|
-
if !node.
|
108
|
+
if !node.resolved_value.empty? || node.children.empty?
|
80
109
|
node.send(:check!)
|
81
110
|
result.unshift(node)
|
82
111
|
end
|
@@ -89,8 +118,8 @@ module Sass::Tree
|
|
89
118
|
# @param parent [PropNode, nil] The parent node of this node,
|
90
119
|
# or nil if the parent isn't a {PropNode}
|
91
120
|
def cssize!(parent)
|
92
|
-
self.
|
93
|
-
self.tabs = parent.tabs + (parent.
|
121
|
+
self.resolved_name = "#{parent.resolved_name}-#{resolved_name}" if parent
|
122
|
+
self.tabs = parent.tabs + (parent.resolved_value.empty? ? 0 : 1) if parent && style == :nested
|
94
123
|
super
|
95
124
|
end
|
96
125
|
|
@@ -100,8 +129,14 @@ module Sass::Tree
|
|
100
129
|
# @param environment [Sass::Environment] The lexical environment containing
|
101
130
|
# variable and mixin values
|
102
131
|
def perform!(environment)
|
103
|
-
@
|
104
|
-
|
132
|
+
@resolved_name = run_interp(@name, environment)
|
133
|
+
val = @value.perform(environment)
|
134
|
+
@resolved_value =
|
135
|
+
if @value.context == :equals && val.is_a?(Sass::Script::String)
|
136
|
+
val.value
|
137
|
+
else
|
138
|
+
val.to_s
|
139
|
+
end
|
105
140
|
super
|
106
141
|
end
|
107
142
|
|
@@ -124,16 +159,58 @@ module Sass::Tree
|
|
124
159
|
raise Sass::SyntaxError.new("Illegal property syntax: can't use new syntax when :property_syntax => :old is set.")
|
125
160
|
elsif @options[:property_syntax] == :new && @prop_syntax == :old
|
126
161
|
raise Sass::SyntaxError.new("Illegal property syntax: can't use old syntax when :property_syntax => :new is set.")
|
127
|
-
elsif
|
128
|
-
raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no \";\" required at end-of-line).")
|
129
|
-
elsif value.empty?
|
162
|
+
elsif resolved_value.empty?
|
130
163
|
raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no value)." +
|
131
164
|
pseudo_class_selector_message)
|
132
165
|
end
|
133
166
|
end
|
134
167
|
|
135
168
|
def declaration
|
136
|
-
|
169
|
+
if @prop_syntax == :new
|
170
|
+
"#{resolved_name}: #{resolved_value}"
|
171
|
+
else
|
172
|
+
":#{resolved_name} #{resolved_value}"
|
173
|
+
end.strip
|
174
|
+
end
|
175
|
+
|
176
|
+
class << self
|
177
|
+
# @private
|
178
|
+
def val_to_sass(value)
|
179
|
+
return value.to_sass unless value.context == :equals
|
180
|
+
val_to_sass_comma(value).to_sass
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def val_to_sass_comma(node)
|
186
|
+
return node unless node.is_a?(Sass::Script::Operation)
|
187
|
+
return val_to_sass_concat(node) unless node.operator == :comma
|
188
|
+
|
189
|
+
Sass::Script::Operation.new(
|
190
|
+
val_to_sass_concat(node.operand1),
|
191
|
+
val_to_sass_comma(node.operand2),
|
192
|
+
node.operator)
|
193
|
+
end
|
194
|
+
|
195
|
+
def val_to_sass_concat(node)
|
196
|
+
return node unless node.is_a?(Sass::Script::Operation)
|
197
|
+
return val_to_sass_div(node) unless node.operator == :concat
|
198
|
+
|
199
|
+
Sass::Script::Operation.new(
|
200
|
+
val_to_sass_div(node.operand1),
|
201
|
+
val_to_sass_concat(node.operand2),
|
202
|
+
node.operator)
|
203
|
+
end
|
204
|
+
|
205
|
+
def val_to_sass_div(node)
|
206
|
+
unless node.is_a?(Sass::Script::Operation) && node.operator == :div &&
|
207
|
+
node.operand1.is_a?(Sass::Script::Number) &&
|
208
|
+
node.operand2.is_a?(Sass::Script::Number)
|
209
|
+
return node
|
210
|
+
end
|
211
|
+
|
212
|
+
Sass::Script::String.new("(#{node.to_sass})")
|
213
|
+
end
|
137
214
|
end
|
138
215
|
end
|
139
216
|
end
|
data/lib/sass/tree/root_node.rb
CHANGED
@@ -44,8 +44,37 @@ module Sass
|
|
44
44
|
super
|
45
45
|
end
|
46
46
|
|
47
|
+
# Converts a node to Sass code that will generate it.
|
48
|
+
#
|
49
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
50
|
+
# @return [String] The Sass code corresponding to the node
|
51
|
+
def to_sass(opts = {})
|
52
|
+
to_src(opts, :sass)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Converts a node to SCSS code that will generate it.
|
56
|
+
#
|
57
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
58
|
+
# @return [String] The SCSS code corresponding to the node
|
59
|
+
def to_scss(opts = {})
|
60
|
+
to_src(opts, :scss)
|
61
|
+
end
|
62
|
+
|
47
63
|
protected
|
48
64
|
|
65
|
+
def to_src(opts, fmt)
|
66
|
+
Haml::Util.enum_cons(children + [nil], 2).map do |child, nxt|
|
67
|
+
child.send("to_#{fmt}", 0, opts) +
|
68
|
+
if nxt &&
|
69
|
+
(child.is_a?(CommentNode) && child.line + child.value.count("\n") + 1 == nxt.line) ||
|
70
|
+
(child.is_a?(ImportNode) && nxt.is_a?(ImportNode) && child.line + 1 == nxt.line)
|
71
|
+
""
|
72
|
+
else
|
73
|
+
"\n"
|
74
|
+
end
|
75
|
+
end.join.rstrip + "\n"
|
76
|
+
end
|
77
|
+
|
49
78
|
# Destructively converts this static Sass node into a static CSS node,
|
50
79
|
# and checks that there are no properties at root level.
|
51
80
|
#
|
@@ -76,6 +105,14 @@ module Sass
|
|
76
105
|
return "" if result.empty?
|
77
106
|
return result + "\n"
|
78
107
|
end
|
108
|
+
|
109
|
+
# Returns false, because all nodes are allowed at the root of the document
|
110
|
+
# (properties are detected elsewhere post-mixin-resolution).
|
111
|
+
#
|
112
|
+
# @see Node#invalid_child?
|
113
|
+
def invalid_child?(child)
|
114
|
+
false
|
115
|
+
end
|
79
116
|
end
|
80
117
|
end
|
81
118
|
end
|