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
Classes: Extend
Constant Summary collapse
- MERGEABLE_DIRECTIVES =
[Sass::Tree::MediaNode]
Constants inherited from Base
Instance Attribute Summary collapse
-
#parent ⇒ Tree::Node
readonly
protected
Returns the immediate parent of the current node.
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.
-
#visit(node)
protected
If an exception is raised, this adds proper metadata to the backtrace.
-
#visit_children(parent)
protected
Keeps track of the current parent node.
-
#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_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
In Ruby 1.8, ensures that there's only one
@charset
directive and that it's at the top of the document. -
#visit_rule(node)
protected
Resolves parent references and nested selectors, and 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.
14 15 16 17 |
# File 'lib/sass/tree/visitors/cssize.rb', line 14
def initialize
@parent_directives = []
@extends = Sass::Util::SubsetMap.new
end
|
Instance Attribute Details
#parent ⇒ Tree::Node (readonly, protected)
Returns the immediate parent of the current node.
12 13 14 |
# File 'lib/sass/tree/visitors/cssize.rb', line 12
def parent
@parent
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
#visit(node) (protected)
If an exception is raised, this adds proper metadata to the backtrace.
20 21 22 23 24 25 |
# File 'lib/sass/tree/visitors/cssize.rb', line 20
def visit(node)
super(node)
rescue Sass::SyntaxError => e
e.modify_backtrace(:filename => node.filename, :line => node.line)
raise e
end
|
#visit_children(parent) (protected)
Keeps track of the current parent node.
28 29 30 31 32 33 |
# File 'lib/sass/tree/visitors/cssize.rb', line 28
def visit_children(parent)
with_parent parent do
parent.children = super.flatten
parent
end
end
|
#visit_extend(node) (protected)
Registers an extension in the @extends
subset map.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/sass/tree/visitors/cssize.rb', line 113
def visit_extend(node)
node.resolved_selector.members.each do |seq|
if seq.members.size > 1
raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: can't extend nested selectors")
end
sseq = seq.members.first
if !sseq.is_a?(Sass::Selector::SimpleSequence)
raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: invalid selector")
elsif sseq.members.any? {|ss| ss.is_a?(Sass::Selector::Parent)}
raise Sass::SyntaxError.new("Can't extend #{seq.to_a.join}: can't extend parent selectors")
end
sel = sseq.members
parent.resolved_rules.members.each do |member|
if !member.members.last.is_a?(Sass::Selector::SimpleSequence)
raise Sass::SyntaxError.new("#{member} can't extend: invalid selector")
end
@extends[sel] = Extend.new(member, sel, node, @parent_directives.dup, :not_found)
end
end
[]
end
|
#visit_import(node) (protected)
Modifies exception backtraces to include the imported file.
140 141 142 143 144 145 146 147 |
# File 'lib/sass/tree/visitors/cssize.rb', line 140
def visit_import(node)
# Don't use #visit_children to avoid adding the import node to the list of parents.
node.children.map {|c| visit(c)}.flatten
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_media(node) (protected)
Bubbles the @media
directive up through RuleNodes
and merges it with other @media
directives.
151 152 153 154 155 156 157 |
# File 'lib/sass/tree/visitors/cssize.rb', line 151
def visit_media(node)
yield unless bubble(node)
media = node.children.select {|c| c.is_a?(Sass::Tree::MediaNode)}
node.children.reject! {|c| c.is_a?(Sass::Tree::MediaNode)}
media = media.select {|n| n.resolved_query = n.resolved_query.merge(node.resolved_query)}
(node.children.empty? ? [] : [node]) + media
end
|
#visit_prop(node) (protected)
Converts nested properties into flat properties and updates the indentation of the prop node based on the nesting level.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/sass/tree/visitors/cssize.rb', line 177
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)
In Ruby 1.8, ensures that there's only one @charset
directive
and that it's at the top of the document.
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 |
# File 'lib/sass/tree/visitors/cssize.rb', line 64
def visit_root(node)
yield
if parent.nil?
# In Ruby 1.9 we can make all @charset nodes invisible
# and infer the final @charset from the encoding of the final string.
if Sass::Util.ruby1_8?
charset = node.children.find {|c| c.is_a?(Sass::Tree::CharsetNode)}
node.children.reject! {|c| c.is_a?(Sass::Tree::CharsetNode)}
node.children.unshift charset if charset
end
imports = Sass::Util.extract!(node.children) do |c|
c.is_a?(Sass::Tree::DirectiveNode) && !c.is_a?(Sass::Tree::MediaNode) &&
c.resolved_value =~ /^@import /i
end
charset_and_index = Sass::Util.ruby1_8? &&
node.children.each_with_index.find {|c, _| c.is_a?(Sass::Tree::CharsetNode)}
if charset_and_index
index = charset_and_index.last
node.children = node.children[0..index] + imports + node.children[index+1..-1]
else
node.children = imports + node.children
end
end
return node, @extends
rescue Sass::SyntaxError => e
e.sass_template ||= node.template
raise e
end
|
#visit_rule(node) (protected)
Resolves parent references and nested selectors, and updates the indentation of the rule node based on the nesting level.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/sass/tree/visitors/cssize.rb', line 196
def visit_rule(node)
parent_resolved_rules = parent.is_a?(Sass::Tree::RuleNode) ? parent.resolved_rules : nil
# It's possible for resolved_rules to be set if we've duplicated this node during @media bubbling
node.resolved_rules ||= node.parsed_rules.resolve_parent_refs(parent_resolved_rules)
yield
rules = node.children.select {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles?}
props = node.children.reject {|c| c.is_a?(Sass::Tree::RuleNode) || c.bubbles? || c.invisible?}
unless props.empty?
node.children = props
rules.each {|r| r.tabs += 1} if node.style == :nested
rules.unshift(node)
end
rules.last.group_end = true unless parent.is_a?(Sass::Tree::RuleNode) || rules.empty?
rules
end
|
#visit_supports(node) (protected)
Bubbles the @supports
directive up through RuleNodes.
160 161 162 163 |
# File 'lib/sass/tree/visitors/cssize.rb', line 160
def visit_supports(node)
yield unless bubble(node)
node
end
|
#visit_trace(node) (protected)
Asserts that all the traced children are valid in their new location.
166 167 168 169 170 171 172 173 |
# File 'lib/sass/tree/visitors/cssize.rb', line 166
def visit_trace(node)
# Don't use #visit_children to avoid adding the trace node to the list of parents.
node.children.map {|c| visit(c)}.flatten
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.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/sass/tree/visitors/cssize.rb', line 43
def with_parent(parent)
if parent.is_a?(Sass::Tree::DirectiveNode)
if MERGEABLE_DIRECTIVES.any? {|klass| parent.is_a?(klass)}
old_parent_directive = @parent_directives.pop
end
@parent_directives.push parent
end
old_parent, @parent = @parent, parent
yield
ensure
@parent_directives.pop if parent.is_a?(Sass::Tree::DirectiveNode)
@parent_directives.push old_parent_directive if old_parent_directive
@parent = old_parent
end
|