haml 2.2.24 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/.yardopts +0 -1
- data/README.md +91 -151
- data/REMEMBER +11 -1
- data/Rakefile +73 -55
- data/VERSION +1 -1
- data/VERSION_NAME +1 -1
- data/bin/css2sass +7 -1
- data/bin/sass-convert +7 -0
- data/extra/haml-mode.el +2 -1
- data/lib/haml/buffer.rb +22 -4
- data/lib/haml/engine.rb +5 -1
- data/lib/haml/exec.rb +231 -46
- data/lib/haml/filters.rb +19 -8
- data/lib/haml/helpers.rb +47 -20
- data/lib/haml/helpers/action_view_extensions.rb +2 -4
- data/lib/haml/helpers/action_view_mods.rb +11 -8
- data/lib/haml/helpers/xss_mods.rb +13 -2
- data/lib/haml/html.rb +179 -48
- data/lib/haml/html/erb.rb +141 -0
- data/lib/haml/precompiler.rb +40 -15
- data/lib/haml/railtie.rb +1 -5
- data/lib/haml/root.rb +3 -0
- data/lib/haml/template.rb +4 -14
- data/lib/haml/util.rb +120 -30
- data/lib/haml/version.rb +25 -2
- data/lib/sass.rb +5 -1
- data/lib/sass/callbacks.rb +50 -0
- data/lib/sass/css.rb +40 -191
- data/lib/sass/engine.rb +170 -74
- data/lib/sass/environment.rb +8 -2
- data/lib/sass/error.rb +163 -25
- data/lib/sass/files.rb +31 -28
- data/lib/sass/plugin.rb +268 -87
- data/lib/sass/plugin/rails.rb +9 -4
- data/lib/sass/repl.rb +1 -1
- data/lib/sass/script.rb +31 -29
- data/lib/sass/script/bool.rb +1 -0
- data/lib/sass/script/color.rb +290 -23
- data/lib/sass/script/css_lexer.rb +22 -0
- data/lib/sass/script/css_parser.rb +28 -0
- data/lib/sass/script/funcall.rb +22 -3
- data/lib/sass/script/functions.rb +523 -33
- data/lib/sass/script/interpolation.rb +42 -0
- data/lib/sass/script/lexer.rb +169 -52
- data/lib/sass/script/literal.rb +58 -9
- data/lib/sass/script/node.rb +79 -1
- data/lib/sass/script/number.rb +20 -5
- data/lib/sass/script/operation.rb +49 -3
- data/lib/sass/script/parser.rb +162 -28
- data/lib/sass/script/string.rb +50 -2
- data/lib/sass/script/unary_operation.rb +25 -2
- data/lib/sass/script/variable.rb +21 -4
- 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 +69 -27
- data/lib/sass/tree/debug_node.rb +7 -2
- data/lib/sass/tree/directive_node.rb +41 -35
- data/lib/sass/tree/for_node.rb +6 -0
- data/lib/sass/tree/if_node.rb +13 -1
- data/lib/sass/tree/import_node.rb +52 -27
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +41 -6
- data/lib/sass/tree/node.rb +197 -70
- data/lib/sass/tree/prop_node.rb +152 -57
- data/lib/sass/tree/root_node.rb +118 -0
- data/lib/sass/tree/rule_node.rb +193 -96
- data/lib/sass/tree/variable_node.rb +9 -5
- data/lib/sass/tree/while_node.rb +4 -0
- data/test/benchmark.rb +5 -5
- data/test/haml/engine_test.rb +147 -10
- data/test/haml/{rhtml/_av_partial_1.rhtml → erb/_av_partial_1.erb} +1 -1
- data/test/haml/{rhtml/_av_partial_2.rhtml → erb/_av_partial_2.erb} +1 -1
- data/test/haml/{rhtml/action_view.rhtml → erb/action_view.erb} +1 -1
- data/test/haml/{rhtml/standard.rhtml → erb/standard.erb} +0 -0
- data/test/haml/helper_test.rb +91 -24
- data/test/haml/html2haml/erb_tests.rb +410 -0
- data/test/haml/html2haml_test.rb +210 -66
- data/test/haml/results/filters.xhtml +1 -1
- data/test/haml/results/just_stuff.xhtml +2 -0
- data/test/haml/spec_test.rb +44 -0
- data/test/haml/template_test.rb +22 -2
- data/test/haml/templates/helpers.haml +0 -13
- data/test/haml/templates/just_stuff.haml +2 -0
- data/test/haml/util_test.rb +48 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +884 -0
- data/test/sass/css2sass_test.rb +99 -18
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +1049 -131
- data/test/sass/functions_test.rb +398 -47
- 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 +184 -10
- 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/options.css +1 -0
- 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 +137 -70
- 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 +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- 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/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +2 -2
- data/test/sass/templates/nested_bork1.sass +2 -0
- data/test/sass/templates/nested_bork2.sass +2 -0
- data/test/sass/templates/nested_bork3.sass +2 -0
- data/test/sass/templates/nested_bork4.sass +2 -0
- data/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- 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 +20 -8
- data/vendor/fssm/LICENSE +20 -0
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +14 -0
- metadata +94 -14
- data/test/sass/templates/bork.sass +0 -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
@@ -1,10 +1,18 @@
|
|
1
1
|
require 'sass/tree/node'
|
2
2
|
|
3
3
|
module Sass::Tree
|
4
|
-
# A
|
4
|
+
# A static node representing a mixin include.
|
5
|
+
# When in a static tree, the sole purpose is to wrap exceptions
|
6
|
+
# to add the mixin to the backtrace.
|
5
7
|
#
|
6
8
|
# @see Sass::Tree
|
7
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
|
+
|
8
16
|
# @param name [String] The name of the mixin
|
9
17
|
# @param args [Array<Script::Node>] The arguments to the mixin
|
10
18
|
def initialize(name, args)
|
@@ -13,18 +21,36 @@ module Sass::Tree
|
|
13
21
|
super()
|
14
22
|
end
|
15
23
|
|
24
|
+
# @see Node#cssize
|
25
|
+
def cssize(parent = nil)
|
26
|
+
_cssize(parent) # Pass on the parent even if it's not a MixinNode
|
27
|
+
end
|
28
|
+
|
16
29
|
protected
|
17
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
|
+
|
36
|
+
# @see Node#_cssize
|
37
|
+
def _cssize(parent)
|
38
|
+
children.map {|c| c.cssize(parent)}.flatten
|
39
|
+
rescue Sass::SyntaxError => e
|
40
|
+
e.modify_backtrace(:mixin => @name, :line => line)
|
41
|
+
e.add_backtrace(:filename => filename, :line => line)
|
42
|
+
raise e
|
43
|
+
end
|
44
|
+
|
18
45
|
# Runs the mixin.
|
19
46
|
#
|
20
47
|
# @param environment [Sass::Environment] The lexical environment containing
|
21
48
|
# variable and mixin values
|
22
|
-
# @return [Array<Tree::Node>] The resulting static nodes
|
23
49
|
# @raise [Sass::SyntaxError] if there is no mixin with the given name
|
24
50
|
# @raise [Sass::SyntaxError] if an incorrect number of arguments was passed
|
25
51
|
# @see Sass::Tree
|
26
|
-
def
|
27
|
-
raise Sass::SyntaxError.new("Undefined mixin '#{@name}'."
|
52
|
+
def perform!(environment)
|
53
|
+
raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.") unless mixin = environment.mixin(@name)
|
28
54
|
|
29
55
|
raise Sass::SyntaxError.new(<<END.gsub("\n", "")) if mixin.args.size < @args.size
|
30
56
|
Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
|
@@ -37,12 +63,21 @@ END
|
|
37
63
|
if value
|
38
64
|
value.perform(environment)
|
39
65
|
elsif default
|
40
|
-
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
|
41
71
|
end)
|
42
72
|
raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter #{var.inspect}.") unless env.var(var.name)
|
43
73
|
env
|
44
74
|
end
|
45
|
-
|
75
|
+
|
76
|
+
self.children = mixin.tree.map {|c| c.perform(environment)}.flatten
|
77
|
+
rescue Sass::SyntaxError => e
|
78
|
+
e.modify_backtrace(:mixin => @name, :line => @line)
|
79
|
+
e.add_backtrace(:line => @line)
|
80
|
+
raise e
|
46
81
|
end
|
47
82
|
end
|
48
83
|
end
|
data/lib/sass/tree/node.rb
CHANGED
@@ -1,28 +1,45 @@
|
|
1
1
|
module Sass
|
2
2
|
# A namespace for nodes in the Sass parse tree.
|
3
3
|
#
|
4
|
-
# The Sass parse tree has
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# The Sass parse tree has three states: dynamic, static Sass, and static CSS.
|
5
|
+
#
|
6
|
+
# When it's first parsed, a Sass document is in the dynamic state.
|
7
|
+
# It has nodes for mixin definitions and `@for` loops and so forth,
|
7
8
|
# in addition to nodes for CSS rules and properties.
|
9
|
+
# Nodes that only appear in this state are called **dynamic nodes**.
|
8
10
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# than it does to the original Sass document.
|
12
|
-
# It still has nodes for CSS rules and properties,
|
11
|
+
# {Tree::Node#perform} returns a static Sass tree, which is different.
|
12
|
+
# It still has nodes for CSS rules and properties
|
13
13
|
# but it doesn't have any dynamic-generation-related nodes.
|
14
|
+
# The nodes in this state are in the same structure as the Sass document:
|
15
|
+
# rules and properties are nested beneath one another.
|
16
|
+
# Nodes that can be in this state or in the dynamic state
|
17
|
+
# are called **static nodes**.
|
18
|
+
#
|
19
|
+
# {Tree::Node#cssize} then returns a static CSS tree.
|
20
|
+
# This is like a static Sass tree,
|
21
|
+
# but the structure exactly mirrors that of the generated CSS.
|
22
|
+
# Rules and properties can't be nested beneath one another in this state.
|
14
23
|
#
|
15
|
-
#
|
16
|
-
#
|
24
|
+
# Finally, {Tree::Node#to_s} can be called on a static CSS tree
|
25
|
+
# to get the actual CSS code as a string.
|
17
26
|
module Tree
|
18
|
-
#
|
19
|
-
# and the superclass of all other parse-tree nodes.
|
27
|
+
# The abstract superclass of all parse-tree nodes.
|
20
28
|
class Node
|
29
|
+
include Enumerable
|
30
|
+
|
21
31
|
# The child nodes of this node.
|
22
32
|
#
|
23
33
|
# @return [Array<Tree::Node>]
|
24
34
|
attr_accessor :children
|
25
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
|
+
|
26
43
|
# The line of the document on which this node appeared.
|
27
44
|
#
|
28
45
|
# @return [Fixnum]
|
@@ -52,6 +69,12 @@ module Sass
|
|
52
69
|
@options = options
|
53
70
|
end
|
54
71
|
|
72
|
+
# @private
|
73
|
+
def children=(children)
|
74
|
+
self.has_children ||= !children.empty?
|
75
|
+
@children = children
|
76
|
+
end
|
77
|
+
|
55
78
|
# The name of the document on which this node appeared.
|
56
79
|
#
|
57
80
|
# @return [String]
|
@@ -65,21 +88,14 @@ module Sass
|
|
65
88
|
# @raise [Sass::SyntaxError] if `child` is invalid
|
66
89
|
# @see #invalid_child?
|
67
90
|
def <<(child)
|
91
|
+
return if child.nil?
|
68
92
|
if msg = invalid_child?(child)
|
69
|
-
raise Sass::SyntaxError.new(msg, child.line)
|
93
|
+
raise Sass::SyntaxError.new(msg, :line => child.line)
|
70
94
|
end
|
95
|
+
self.has_children = true
|
71
96
|
@children << child
|
72
97
|
end
|
73
98
|
|
74
|
-
# Return the last child node.
|
75
|
-
#
|
76
|
-
# We need this because {Tree::Node} duck types as an Array for {Sass::Engine}.
|
77
|
-
#
|
78
|
-
# @return [Tree::Node] The last child node
|
79
|
-
def last
|
80
|
-
children.last
|
81
|
-
end
|
82
|
-
|
83
99
|
# Compares this node and another object (only other {Tree::Node}s will be equal).
|
84
100
|
# This does a structural comparison;
|
85
101
|
# if the contents of the nodes and all the child nodes are equivalent,
|
@@ -100,7 +116,7 @@ module Sass
|
|
100
116
|
# @see #perform
|
101
117
|
# @see #to_s
|
102
118
|
def render
|
103
|
-
perform(Environment.new).to_s
|
119
|
+
perform(Environment.new).cssize.to_s
|
104
120
|
end
|
105
121
|
|
106
122
|
# True if \{#to\_s} will return `nil`;
|
@@ -110,43 +126,55 @@ module Sass
|
|
110
126
|
# @return [Boolean]
|
111
127
|
def invisible?; false; end
|
112
128
|
|
113
|
-
#
|
129
|
+
# The output style. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
|
130
|
+
#
|
131
|
+
# @return [Symbol]
|
132
|
+
def style
|
133
|
+
@options[:style]
|
134
|
+
end
|
135
|
+
|
136
|
+
# Computes the CSS corresponding to this static CSS tree.
|
114
137
|
#
|
138
|
+
# \{#to_s} shouldn't be overridden directly; instead, override \{#\_to\_s}.
|
115
139
|
# Only static-node subclasses need to implement \{#to\_s}.
|
116
140
|
#
|
117
141
|
# This may return `nil`, but it will only do so if \{#invisible?} is true.
|
118
142
|
#
|
143
|
+
# @param args [Array] Passed on to \{#\_to\_s}
|
119
144
|
# @return [String, nil] The resulting CSS
|
145
|
+
# @see Sass::Tree
|
146
|
+
def to_s(*args)
|
147
|
+
_to_s(*args)
|
148
|
+
rescue Sass::SyntaxError => e
|
149
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
150
|
+
raise e
|
151
|
+
end
|
152
|
+
|
153
|
+
# Converts a static Sass tree (e.g. the output of \{#perform})
|
154
|
+
# into a static CSS tree.
|
155
|
+
#
|
156
|
+
# \{#cssize} shouldn't be overridden directly;
|
157
|
+
# instead, override \{#\_cssize} or \{#cssize!}.
|
158
|
+
#
|
159
|
+
# @param parent [Node, nil] The parent node of this node.
|
160
|
+
# This should only be non-nil if the parent is the same class as this node
|
161
|
+
# @return [Tree::Node] The resulting tree of static nodes
|
120
162
|
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
121
163
|
# @see Sass::Tree
|
122
|
-
def
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
child.pseudo_class_selector_message
|
128
|
-
raise Sass::SyntaxError.new(message, child.line)
|
129
|
-
else
|
130
|
-
next if child.invisible?
|
131
|
-
child_str = child.to_s(1)
|
132
|
-
result << child_str + (style == :compressed ? '' : "\n")
|
133
|
-
end
|
134
|
-
end
|
135
|
-
result.rstrip!
|
136
|
-
return "" if result.empty?
|
137
|
-
return result + "\n"
|
138
|
-
rescue Sass::SyntaxError => e; e.add_metadata(filename, line)
|
164
|
+
def cssize(parent = nil)
|
165
|
+
_cssize((parent if parent.class == self.class))
|
166
|
+
rescue Sass::SyntaxError => e
|
167
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
168
|
+
raise e
|
139
169
|
end
|
140
170
|
|
141
|
-
#
|
171
|
+
# Converts a dynamic tree into a static Sass tree.
|
172
|
+
# That is, runs the dynamic Sass code:
|
142
173
|
# mixins, variables, control directives, and so forth.
|
143
174
|
# This doesn't modify this node or any of its children.
|
144
175
|
#
|
145
176
|
# \{#perform} shouldn't be overridden directly;
|
146
|
-
#
|
147
|
-
# override \{#\_perform};
|
148
|
-
# if you want to destructively modify this node,
|
149
|
-
# override \{#perform!}.
|
177
|
+
# instead, override \{#\_perform} or \{#perform!}.
|
150
178
|
#
|
151
179
|
# @param environment [Sass::Environment] The lexical environment containing
|
152
180
|
# variable and mixin values
|
@@ -154,20 +182,84 @@ module Sass
|
|
154
182
|
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
155
183
|
# @see Sass::Tree
|
156
184
|
def perform(environment)
|
157
|
-
environment.options = @options if self.class == Tree::Node
|
158
185
|
_perform(environment)
|
159
|
-
rescue Sass::SyntaxError => e
|
186
|
+
rescue Sass::SyntaxError => e
|
187
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
188
|
+
raise e
|
160
189
|
end
|
161
190
|
|
162
|
-
#
|
191
|
+
# Iterates through each node in the tree rooted at this node
|
192
|
+
# in a pre-order walk.
|
163
193
|
#
|
164
|
-
# @
|
165
|
-
|
166
|
-
|
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)
|
167
217
|
end
|
168
218
|
|
169
219
|
protected
|
170
220
|
|
221
|
+
# Computes the CSS corresponding to this particular Sass node.
|
222
|
+
#
|
223
|
+
# This method should never raise {Sass::SyntaxError}s.
|
224
|
+
# Such errors will not be properly annotated with Sass backtrace information.
|
225
|
+
# All error conditions should be checked in earlier transformations,
|
226
|
+
# such as \{#cssize} and \{#perform}.
|
227
|
+
#
|
228
|
+
# @param args [Array] ignored
|
229
|
+
# @return [String, nil] The resulting CSS
|
230
|
+
# @see #to_s
|
231
|
+
# @see Sass::Tree
|
232
|
+
def _to_s
|
233
|
+
raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #_to_s or #to_s.")
|
234
|
+
end
|
235
|
+
|
236
|
+
# Converts this static Sass node into a static CSS node,
|
237
|
+
# returning the new node.
|
238
|
+
# This doesn't modify this node or any of its children.
|
239
|
+
#
|
240
|
+
# @param parent [Node, nil] The parent node of this node.
|
241
|
+
# This should only be non-nil if the parent is the same class as this node
|
242
|
+
# @return [Tree::Node, Array<Tree::Node>] The resulting static CSS nodes
|
243
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
244
|
+
# @see #cssize
|
245
|
+
# @see Sass::Tree
|
246
|
+
def _cssize(parent)
|
247
|
+
node = dup
|
248
|
+
node.cssize!(parent)
|
249
|
+
node
|
250
|
+
end
|
251
|
+
|
252
|
+
# Destructively converts this static Sass node into a static CSS node.
|
253
|
+
# This *does* modify this node,
|
254
|
+
# but will be run non-destructively by \{#\_cssize\}.
|
255
|
+
#
|
256
|
+
# @param parent [Node, nil] The parent node of this node.
|
257
|
+
# This should only be non-nil if the parent is the same class as this node
|
258
|
+
# @see #cssize
|
259
|
+
def cssize!(parent)
|
260
|
+
self.children = children.map {|c| c.cssize(self)}.flatten
|
261
|
+
end
|
262
|
+
|
171
263
|
# Runs any dynamic Sass code in this particular node.
|
172
264
|
# This doesn't modify this node or any of its children.
|
173
265
|
#
|
@@ -202,27 +294,21 @@ module Sass
|
|
202
294
|
children.map {|c| c.perform(environment)}.flatten
|
203
295
|
end
|
204
296
|
|
205
|
-
# Replaces SassScript in a chunk of text
|
297
|
+
# Replaces SassScript in a chunk of text
|
206
298
|
# with the resulting value.
|
207
299
|
#
|
208
|
-
# @param text [String] The text to interpolate
|
300
|
+
# @param text [Array<String, Sass::Script::Node>] The text to interpolate
|
209
301
|
# @param environment [Sass::Environment] The lexical environment containing
|
210
302
|
# variable and mixin values
|
211
303
|
# @return [String] The interpolated text
|
212
|
-
def
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
res << "\\" * [0, escapes - 1].max
|
221
|
-
res << Script::Parser.new(scan, line, scan.pos - scan.matched_size, filename).
|
222
|
-
parse_interpolated.perform(environment).to_s
|
223
|
-
end
|
224
|
-
end
|
225
|
-
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
|
226
312
|
end
|
227
313
|
|
228
314
|
# @see Haml::Shared.balance
|
@@ -230,13 +316,14 @@ module Sass
|
|
230
316
|
def balance(*args)
|
231
317
|
res = Haml::Shared.balance(*args)
|
232
318
|
return res if res
|
233
|
-
raise Sass::SyntaxError.new("Unbalanced brackets.", line)
|
319
|
+
raise Sass::SyntaxError.new("Unbalanced brackets.", :line => line)
|
234
320
|
end
|
235
321
|
|
236
322
|
# Returns an error message if the given child node is invalid,
|
237
323
|
# and false otherwise.
|
238
324
|
#
|
239
|
-
# 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.
|
240
327
|
# This is expected to be overriden by subclasses
|
241
328
|
# for which some children are invalid.
|
242
329
|
#
|
@@ -244,7 +331,47 @@ module Sass
|
|
244
331
|
# @return [Boolean, String] Whether or not the child node is valid,
|
245
332
|
# as well as the error message to display if it is invalid
|
246
333
|
def invalid_child?(child)
|
247
|
-
|
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 ? "" : ";"
|
248
375
|
end
|
249
376
|
end
|
250
377
|
end
|