sass 3.1.0.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +11 -0
- data/CONTRIBUTING +3 -0
- data/EDGE_GEM_VERSION +1 -0
- data/MIT-LICENSE +20 -0
- data/README.md +201 -0
- data/REVISION +1 -0
- data/Rakefile +353 -0
- data/VERSION +1 -0
- data/VERSION_NAME +1 -0
- data/bin/css2sass +13 -0
- data/bin/sass +8 -0
- data/bin/sass-convert +7 -0
- data/extra/update_watch.rb +13 -0
- data/init.rb +18 -0
- data/lib/sass.rb +71 -0
- data/lib/sass/cache_store.rb +208 -0
- data/lib/sass/callbacks.rb +66 -0
- data/lib/sass/css.rb +294 -0
- data/lib/sass/engine.rb +792 -0
- data/lib/sass/environment.rb +143 -0
- data/lib/sass/error.rb +201 -0
- data/lib/sass/exec.rb +619 -0
- data/lib/sass/importers.rb +22 -0
- data/lib/sass/importers/base.rb +138 -0
- data/lib/sass/importers/filesystem.rb +121 -0
- data/lib/sass/less.rb +363 -0
- data/lib/sass/plugin.rb +126 -0
- data/lib/sass/plugin/compiler.rb +346 -0
- data/lib/sass/plugin/configuration.rb +123 -0
- data/lib/sass/plugin/generic.rb +15 -0
- data/lib/sass/plugin/merb.rb +48 -0
- data/lib/sass/plugin/rack.rb +47 -0
- data/lib/sass/plugin/rails.rb +41 -0
- data/lib/sass/plugin/staleness_checker.rb +145 -0
- data/lib/sass/railtie.rb +8 -0
- data/lib/sass/repl.rb +58 -0
- data/lib/sass/root.rb +7 -0
- data/lib/sass/script.rb +63 -0
- data/lib/sass/script/bool.rb +18 -0
- data/lib/sass/script/color.rb +490 -0
- data/lib/sass/script/css_lexer.rb +29 -0
- data/lib/sass/script/css_parser.rb +31 -0
- data/lib/sass/script/funcall.rb +78 -0
- data/lib/sass/script/functions.rb +852 -0
- data/lib/sass/script/interpolation.rb +70 -0
- data/lib/sass/script/lexer.rb +337 -0
- data/lib/sass/script/literal.rb +236 -0
- data/lib/sass/script/node.rb +101 -0
- data/lib/sass/script/number.rb +420 -0
- data/lib/sass/script/operation.rb +92 -0
- data/lib/sass/script/parser.rb +392 -0
- data/lib/sass/script/string.rb +67 -0
- data/lib/sass/script/string_interpolation.rb +93 -0
- data/lib/sass/script/unary_operation.rb +57 -0
- data/lib/sass/script/variable.rb +48 -0
- data/lib/sass/scss.rb +17 -0
- data/lib/sass/scss/css_parser.rb +51 -0
- data/lib/sass/scss/parser.rb +838 -0
- data/lib/sass/scss/rx.rb +126 -0
- data/lib/sass/scss/sass_parser.rb +11 -0
- data/lib/sass/scss/script_lexer.rb +15 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/scss/static_parser.rb +40 -0
- data/lib/sass/selector.rb +361 -0
- data/lib/sass/selector/abstract_sequence.rb +62 -0
- data/lib/sass/selector/comma_sequence.rb +82 -0
- data/lib/sass/selector/sequence.rb +236 -0
- data/lib/sass/selector/simple.rb +113 -0
- data/lib/sass/selector/simple_sequence.rb +135 -0
- data/lib/sass/shared.rb +78 -0
- data/lib/sass/tree/comment_node.rb +128 -0
- data/lib/sass/tree/debug_node.rb +36 -0
- data/lib/sass/tree/directive_node.rb +75 -0
- data/lib/sass/tree/extend_node.rb +65 -0
- data/lib/sass/tree/for_node.rb +67 -0
- data/lib/sass/tree/if_node.rb +81 -0
- data/lib/sass/tree/import_node.rb +124 -0
- data/lib/sass/tree/mixin_def_node.rb +60 -0
- data/lib/sass/tree/mixin_node.rb +123 -0
- data/lib/sass/tree/node.rb +490 -0
- data/lib/sass/tree/prop_node.rb +220 -0
- data/lib/sass/tree/root_node.rb +125 -0
- data/lib/sass/tree/rule_node.rb +273 -0
- data/lib/sass/tree/variable_node.rb +39 -0
- data/lib/sass/tree/warn_node.rb +42 -0
- data/lib/sass/tree/while_node.rb +48 -0
- data/lib/sass/util.rb +687 -0
- data/lib/sass/util/subset_map.rb +101 -0
- data/lib/sass/version.rb +109 -0
- data/rails/init.rb +1 -0
- data/test/sass/cache_test.rb +74 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +1210 -0
- data/test/sass/css2sass_test.rb +364 -0
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +2273 -0
- data/test/sass/extend_test.rb +1348 -0
- data/test/sass/functions_test.rb +565 -0
- data/test/sass/importer_test.rb +104 -0
- data/test/sass/less_conversion_test.rb +632 -0
- data/test/sass/mock_importer.rb +49 -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 +430 -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 +86 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/import.css +31 -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/options.css +1 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/scss_import.css +31 -0
- data/test/sass/results/scss_importee.css +2 -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/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +254 -0
- data/test/sass/script_test.rb +459 -0
- data/test/sass/scss/css_test.rb +897 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +1088 -0
- data/test/sass/scss/test_helper.rb +37 -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/bork4.sass +2 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +305 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/import.sass +12 -0
- data/test/sass/templates/importee.less +2 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixin_bork.sass +5 -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/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 +25 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/scss_import.scss +11 -0
- data/test/sass/templates/scss_importee.scss +1 -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/sass/templates/warn.sass +3 -0
- data/test/sass/templates/warn_imported.sass +4 -0
- data/test/sass/test_helper.rb +8 -0
- data/test/sass/util/subset_map_test.rb +91 -0
- data/test/sass/util_test.rb +275 -0
- data/test/test_helper.rb +64 -0
- 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 +297 -0
@@ -0,0 +1,490 @@
|
|
1
|
+
module Sass
|
2
|
+
# A namespace for nodes in the Sass parse tree.
|
3
|
+
#
|
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,
|
8
|
+
# in addition to nodes for CSS rules and properties.
|
9
|
+
# Nodes that only appear in this state are called **dynamic nodes**.
|
10
|
+
#
|
11
|
+
# {Tree::Node#perform} returns a static Sass tree, which is different.
|
12
|
+
# It still has nodes for CSS rules and properties
|
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.
|
23
|
+
#
|
24
|
+
# Finally, {Tree::Node#to_s} can be called on a static CSS tree
|
25
|
+
# to get the actual CSS code as a string.
|
26
|
+
module Tree
|
27
|
+
# The abstract superclass of all parse-tree nodes.
|
28
|
+
class Node
|
29
|
+
include Enumerable
|
30
|
+
|
31
|
+
# The child nodes of this node.
|
32
|
+
#
|
33
|
+
# @return [Array<Tree::Node>]
|
34
|
+
attr_accessor :children
|
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
|
+
|
43
|
+
# The line of the document on which this node appeared.
|
44
|
+
#
|
45
|
+
# @return [Fixnum]
|
46
|
+
attr_accessor :line
|
47
|
+
|
48
|
+
# The name of the document on which this node appeared.
|
49
|
+
#
|
50
|
+
# @return [String]
|
51
|
+
attr_writer :filename
|
52
|
+
|
53
|
+
# The options hash for the node.
|
54
|
+
# See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
|
55
|
+
#
|
56
|
+
# @return [{Symbol => Object}]
|
57
|
+
attr_reader :options
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@children = []
|
61
|
+
end
|
62
|
+
|
63
|
+
# Sets the options hash for the node and all its children.
|
64
|
+
#
|
65
|
+
# @param options [{Symbol => Object}] The options
|
66
|
+
# @see #options
|
67
|
+
def options=(options)
|
68
|
+
children.each {|c| c.options = options}
|
69
|
+
@options = options
|
70
|
+
end
|
71
|
+
|
72
|
+
# @private
|
73
|
+
def children=(children)
|
74
|
+
self.has_children ||= !children.empty?
|
75
|
+
@children = children
|
76
|
+
end
|
77
|
+
|
78
|
+
# The name of the document on which this node appeared.
|
79
|
+
#
|
80
|
+
# @return [String]
|
81
|
+
def filename
|
82
|
+
@filename || (@options && @options[:filename])
|
83
|
+
end
|
84
|
+
|
85
|
+
# Appends a child to the node.
|
86
|
+
#
|
87
|
+
# @param child [Tree::Node, Array<Tree::Node>] The child node or nodes
|
88
|
+
# @raise [Sass::SyntaxError] if `child` is invalid
|
89
|
+
# @see #invalid_child?
|
90
|
+
def <<(child)
|
91
|
+
return if child.nil?
|
92
|
+
if child.is_a?(Array)
|
93
|
+
child.each {|c| self << c}
|
94
|
+
else
|
95
|
+
check_child! child
|
96
|
+
self.has_children = true
|
97
|
+
@children << child
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Raises an error if the given child node is invalid.
|
102
|
+
#
|
103
|
+
# @param child [Tree::Node] The child node
|
104
|
+
# @raise [Sass::SyntaxError] if `child` is invalid
|
105
|
+
# @see #invalid_child?
|
106
|
+
def check_child!(child)
|
107
|
+
if msg = invalid_child?(child)
|
108
|
+
raise Sass::SyntaxError.new(msg, :line => child.line)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Compares this node and another object (only other {Tree::Node}s will be equal).
|
113
|
+
# This does a structural comparison;
|
114
|
+
# if the contents of the nodes and all the child nodes are equivalent,
|
115
|
+
# then the nodes are as well.
|
116
|
+
#
|
117
|
+
# Only static nodes need to override this.
|
118
|
+
#
|
119
|
+
# @param other [Object] The object to compare with
|
120
|
+
# @return [Boolean] Whether or not this node and the other object
|
121
|
+
# are the same
|
122
|
+
# @see Sass::Tree
|
123
|
+
def ==(other)
|
124
|
+
self.class == other.class && other.children == children
|
125
|
+
end
|
126
|
+
|
127
|
+
# True if \{#to\_s} will return `nil`;
|
128
|
+
# that is, if the node shouldn't be rendered.
|
129
|
+
# Should only be called in a static tree.
|
130
|
+
#
|
131
|
+
# @return [Boolean]
|
132
|
+
def invisible?; false; end
|
133
|
+
|
134
|
+
# The output style. See {file:SASS_REFERENCE.md#sass_options the Sass options documentation}.
|
135
|
+
#
|
136
|
+
# @return [Symbol]
|
137
|
+
def style
|
138
|
+
@options[:style]
|
139
|
+
end
|
140
|
+
|
141
|
+
# Computes the CSS corresponding to this static CSS tree.
|
142
|
+
#
|
143
|
+
# \{#to_s} shouldn't be overridden directly; instead, override \{#\_to\_s}.
|
144
|
+
# Only static-node subclasses need to implement \{#to\_s}.
|
145
|
+
#
|
146
|
+
# This may return `nil`, but it will only do so if \{#invisible?} is true.
|
147
|
+
#
|
148
|
+
# @param args [Array] Passed on to \{#\_to\_s}
|
149
|
+
# @return [String, nil] The resulting CSS
|
150
|
+
# @see Sass::Tree
|
151
|
+
def to_s(*args)
|
152
|
+
_to_s(*args)
|
153
|
+
rescue Sass::SyntaxError => e
|
154
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
155
|
+
raise e
|
156
|
+
end
|
157
|
+
|
158
|
+
# Converts a static CSS tree (e.g. the output of \{#cssize})
|
159
|
+
# into another static CSS tree,
|
160
|
+
# with the given extensions applied to all relevant {RuleNode}s.
|
161
|
+
#
|
162
|
+
# @todo Link this to the reference documentation on `@extend`
|
163
|
+
# when such a thing exists.
|
164
|
+
#
|
165
|
+
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
166
|
+
# The extensions to perform on this tree
|
167
|
+
# @return [Tree::Node] The resulting tree of static CSS nodes.
|
168
|
+
# @raise [Sass::SyntaxError] Only if there's a programmer error
|
169
|
+
# and this is not a static CSS tree
|
170
|
+
def do_extend(extends)
|
171
|
+
node = dup
|
172
|
+
node.children = children.map {|c| c.do_extend(extends)}
|
173
|
+
node
|
174
|
+
rescue Sass::SyntaxError => e
|
175
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
176
|
+
raise e
|
177
|
+
end
|
178
|
+
|
179
|
+
# Converts a static Sass tree (e.g. the output of \{#perform})
|
180
|
+
# into a static CSS tree.
|
181
|
+
#
|
182
|
+
# \{#cssize} shouldn't be overridden directly;
|
183
|
+
# instead, override \{#\_cssize} or \{#cssize!}.
|
184
|
+
#
|
185
|
+
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
186
|
+
# The extensions defined for this tree
|
187
|
+
# @param parent [Node, nil] The parent node of this node.
|
188
|
+
# This should only be non-nil if the parent is the same class as this node
|
189
|
+
# @return [Tree::Node] The resulting tree of static nodes
|
190
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
191
|
+
# @see Sass::Tree
|
192
|
+
def cssize(extends, parent = nil)
|
193
|
+
_cssize(extends, (parent if parent.class == self.class))
|
194
|
+
rescue Sass::SyntaxError => e
|
195
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
196
|
+
raise e
|
197
|
+
end
|
198
|
+
|
199
|
+
# Converts a dynamic tree into a static Sass tree.
|
200
|
+
# That is, runs the dynamic Sass code:
|
201
|
+
# mixins, variables, control directives, and so forth.
|
202
|
+
# This doesn't modify this node or any of its children.
|
203
|
+
#
|
204
|
+
# \{#perform} shouldn't be overridden directly;
|
205
|
+
# instead, override \{#\_perform} or \{#perform!}.
|
206
|
+
#
|
207
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
208
|
+
# variable and mixin values
|
209
|
+
# @return [Tree::Node] The resulting tree of static nodes
|
210
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
211
|
+
# @see Sass::Tree
|
212
|
+
def perform(environment)
|
213
|
+
_perform(environment)
|
214
|
+
rescue Sass::SyntaxError => e
|
215
|
+
e.modify_backtrace(:filename => filename, :line => line)
|
216
|
+
raise e
|
217
|
+
end
|
218
|
+
|
219
|
+
# Iterates through each node in the tree rooted at this node
|
220
|
+
# in a pre-order walk.
|
221
|
+
#
|
222
|
+
# @yield node
|
223
|
+
# @yieldparam node [Node] a node in the tree
|
224
|
+
def each(&block)
|
225
|
+
yield self
|
226
|
+
children.each {|c| c.each(&block)}
|
227
|
+
end
|
228
|
+
|
229
|
+
# Converts a node to Sass code that will generate it.
|
230
|
+
#
|
231
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the Sass code
|
232
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
233
|
+
# @return [String] The Sass code corresponding to the node
|
234
|
+
def to_sass(tabs = 0, opts = {})
|
235
|
+
to_src(tabs, opts, :sass)
|
236
|
+
end
|
237
|
+
|
238
|
+
# Converts a node to SCSS code that will generate it.
|
239
|
+
#
|
240
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
|
241
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
242
|
+
# @return [String] The Sass code corresponding to the node
|
243
|
+
def to_scss(tabs = 0, opts = {})
|
244
|
+
to_src(tabs, opts, :scss)
|
245
|
+
end
|
246
|
+
|
247
|
+
# Names of options that are saved when the node is serialized and cached.
|
248
|
+
SAVED_OPTIONS = [:importer]
|
249
|
+
|
250
|
+
# Ensures that only {SAVED_OPTIONS} get saved.
|
251
|
+
def _around_dump
|
252
|
+
old_options = @options
|
253
|
+
old_children = @children
|
254
|
+
@options = {}
|
255
|
+
SAVED_OPTIONS.each do |opt|
|
256
|
+
@options[opt] = old_options[opt]
|
257
|
+
end
|
258
|
+
@options = Sass::Util.dump(@options)
|
259
|
+
@children = Sass::Util.dump(@children)
|
260
|
+
yield
|
261
|
+
ensure
|
262
|
+
@options = old_options
|
263
|
+
@children = old_children
|
264
|
+
end
|
265
|
+
|
266
|
+
# Ensures that only {SAVED_OPTIONS} get saved.
|
267
|
+
def _after_load
|
268
|
+
@options = Sass::Util.load(@options)
|
269
|
+
@children = Sass::Util.load(@children)
|
270
|
+
end
|
271
|
+
|
272
|
+
protected
|
273
|
+
|
274
|
+
# Computes the CSS corresponding to this particular Sass node.
|
275
|
+
#
|
276
|
+
# This method should never raise {Sass::SyntaxError}s.
|
277
|
+
# Such errors will not be properly annotated with Sass backtrace information.
|
278
|
+
# All error conditions should be checked in earlier transformations,
|
279
|
+
# such as \{#cssize} and \{#perform}.
|
280
|
+
#
|
281
|
+
# @param args [Array] ignored
|
282
|
+
# @return [String, nil] The resulting CSS
|
283
|
+
# @see #to_s
|
284
|
+
# @see Sass::Tree
|
285
|
+
def _to_s
|
286
|
+
Sass::Util.abstract(self)
|
287
|
+
end
|
288
|
+
|
289
|
+
# Converts this static Sass node into a static CSS node,
|
290
|
+
# returning the new node.
|
291
|
+
# This doesn't modify this node or any of its children.
|
292
|
+
#
|
293
|
+
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
294
|
+
# The extensions defined for this tree
|
295
|
+
# @param parent [Node, nil] The parent node of this node.
|
296
|
+
# This should only be non-nil if the parent is the same class as this node
|
297
|
+
# @return [Tree::Node, Array<Tree::Node>] The resulting static CSS nodes
|
298
|
+
# @raise [Sass::SyntaxError] if some element of the tree is invalid
|
299
|
+
# @see #cssize
|
300
|
+
# @see Sass::Tree
|
301
|
+
def _cssize(extends, parent)
|
302
|
+
node = dup
|
303
|
+
node.cssize!(extends, parent)
|
304
|
+
node
|
305
|
+
end
|
306
|
+
|
307
|
+
# Destructively converts this static Sass node into a static CSS node.
|
308
|
+
# This *does* modify this node,
|
309
|
+
# but will be run non-destructively by \{#\_cssize\}.
|
310
|
+
#
|
311
|
+
# @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
312
|
+
# The extensions defined for this tree
|
313
|
+
# @param parent [Node, nil] The parent node of this node.
|
314
|
+
# This should only be non-nil if the parent is the same class as this node
|
315
|
+
# @see #cssize
|
316
|
+
def cssize!(extends, parent)
|
317
|
+
self.children = children.map {|c| c.cssize(extends, self)}.flatten
|
318
|
+
end
|
319
|
+
|
320
|
+
# Runs any dynamic Sass code in this particular node.
|
321
|
+
# This doesn't modify this node or any of its children.
|
322
|
+
#
|
323
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
324
|
+
# variable and mixin values
|
325
|
+
# @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
|
326
|
+
# @see #perform
|
327
|
+
# @see Sass::Tree
|
328
|
+
def _perform(environment)
|
329
|
+
node = dup
|
330
|
+
node.perform!(environment)
|
331
|
+
node
|
332
|
+
end
|
333
|
+
|
334
|
+
# Destructively runs dynamic Sass code in this particular node.
|
335
|
+
# This *does* modify this node,
|
336
|
+
# but will be run non-destructively by \{#\_perform\}.
|
337
|
+
#
|
338
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
339
|
+
# variable and mixin values
|
340
|
+
# @see #perform
|
341
|
+
def perform!(environment)
|
342
|
+
self.children = perform_children(Environment.new(environment))
|
343
|
+
end
|
344
|
+
|
345
|
+
# Non-destructively runs \{#perform} on all children of the current node.
|
346
|
+
#
|
347
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
348
|
+
# variable and mixin values
|
349
|
+
# @return [Array<Tree::Node>] The resulting static nodes
|
350
|
+
def perform_children(environment)
|
351
|
+
children.map {|c| c.perform(environment)}.flatten
|
352
|
+
end
|
353
|
+
|
354
|
+
# Replaces SassScript in a chunk of text
|
355
|
+
# with the resulting value.
|
356
|
+
#
|
357
|
+
# @param text [Array<String, Sass::Script::Node>] The text to interpolate
|
358
|
+
# @param environment [Sass::Environment] The lexical environment containing
|
359
|
+
# variable and mixin values
|
360
|
+
# @return [String] The interpolated text
|
361
|
+
def run_interp(text, environment)
|
362
|
+
text.map do |r|
|
363
|
+
next r if r.is_a?(String)
|
364
|
+
val = r.perform(environment)
|
365
|
+
# Interpolated strings should never render with quotes
|
366
|
+
next val.value if val.is_a?(Sass::Script::String)
|
367
|
+
val.to_s
|
368
|
+
end.join.strip
|
369
|
+
end
|
370
|
+
|
371
|
+
# @see Sass::Shared.balance
|
372
|
+
# @raise [Sass::SyntaxError] if the brackets aren't balanced
|
373
|
+
def balance(*args)
|
374
|
+
res = Sass::Shared.balance(*args)
|
375
|
+
return res if res
|
376
|
+
raise Sass::SyntaxError.new("Unbalanced brackets.", :line => line)
|
377
|
+
end
|
378
|
+
|
379
|
+
# Returns an error message if the given child node is invalid,
|
380
|
+
# and false otherwise.
|
381
|
+
#
|
382
|
+
# By default, all child nodes except those only allowed under specific nodes
|
383
|
+
# ({Tree::MixinDefNode}, {Tree::ImportNode}, {Tree::ExtendNode}) are valid.
|
384
|
+
# This is expected to be overriden by subclasses
|
385
|
+
# for which some children are invalid.
|
386
|
+
#
|
387
|
+
# @param child [Tree::Node] A potential child node
|
388
|
+
# @return [Boolean, String] Whether or not the child node is valid,
|
389
|
+
# as well as the error message to display if it is invalid
|
390
|
+
def invalid_child?(child)
|
391
|
+
case child
|
392
|
+
when Tree::MixinDefNode
|
393
|
+
"Mixins may only be defined at the root of a document."
|
394
|
+
when Tree::ImportNode
|
395
|
+
"Import directives may only be used at the root of a document."
|
396
|
+
when Tree::ExtendNode
|
397
|
+
"Extend directives may only be used within rules."
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
# Converts a node to Sass or SCSS code that will generate it.
|
402
|
+
#
|
403
|
+
# This method is called by the default \{#to\_sass} and \{#to\_scss} methods,
|
404
|
+
# so that the same code can be used for both with minor variations.
|
405
|
+
#
|
406
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
|
407
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
408
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
409
|
+
# @return [String] The Sass or SCSS code corresponding to the node
|
410
|
+
def to_src(tabs, opts, fmt)
|
411
|
+
Sass::Util.abstract(self)
|
412
|
+
end
|
413
|
+
|
414
|
+
# Converts the children of this node to a Sass or SCSS string.
|
415
|
+
# This will return the trailing newline for the previous line,
|
416
|
+
# including brackets if this is SCSS.
|
417
|
+
#
|
418
|
+
# @param tabs [Fixnum] The amount of tabulation to use for the Sass code
|
419
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
420
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
421
|
+
# @return [String] The Sass or SCSS code corresponding to the children
|
422
|
+
def children_to_src(tabs, opts, fmt)
|
423
|
+
return fmt == :sass ? "\n" : " {}\n" if children.empty?
|
424
|
+
|
425
|
+
(fmt == :sass ? "\n" : " {\n") +
|
426
|
+
children.map {|c| c.send("to_#{fmt}", tabs + 1, opts)}.join.rstrip +
|
427
|
+
(fmt == :sass ? "\n" : " }\n")
|
428
|
+
end
|
429
|
+
|
430
|
+
# Converts a selector to a Sass or SCSS string.
|
431
|
+
#
|
432
|
+
# @param sel [Array<String, Sass::Script::Node>] The selector to convert
|
433
|
+
# @param tabs [Fixnum] The indentation of the selector
|
434
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
435
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
436
|
+
# @return [String] The Sass or SCSS code corresponding to the selector
|
437
|
+
def selector_to_src(sel, tabs, opts, fmt)
|
438
|
+
fmt == :sass ? selector_to_sass(sel, opts) : selector_to_scss(sel, tabs, opts)
|
439
|
+
end
|
440
|
+
|
441
|
+
# Converts a selector to a Sass string.
|
442
|
+
#
|
443
|
+
# @param sel [Array<String, Sass::Script::Node>] The selector to convert
|
444
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
445
|
+
# @return [String] The Sass code corresponding to the selector
|
446
|
+
def selector_to_sass(sel, opts)
|
447
|
+
sel.map do |r|
|
448
|
+
if r.is_a?(String)
|
449
|
+
r.gsub(/(,[ \t]*)?\n\s*/) {$1 ? $1 + "\n" : " "}
|
450
|
+
else
|
451
|
+
"\#{#{r.to_sass(opts)}}"
|
452
|
+
end
|
453
|
+
end.join
|
454
|
+
end
|
455
|
+
|
456
|
+
# Converts a selector to a SCSS string.
|
457
|
+
#
|
458
|
+
# @param sel [Array<String, Sass::Script::Node>] The selector to convert
|
459
|
+
# @param tabs [Fixnum] The indentation of the selector
|
460
|
+
# @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
|
461
|
+
# @return [String] The SCSS code corresponding to the selector
|
462
|
+
def selector_to_scss(sel, tabs, opts)
|
463
|
+
sel.map {|r| r.is_a?(String) ? r : "\#{#{r.to_sass(opts)}}"}.
|
464
|
+
join.gsub(/^[ \t]*/, ' ' * tabs)
|
465
|
+
end
|
466
|
+
|
467
|
+
# Convert any underscores in a string into hyphens,
|
468
|
+
# but only if the `:dasherize` option is set.
|
469
|
+
#
|
470
|
+
# @param s [String] The string to convert
|
471
|
+
# @param opts [{Symbol => Object}] The options hash
|
472
|
+
# @return [String] The converted string
|
473
|
+
def dasherize(s, opts)
|
474
|
+
if opts[:dasherize]
|
475
|
+
s.gsub('_', '-')
|
476
|
+
else
|
477
|
+
s
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
# Returns a semicolon if this is SCSS, or an empty string if this is Sass.
|
482
|
+
#
|
483
|
+
# @param fmt [Symbol] `:sass` or `:scss`
|
484
|
+
# @return [String] A semicolon or the empty string
|
485
|
+
def semi(fmt)
|
486
|
+
fmt == :sass ? "" : ";"
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|