drnic-haml 2.3.0
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/.yardopts +5 -0
- data/CONTRIBUTING +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +347 -0
- data/REVISION +1 -0
- data/Rakefile +371 -0
- data/VERSION +1 -0
- data/VERSION_NAME +1 -0
- data/bin/css2sass +7 -0
- data/bin/haml +9 -0
- data/bin/html2haml +7 -0
- data/bin/sass +8 -0
- data/extra/haml-mode.el +663 -0
- data/extra/sass-mode.el +205 -0
- data/extra/update_watch.rb +13 -0
- data/init.rb +8 -0
- data/lib/haml.rb +40 -0
- data/lib/haml/buffer.rb +307 -0
- data/lib/haml/engine.rb +301 -0
- data/lib/haml/error.rb +22 -0
- data/lib/haml/exec.rb +470 -0
- data/lib/haml/filters.rb +341 -0
- data/lib/haml/helpers.rb +560 -0
- data/lib/haml/helpers/action_view_extensions.rb +40 -0
- data/lib/haml/helpers/action_view_mods.rb +176 -0
- data/lib/haml/herb.rb +96 -0
- data/lib/haml/html.rb +308 -0
- data/lib/haml/precompiler.rb +997 -0
- data/lib/haml/shared.rb +78 -0
- data/lib/haml/template.rb +51 -0
- data/lib/haml/template/patch.rb +58 -0
- data/lib/haml/template/plugin.rb +71 -0
- data/lib/haml/util.rb +244 -0
- data/lib/haml/version.rb +64 -0
- data/lib/sass.rb +24 -0
- data/lib/sass/css.rb +423 -0
- data/lib/sass/engine.rb +491 -0
- data/lib/sass/environment.rb +79 -0
- data/lib/sass/error.rb +162 -0
- data/lib/sass/files.rb +133 -0
- data/lib/sass/plugin.rb +170 -0
- data/lib/sass/plugin/merb.rb +57 -0
- data/lib/sass/plugin/rails.rb +23 -0
- data/lib/sass/repl.rb +58 -0
- data/lib/sass/script.rb +55 -0
- data/lib/sass/script/bool.rb +17 -0
- data/lib/sass/script/color.rb +183 -0
- data/lib/sass/script/funcall.rb +50 -0
- data/lib/sass/script/functions.rb +199 -0
- data/lib/sass/script/lexer.rb +191 -0
- data/lib/sass/script/literal.rb +177 -0
- data/lib/sass/script/node.rb +14 -0
- data/lib/sass/script/number.rb +381 -0
- data/lib/sass/script/operation.rb +45 -0
- data/lib/sass/script/parser.rb +222 -0
- data/lib/sass/script/string.rb +12 -0
- data/lib/sass/script/unary_operation.rb +34 -0
- data/lib/sass/script/variable.rb +31 -0
- data/lib/sass/tree/comment_node.rb +84 -0
- data/lib/sass/tree/debug_node.rb +30 -0
- data/lib/sass/tree/directive_node.rb +70 -0
- data/lib/sass/tree/for_node.rb +48 -0
- data/lib/sass/tree/if_node.rb +54 -0
- data/lib/sass/tree/import_node.rb +69 -0
- data/lib/sass/tree/mixin_def_node.rb +29 -0
- data/lib/sass/tree/mixin_node.rb +48 -0
- data/lib/sass/tree/node.rb +252 -0
- data/lib/sass/tree/prop_node.rb +106 -0
- data/lib/sass/tree/root_node.rb +56 -0
- data/lib/sass/tree/rule_node.rb +220 -0
- data/lib/sass/tree/variable_node.rb +34 -0
- data/lib/sass/tree/while_node.rb +31 -0
- data/rails/init.rb +1 -0
- data/test/benchmark.rb +99 -0
- data/test/haml/engine_test.rb +1129 -0
- data/test/haml/helper_test.rb +282 -0
- data/test/haml/html2haml_test.rb +258 -0
- data/test/haml/markaby/standard.mab +52 -0
- data/test/haml/mocks/article.rb +6 -0
- data/test/haml/results/content_for_layout.xhtml +12 -0
- data/test/haml/results/eval_suppressed.xhtml +9 -0
- data/test/haml/results/filters.xhtml +62 -0
- data/test/haml/results/helpers.xhtml +93 -0
- data/test/haml/results/helpful.xhtml +10 -0
- data/test/haml/results/just_stuff.xhtml +68 -0
- data/test/haml/results/list.xhtml +12 -0
- data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
- data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/test/haml/results/original_engine.xhtml +20 -0
- data/test/haml/results/partial_layout.xhtml +5 -0
- data/test/haml/results/partials.xhtml +21 -0
- data/test/haml/results/render_layout.xhtml +3 -0
- data/test/haml/results/silent_script.xhtml +74 -0
- data/test/haml/results/standard.xhtml +162 -0
- data/test/haml/results/tag_parsing.xhtml +23 -0
- data/test/haml/results/very_basic.xhtml +5 -0
- data/test/haml/results/whitespace_handling.xhtml +89 -0
- data/test/haml/rhtml/_av_partial_1.rhtml +12 -0
- data/test/haml/rhtml/_av_partial_2.rhtml +8 -0
- data/test/haml/rhtml/action_view.rhtml +62 -0
- data/test/haml/rhtml/standard.rhtml +54 -0
- data/test/haml/spec_test.rb +44 -0
- data/test/haml/template_test.rb +217 -0
- data/test/haml/templates/_av_partial_1.haml +9 -0
- data/test/haml/templates/_av_partial_1_ugly.haml +9 -0
- data/test/haml/templates/_av_partial_2.haml +5 -0
- data/test/haml/templates/_av_partial_2_ugly.haml +5 -0
- data/test/haml/templates/_layout.erb +3 -0
- data/test/haml/templates/_layout_for_partial.haml +3 -0
- data/test/haml/templates/_partial.haml +8 -0
- data/test/haml/templates/_text_area.haml +3 -0
- data/test/haml/templates/action_view.haml +47 -0
- data/test/haml/templates/action_view_ugly.haml +47 -0
- data/test/haml/templates/breakage.haml +8 -0
- data/test/haml/templates/content_for_layout.haml +8 -0
- data/test/haml/templates/eval_suppressed.haml +11 -0
- data/test/haml/templates/filters.haml +66 -0
- data/test/haml/templates/helpers.haml +95 -0
- data/test/haml/templates/helpful.haml +11 -0
- data/test/haml/templates/just_stuff.haml +83 -0
- data/test/haml/templates/list.haml +12 -0
- data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/original_engine.haml +17 -0
- data/test/haml/templates/partial_layout.haml +3 -0
- data/test/haml/templates/partialize.haml +1 -0
- data/test/haml/templates/partials.haml +12 -0
- data/test/haml/templates/render_layout.haml +2 -0
- data/test/haml/templates/silent_script.haml +40 -0
- data/test/haml/templates/standard.haml +42 -0
- data/test/haml/templates/standard_ugly.haml +42 -0
- data/test/haml/templates/tag_parsing.haml +21 -0
- data/test/haml/templates/very_basic.haml +4 -0
- data/test/haml/templates/whitespace_handling.haml +87 -0
- data/test/haml/util_test.rb +92 -0
- data/test/linked_rails.rb +12 -0
- data/test/sass/css2sass_test.rb +294 -0
- data/test/sass/engine_test.rb +956 -0
- data/test/sass/functions_test.rb +126 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +229 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +87 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/import.css +29 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/script_test.rb +261 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork1.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +307 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/import.sass +11 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- 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/parent_ref.sass +25 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/test_helper.rb +44 -0
- metadata +298 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'sass/tree/node'
|
|
2
|
+
|
|
3
|
+
module Sass::Tree
|
|
4
|
+
# A dynamic node representing a mixin include.
|
|
5
|
+
#
|
|
6
|
+
# @see Sass::Tree
|
|
7
|
+
class MixinNode < Node
|
|
8
|
+
# @param name [String] The name of the mixin
|
|
9
|
+
# @param args [Array<Script::Node>] The arguments to the mixin
|
|
10
|
+
def initialize(name, args)
|
|
11
|
+
@name = name
|
|
12
|
+
@args = args
|
|
13
|
+
super()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
# Runs the mixin.
|
|
19
|
+
#
|
|
20
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
21
|
+
# variable and mixin values
|
|
22
|
+
# @return [Array<Tree::Node>] The resulting static nodes
|
|
23
|
+
# @raise [Sass::SyntaxError] if there is no mixin with the given name
|
|
24
|
+
# @raise [Sass::SyntaxError] if an incorrect number of arguments was passed
|
|
25
|
+
# @see Sass::Tree
|
|
26
|
+
def _perform(environment)
|
|
27
|
+
raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.") unless mixin = environment.mixin(@name)
|
|
28
|
+
|
|
29
|
+
raise Sass::SyntaxError.new(<<END.gsub("\n", "")) if mixin.args.size < @args.size
|
|
30
|
+
Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
|
|
31
|
+
but #{@args.size} #{@args.size == 1 ? 'was' : 'were'} passed.
|
|
32
|
+
END
|
|
33
|
+
|
|
34
|
+
environment = mixin.args.zip(@args).
|
|
35
|
+
inject(Sass::Environment.new(mixin.environment)) do |env, ((var, default), value)|
|
|
36
|
+
env.set_local_var(var.name,
|
|
37
|
+
if value
|
|
38
|
+
value.perform(environment)
|
|
39
|
+
elsif default
|
|
40
|
+
default.perform(env)
|
|
41
|
+
end)
|
|
42
|
+
raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter #{var.inspect}.") unless env.var(var.name)
|
|
43
|
+
env
|
|
44
|
+
end
|
|
45
|
+
mixin.tree.map {|c| c.perform(environment)}.flatten
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
module Sass
|
|
2
|
+
# A namespace for nodes in the Sass parse tree.
|
|
3
|
+
#
|
|
4
|
+
# The Sass parse tree has two states.
|
|
5
|
+
# When it's first parsed, it has nodes for mixin definitions
|
|
6
|
+
# and for loops and so forth,
|
|
7
|
+
# in addition to nodes for CSS rules and properties.
|
|
8
|
+
#
|
|
9
|
+
# However, {Tree::Node#perform} returns a different sort of tree.
|
|
10
|
+
# This tree maps more closely to the resulting CSS document
|
|
11
|
+
# than it does to the original Sass document.
|
|
12
|
+
# It still has nodes for CSS rules and properties,
|
|
13
|
+
# but it doesn't have any dynamic-generation-related nodes.
|
|
14
|
+
#
|
|
15
|
+
# Nodes that only appear in the pre-perform state are called **dynamic nodes**;
|
|
16
|
+
# those that appear in both states are called **static nodes**.
|
|
17
|
+
module Tree
|
|
18
|
+
# The abstract superclass of all parse-tree nodes.
|
|
19
|
+
class Node
|
|
20
|
+
# The child nodes of this node.
|
|
21
|
+
#
|
|
22
|
+
# @return [Array<Tree::Node>]
|
|
23
|
+
attr_accessor :children
|
|
24
|
+
|
|
25
|
+
# The line of the document on which this node appeared.
|
|
26
|
+
#
|
|
27
|
+
# @return [Fixnum]
|
|
28
|
+
attr_accessor :line
|
|
29
|
+
|
|
30
|
+
# The name of the document on which this node appeared.
|
|
31
|
+
#
|
|
32
|
+
# @return [String]
|
|
33
|
+
attr_writer :filename
|
|
34
|
+
|
|
35
|
+
# The options hash for the node.
|
|
36
|
+
# See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
|
|
37
|
+
#
|
|
38
|
+
# @return [Hash<Symbol, Object>]
|
|
39
|
+
attr_reader :options
|
|
40
|
+
|
|
41
|
+
def initialize
|
|
42
|
+
@children = []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Sets the options hash for the node and all its children.
|
|
46
|
+
#
|
|
47
|
+
# @param options [Hash<Symbol, Object>] The options
|
|
48
|
+
# @see #options
|
|
49
|
+
def options=(options)
|
|
50
|
+
children.each {|c| c.options = options}
|
|
51
|
+
@options = options
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# The name of the document on which this node appeared.
|
|
55
|
+
#
|
|
56
|
+
# @return [String]
|
|
57
|
+
def filename
|
|
58
|
+
@filename || @options[:filename]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Appends a child to the node.
|
|
62
|
+
#
|
|
63
|
+
# @param child [Tree::Node] The child node
|
|
64
|
+
# @raise [Sass::SyntaxError] if `child` is invalid
|
|
65
|
+
# @see #invalid_child?
|
|
66
|
+
def <<(child)
|
|
67
|
+
if msg = invalid_child?(child)
|
|
68
|
+
raise Sass::SyntaxError.new(msg, :line => child.line)
|
|
69
|
+
end
|
|
70
|
+
@children << child
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Return the last child node.
|
|
74
|
+
#
|
|
75
|
+
# We need this because {Tree::Node} duck types as an Array for {Sass::Engine}.
|
|
76
|
+
#
|
|
77
|
+
# @return [Tree::Node] The last child node
|
|
78
|
+
def last
|
|
79
|
+
children.last
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Compares this node and another object (only other {Tree::Node}s will be equal).
|
|
83
|
+
# This does a structural comparison;
|
|
84
|
+
# if the contents of the nodes and all the child nodes are equivalent,
|
|
85
|
+
# then the nodes are as well.
|
|
86
|
+
#
|
|
87
|
+
# Only static nodes need to override this.
|
|
88
|
+
#
|
|
89
|
+
# @param other [Object] The object to compare with
|
|
90
|
+
# @return [Boolean] Whether or not this node and the other object
|
|
91
|
+
# are the same
|
|
92
|
+
# @see Sass::Tree
|
|
93
|
+
def ==(other)
|
|
94
|
+
self.class == other.class && other.children == children
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Runs the dynamic Sass code *and* computes the CSS for the tree.
|
|
98
|
+
#
|
|
99
|
+
# @see #perform
|
|
100
|
+
# @see #to_s
|
|
101
|
+
def render
|
|
102
|
+
perform(Environment.new).to_s
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# True if \{#to\_s} will return `nil`;
|
|
106
|
+
# that is, if the node shouldn't be rendered.
|
|
107
|
+
# Should only be called in a static tree.
|
|
108
|
+
#
|
|
109
|
+
# @return [Boolean]
|
|
110
|
+
def invisible?; false; end
|
|
111
|
+
|
|
112
|
+
# The output style. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
|
|
113
|
+
#
|
|
114
|
+
# @return [Symbol]
|
|
115
|
+
def style
|
|
116
|
+
@options[:style]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Computes the CSS corresponding to this Sass tree.
|
|
120
|
+
#
|
|
121
|
+
# Only static-node subclasses need to implement \{#to\_s}.
|
|
122
|
+
#
|
|
123
|
+
# This may return `nil`, but it will only do so if \{#invisible?} is true.
|
|
124
|
+
#
|
|
125
|
+
# @param args [Array] Passed on to \{#\_to\_s}
|
|
126
|
+
# @return [String, nil] The resulting CSS
|
|
127
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
|
128
|
+
# @see Sass::Tree
|
|
129
|
+
def to_s(*args)
|
|
130
|
+
_to_s(*args)
|
|
131
|
+
rescue Sass::SyntaxError => e
|
|
132
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
|
133
|
+
raise e
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Runs the dynamic Sass code:
|
|
137
|
+
# mixins, variables, control directives, and so forth.
|
|
138
|
+
# This doesn't modify this node or any of its children.
|
|
139
|
+
#
|
|
140
|
+
# \{#perform} shouldn't be overridden directly;
|
|
141
|
+
# if you want to return a new node (or list of nodes),
|
|
142
|
+
# override \{#\_perform};
|
|
143
|
+
# if you want to destructively modify this node,
|
|
144
|
+
# override \{#perform!}.
|
|
145
|
+
#
|
|
146
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
147
|
+
# variable and mixin values
|
|
148
|
+
# @return [Tree::Node] The resulting tree of static nodes
|
|
149
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
|
150
|
+
# @see Sass::Tree
|
|
151
|
+
def perform(environment)
|
|
152
|
+
environment.options = @options if self.class == Tree::Node
|
|
153
|
+
_perform(environment)
|
|
154
|
+
rescue Sass::SyntaxError => e
|
|
155
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
|
156
|
+
raise e
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
protected
|
|
160
|
+
|
|
161
|
+
# Computes the CSS corresponding to this particular Sass node.
|
|
162
|
+
#
|
|
163
|
+
# @param args [Array] ignored
|
|
164
|
+
# @return [String, nil] The resulting CSS
|
|
165
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
|
166
|
+
# @see #to_s
|
|
167
|
+
# @see Sass::Tree
|
|
168
|
+
def _to_s
|
|
169
|
+
raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #_to_s or #to_s.")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Runs any dynamic Sass code in this particular node.
|
|
173
|
+
# This doesn't modify this node or any of its children.
|
|
174
|
+
#
|
|
175
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
176
|
+
# variable and mixin values
|
|
177
|
+
# @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
|
|
178
|
+
# @see #perform
|
|
179
|
+
# @see Sass::Tree
|
|
180
|
+
def _perform(environment)
|
|
181
|
+
node = dup
|
|
182
|
+
node.perform!(environment)
|
|
183
|
+
node
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Destructively runs dynamic Sass code in this particular node.
|
|
187
|
+
# This *does* modify this node,
|
|
188
|
+
# but will be run non-destructively by \{#\_perform\}.
|
|
189
|
+
#
|
|
190
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
191
|
+
# variable and mixin values
|
|
192
|
+
# @see #perform
|
|
193
|
+
def perform!(environment)
|
|
194
|
+
self.children = perform_children(Environment.new(environment))
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Non-destructively runs \{#perform} on all children of the current node.
|
|
198
|
+
#
|
|
199
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
200
|
+
# variable and mixin values
|
|
201
|
+
# @return [Array<Tree::Node>] The resulting static nodes
|
|
202
|
+
def perform_children(environment)
|
|
203
|
+
children.map {|c| c.perform(environment)}.flatten
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Replaces SassScript in a chunk of text (via `#{}`)
|
|
207
|
+
# with the resulting value.
|
|
208
|
+
#
|
|
209
|
+
# @param text [String] The text to interpolate
|
|
210
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
211
|
+
# variable and mixin values
|
|
212
|
+
# @return [String] The interpolated text
|
|
213
|
+
def interpolate(text, environment)
|
|
214
|
+
res = ''
|
|
215
|
+
rest = Haml::Shared.handle_interpolation text do |scan|
|
|
216
|
+
escapes = scan[2].size
|
|
217
|
+
res << scan.matched[0...-2 - escapes]
|
|
218
|
+
if escapes % 2 == 1
|
|
219
|
+
res << "\\" * (escapes - 1) << '#{'
|
|
220
|
+
else
|
|
221
|
+
res << "\\" * [0, escapes - 1].max
|
|
222
|
+
res << Script::Parser.new(scan, line, scan.pos - scan.matched_size, filename).
|
|
223
|
+
parse_interpolated.perform(environment).to_s
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
res + rest
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# @see Haml::Shared.balance
|
|
230
|
+
# @raise [Sass::SyntaxError] if the brackets aren't balanced
|
|
231
|
+
def balance(*args)
|
|
232
|
+
res = Haml::Shared.balance(*args)
|
|
233
|
+
return res if res
|
|
234
|
+
raise Sass::SyntaxError.new("Unbalanced brackets.", :line => line)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Returns an error message if the given child node is invalid,
|
|
238
|
+
# and false otherwise.
|
|
239
|
+
#
|
|
240
|
+
# By default, all child nodes are valid.
|
|
241
|
+
# This is expected to be overriden by subclasses
|
|
242
|
+
# for which some children are invalid.
|
|
243
|
+
#
|
|
244
|
+
# @param child [Tree::Node] A potential child node
|
|
245
|
+
# @return [Boolean, String] Whether or not the child node is valid,
|
|
246
|
+
# as well as the error message to display if it is invalid
|
|
247
|
+
def invalid_child?(child)
|
|
248
|
+
false
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
module Sass::Tree
|
|
2
|
+
# A static node reprenting a CSS property.
|
|
3
|
+
#
|
|
4
|
+
# @see Sass::Tree
|
|
5
|
+
class PropNode < Node
|
|
6
|
+
# The name of the property.
|
|
7
|
+
#
|
|
8
|
+
# @return [String]
|
|
9
|
+
attr_accessor :name
|
|
10
|
+
|
|
11
|
+
# The value of the property,
|
|
12
|
+
# either a plain string or a SassScript parse tree.
|
|
13
|
+
#
|
|
14
|
+
# @return [String, Script::Node]
|
|
15
|
+
attr_accessor :value
|
|
16
|
+
|
|
17
|
+
# @param name [String] See \{#name}
|
|
18
|
+
# @param value [String] See \{#value}
|
|
19
|
+
# @param prop_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
|
|
20
|
+
# `:old` if it uses `:a b`-style syntax
|
|
21
|
+
def initialize(name, value, prop_syntax)
|
|
22
|
+
@name = name
|
|
23
|
+
@value = value
|
|
24
|
+
@prop_syntax = prop_syntax
|
|
25
|
+
super()
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Compares the names and values of two properties.
|
|
29
|
+
#
|
|
30
|
+
# @param other [Object] The object to compare with
|
|
31
|
+
# @return [Boolean] Whether or not this node and the other object
|
|
32
|
+
# are the same
|
|
33
|
+
def ==(other)
|
|
34
|
+
self.class == other.class && name == other.name && value == other.value && super
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
# Computes the CSS for the property.
|
|
40
|
+
#
|
|
41
|
+
# @param tabs [Fixnum] The level of indentation for the CSS
|
|
42
|
+
# @param parent_name [String] The name of the parent property (e.g. `text`) or nil
|
|
43
|
+
# @return [String] The resulting CSS
|
|
44
|
+
# @raise [Sass::SyntaxError] if the property uses invalid syntax
|
|
45
|
+
def _to_s(tabs, parent_name = nil)
|
|
46
|
+
if @options[:property_syntax] == :old && @prop_syntax == :new
|
|
47
|
+
raise Sass::SyntaxError.new("Illegal property syntax: can't use new syntax when :property_syntax => :old is set.")
|
|
48
|
+
elsif @options[:property_syntax] == :new && @prop_syntax == :old
|
|
49
|
+
raise Sass::SyntaxError.new("Illegal property syntax: can't use old syntax when :property_syntax => :new is set.")
|
|
50
|
+
elsif value[-1] == ?;
|
|
51
|
+
raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no \";\" required at end-of-line).")
|
|
52
|
+
elsif value.empty? && children.empty?
|
|
53
|
+
raise Sass::SyntaxError.new("Invalid property: #{declaration.dump} (no value).")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
real_name = name
|
|
57
|
+
real_name = "#{parent_name}-#{real_name}" if parent_name
|
|
58
|
+
|
|
59
|
+
join_string = case style
|
|
60
|
+
when :compact; ' '
|
|
61
|
+
when :compressed; ''
|
|
62
|
+
else "\n"
|
|
63
|
+
end
|
|
64
|
+
spaces = ' ' * (tabs - 1)
|
|
65
|
+
to_return = ''
|
|
66
|
+
if !value.empty?
|
|
67
|
+
to_return << "#{spaces}#{real_name}:#{style == :compressed ? '' : ' '}#{value};#{join_string}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
children.each do |kid|
|
|
71
|
+
next if kid.invisible?
|
|
72
|
+
to_return << kid.to_s(tabs, real_name) << join_string
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
(style == :compressed && parent_name) ? to_return : to_return[0...-1]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Runs any SassScript that may be embedded in the property.
|
|
79
|
+
#
|
|
80
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
|
81
|
+
# variable and mixin values
|
|
82
|
+
def perform!(environment)
|
|
83
|
+
@name = interpolate(@name, environment)
|
|
84
|
+
@value = @value.is_a?(String) ? interpolate(@value, environment) : @value.perform(environment).to_s
|
|
85
|
+
super
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Returns an error message if the given child node is invalid,
|
|
89
|
+
# and false otherwise.
|
|
90
|
+
#
|
|
91
|
+
# {PropNode} only allows other {PropNode}s and {CommentNode}s as children.
|
|
92
|
+
# @param child [Tree::Node] A potential child node
|
|
93
|
+
# @return [String] An error message if the child is invalid, or nil otherwise
|
|
94
|
+
def invalid_child?(child)
|
|
95
|
+
if !child.is_a?(PropNode) && !child.is_a?(CommentNode)
|
|
96
|
+
"Illegal nesting: Only properties may be nested beneath properties."
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def declaration
|
|
103
|
+
@prop_syntax == :new ? "#{name}: #{value}" : ":#{name} #{value}"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Sass
|
|
2
|
+
module Tree
|
|
3
|
+
# A static node that is the root node of the Sass document.
|
|
4
|
+
class RootNode < Node
|
|
5
|
+
# The Sass template from which this node was created
|
|
6
|
+
#
|
|
7
|
+
# @param template [String]
|
|
8
|
+
attr_reader :template
|
|
9
|
+
|
|
10
|
+
# @param template [String] The Sass template from which this node was created
|
|
11
|
+
def initialize(template)
|
|
12
|
+
super()
|
|
13
|
+
@template = template
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @see \{Node#to\_s}
|
|
17
|
+
def to_s(*args)
|
|
18
|
+
super
|
|
19
|
+
rescue Sass::SyntaxError => e
|
|
20
|
+
e.sass_template = @template
|
|
21
|
+
raise e
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @see \{Node#perform}
|
|
25
|
+
def perform(*args)
|
|
26
|
+
super
|
|
27
|
+
rescue Sass::SyntaxError => e
|
|
28
|
+
e.sass_template = @template
|
|
29
|
+
raise e
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
|
|
34
|
+
# Computes the CSS corresponding to this Sass tree.
|
|
35
|
+
#
|
|
36
|
+
# @param args [Array] ignored
|
|
37
|
+
# @return [String] The resulting CSS
|
|
38
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
|
39
|
+
# @see Sass::Tree
|
|
40
|
+
def _to_s(*args)
|
|
41
|
+
result = String.new
|
|
42
|
+
children.each do |child|
|
|
43
|
+
raise Sass::SyntaxError.new('Properties aren\'t allowed at the root of a document.',
|
|
44
|
+
:line => child.line) if child.is_a? PropNode
|
|
45
|
+
|
|
46
|
+
next if child.invisible?
|
|
47
|
+
child_str = child.to_s(1)
|
|
48
|
+
result << child_str + (style == :compressed ? '' : "\n")
|
|
49
|
+
end
|
|
50
|
+
result.rstrip!
|
|
51
|
+
return "" if result.empty?
|
|
52
|
+
return result + "\n"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|