Class: Sass::Tree::Visitors::Cssize
- Defined in:
- lib/sass/tree/visitors/cssize.rb
Overview
A visitor for converting a static Sass tree into a static CSS tree.
Defined Under Namespace
Class Method Summary collapse
-
.visit(root) ⇒ (Tree::Node, Sass::Util::SubsetMap)
The resulting tree of static nodes and the extensions defined for this tree.
Instance Method Summary collapse
-
#initialize ⇒ Cssize
constructor
protected
A new instance of Cssize.
-
#parent ⇒ Tree::Node
protected
Returns the immediate parent of the current node.
-
#visit(node)
protected
If an exception is raised, this adds proper metadata to the backtrace.
- #visit_atroot(node) protected
-
#visit_children(parent)
protected
Keeps track of the current parent node.
-
#visit_children_without_parent(node) ⇒ Array<Sass::Tree::Node>
protected
Like #visit_children, but doesn't set #parent.
-
#visit_directive(node)
protected
Bubbles a directive up through RuleNodes.
-
#visit_extend(node)
protected
Registers an extension in the
@extends
subset map. -
#visit_import(node)
protected
Modifies exception backtraces to include the imported file.
- #visit_keyframerule(node) protected
-
#visit_media(node)
protected
Bubbles the
@media
directive up through RuleNodes and merges it with other@media
directives. -
#visit_prop(node)
protected
Converts nested properties into flat properties and updates the indentation of the prop node based on the nesting level.
-
#visit_root(node) ⇒ (Tree::Node, Sass::Util::SubsetMap)
protected
Converts the entire document to CSS.
-
#visit_rule(node)
protected
Updates the indentation of the rule node based on the nesting level.
-
#visit_supports(node)
protected
Bubbles the
@supports
directive up through RuleNodes. -
#visit_trace(node)
protected
Asserts that all the traced children are valid in their new location.
-
#with_parent(parent) { ... } ⇒ Object
protected
Runs a block of code with the current parent node replaced with the given node.
Methods inherited from Base
Constructor Details
#initialize ⇒ Cssize (protected)
Returns a new instance of Cssize.
16 17 18 19 |
# File 'lib/sass/tree/visitors/cssize.rb', line 16
def initialize
@parents = []
@extends = Sass::Util::SubsetMap.new
end
|
Class Method Details
.visit(root) ⇒ (Tree::Node, Sass::Util::SubsetMap)
Returns The resulting tree of static nodes and the extensions defined for this tree.
6 |
# File 'lib/sass/tree/visitors/cssize.rb', line 6
def self.visit(root); super; end
|
Instance Method Details
#parent ⇒ Tree::Node (protected)
Returns the immediate parent of the current node.
12 13 14 |
# File 'lib/sass/tree/visitors/cssize.rb', line 12
def parent
@parents.last
end
|
#visit(node) (protected)
If an exception is raised, this adds proper metadata to the backtrace.
22 23 24 25 26 27 |
# File 'lib/sass/tree/visitors/cssize.rb', line 22
def visit(node)
super(node)
rescue Sass::SyntaxError => e
e.modify_backtrace(:filename => node.filename, :line => node.line)
raise e
end
|
#visit_atroot(node) (protected)
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/sass/tree/visitors/cssize.rb', line 157
def visit_atroot(node)
# If there aren't any more directives or rules that this @at-root needs to
# exclude, we can get rid of it and just evaluate the children.
if @parents.none? {|n| node.exclude_node?(n)}
results = visit_children_without_parent(node)
results.each {|c| c.tabs += node.tabs if bubblable?(c)}
if !results.empty? && bubblable?(results.last)
results.last.group_end = node.group_end
end
return results
end
# If this @at-root excludes the immediate parent, return it as-is so that it
# can be bubbled up by the parent node.
return Bubble.new(node) if node.exclude_node?(parent)
# Otherwise, duplicate the current parent and move it into the @at-root
# node. As above, returning an @at-root node signals to the parent directive
# that it should be bubbled upwards.
bubble(node)
end
|
#visit_children(parent) (protected)
Keeps track of the current parent node.
30 31 32 33 34 35 |
# File 'lib/sass/tree/visitors/cssize.rb', line 30
def visit_children(parent)
with_parent parent do
parent.children = visit_children_without_parent(parent)
parent
end
end
|
#visit_children_without_parent(node) ⇒ Array<Sass::Tree::Node> (protected)
Like #visit_children, but doesn't set #parent.
42 43 44 |
# File 'lib/sass/tree/visitors/cssize.rb', line 42
def visit_children_without_parent(node)
node.children.map {|c| visit(c)}.flatten
end
|
#visit_directive(node) (protected)
Bubbles a directive up through RuleNodes.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/sass/tree/visitors/cssize.rb', line 212
def visit_directive(node)
return node unless node.has_children
if parent.is_a?(Sass::Tree::RuleNode)
# @keyframes shouldn't include the rule nodes, so we manually create a
# bubble that doesn't have the parent's contents for them.
return node.normalized_name == '@keyframes' ? Bubble.new(node) : bubble(node)
end
yield
# Since we don't know if the mere presence of an unknown directive may be
# important, we should keep an empty version around even if all the contents
# are removed via @at-root. However, if the contents are just bubbled out,
# we don't need to do so.
directive_exists = node.children.any? do |child|
next true unless child.is_a?(Bubble)
next false unless child.node.is_a?(Sass::Tree::DirectiveNode)
child.node.resolved_value == node.resolved_value
end
# We know empty @keyframes directives do nothing.
if directive_exists || node.name == '@keyframes'
[]
else
empty_node = node.dup
empty_node.children = []
[empty_node]
end + debubble(node.children, node)
end
|
#visit_extend(node) (protected)
Registers an extension in the @extends
subset map.
114 115 116 117 118 |
# File 'lib/sass/tree/visitors/cssize.rb', line 114
def visit_extend(node)
parent.resolved_rules.populate_extends(@extends, node.resolved_selector, node,
@parents.select {|p| p.is_a?(Sass::Tree::DirectiveNode)})
[]
end
|
#visit_import(node) (protected)
Modifies exception backtraces to include the imported file.
121 122 123 124 125 126 127 |
# File 'lib/sass/tree/visitors/cssize.rb', line 121
def visit_import(node)
visit_children_without_parent(node)
rescue Sass::SyntaxError => e
e.modify_backtrace(:filename => node.children.first.filename)
e.add_backtrace(:filename => node.filename, :line => node.line)
raise e
end
|
#visit_keyframerule(node) (protected)
203 204 205 206 207 208 209 |
# File 'lib/sass/tree/visitors/cssize.rb', line 203
def visit_keyframerule(node)
return node unless node.has_children
yield
debubble(node.children, node)
end
|
#visit_media(node) (protected)
Bubbles the @media
directive up through RuleNodes
and merges it with other @media
directives.
244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/sass/tree/visitors/cssize.rb', line 244
def visit_media(node)
return bubble(node) if parent.is_a?(Sass::Tree::RuleNode)
return Bubble.new(node) if parent.is_a?(Sass::Tree::MediaNode)
yield
debubble(node.children, node) do |child|
next child unless child.is_a?(Sass::Tree::MediaNode)
# Copies of `node` can be bubbled, and we don't want to merge it with its
# own query.
next child if child.resolved_query == node.resolved_query
next child if child.resolved_query = child.resolved_query.merge(node.resolved_query)
end
end
|
#visit_prop(node) (protected)
Converts nested properties into flat properties and updates the indentation of the prop node based on the nesting level.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/sass/tree/visitors/cssize.rb', line 140
def visit_prop(node)
if parent.is_a?(Sass::Tree::PropNode)
node.resolved_name = "#{parent.resolved_name}-#{node.resolved_name}"
node.tabs = parent.tabs + (parent.resolved_value.empty? ? 0 : 1) if node.style == :nested
end
yield
result = node.children.dup
if !node.resolved_value.empty? || node.children.empty?
node.send(:check!)
result.unshift(node)
end
result
end
|
#visit_root(node) ⇒ (Tree::Node, Sass::Util::SubsetMap) (protected)
Converts the entire document to CSS.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/sass/tree/visitors/cssize.rb', line 63
def visit_root(node)
yield
if parent.nil?
imports_to_move = []
import_limit = nil
i = -1
node.children.reject! do |n|
i += 1
if import_limit
next false unless n.is_a?(Sass::Tree::CssImportNode)
imports_to_move << n
next true
end
if !n.is_a?(Sass::Tree::CommentNode) &&
!n.is_a?(Sass::Tree::CharsetNode) &&
!n.is_a?(Sass::Tree::CssImportNode)
import_limit = i
end
false
end
if import_limit
node.children = node.children[0...import_limit] + imports_to_move +
node.children[import_limit..-1]
end
end
return node, @extends
rescue Sass::SyntaxError => e
e.sass_template ||= node.template
raise e
end
|
#visit_rule(node) (protected)
Updates the indentation of the rule node based on the nesting level. The selectors were resolved in Perform.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/sass/tree/visitors/cssize.rb', line 184
def visit_rule(node)
yield
rules = node.children.select {|c| bubblable?(c)}
props = node.children.reject {|c| bubblable?(c) || c.invisible?}
unless props.empty?
node.children = props
rules.each {|r| r.tabs += 1} if node.style == :nested
rules.unshift(node)
end
rules = debubble(rules)
unless parent.is_a?(Sass::Tree::RuleNode) || rules.empty? || !bubblable?(rules.last)
rules.last.group_end = true
end
rules
end
|
#visit_supports(node) (protected)
Bubbles the @supports
directive up through RuleNodes.
260 261 262 263 264 265 266 267 |
# File 'lib/sass/tree/visitors/cssize.rb', line 260
def visit_supports(node)
return node unless node.has_children
return bubble(node) if parent.is_a?(Sass::Tree::RuleNode)
yield
debubble(node.children, node)
end
|
#visit_trace(node) (protected)
Asserts that all the traced children are valid in their new location.
130 131 132 133 134 135 136 |
# File 'lib/sass/tree/visitors/cssize.rb', line 130
def visit_trace(node)
visit_children_without_parent(node)
rescue Sass::SyntaxError => e
e.modify_backtrace(:mixin => node.name, :filename => node.filename, :line => node.line)
e.add_backtrace(:filename => node.filename, :line => node.line)
raise e
end
|
#with_parent(parent) { ... } ⇒ Object (protected)
Runs a block of code with the current parent node replaced with the given node.
52 53 54 55 56 57 |
# File 'lib/sass/tree/visitors/cssize.rb', line 52
def with_parent(parent)
@parents.push parent
yield
ensure
@parents.pop
end
|