| Class | Sass::Tree::RuleNode |
| In: |
lib/sass/tree/rule_node.rb
|
| Parent: | Node |
A static node reprenting a CSS rule.
@see Sass::Tree
| PARENT | = | '&' | The character used to include the parent selector |
| group_end | [RW] |
Whether or not this rule is the last rule in a nested group. This is only
set in a CSS tree.
@return [Boolean] |
| parsed_rules | [RW] |
The CSS selector for this rule, without any
unresolved interpolation but with parent references still intact.
It‘s only set once {Tree::Node#perform} has been called.
@return [Selector::CommaSequence] |
| resolved_rules | [RW] |
The CSS selector for this rule, without any
unresolved interpolation or parent references. It‘s only set once {Tree::Node#cssize} has been called.
@return [Selector::CommaSequence] |
| rule | [RW] |
The CSS selector for this rule, interspersed with
{Sass::Script::Node}s representing
`#{}`-interpolation. Any adjacent strings will be merged together.
@return [Array<String, Sass::Script::Node>] |
| tabs | [RW] |
How deep this rule is indented relative to a base-level rule. This is only
greater than 0 in the case that:
@return [Fixnum] |
@param rule [Array<String, Sass::Script::Node>]
The CSS rule. See \{#rule}
# File lib/sass/tree/rule_node.rb, line 55
55: def initialize(rule)
56: #p rule
57: merged = Haml::Util.merge_adjacent_strings(rule)
58: #p merged
59: @rule = Haml::Util.strip_string_array(merged)
60: #p @rule
61: @tabs = 0
62: super()
63: end
Compares the contents of two rules.
@param other [Object] The object to compare with @return [Boolean] Whether or not this node and the other object
are the same
# File lib/sass/tree/rule_node.rb, line 70
70: def ==(other)
71: self.class == other.class && rule == other.rule && super
72: end
@return [Boolean] Whether or not this rule is continued on the next line
# File lib/sass/tree/rule_node.rb, line 83
83: def continued?
84: last = @rule.last
85: last.is_a?(String) && last[-1] == ?,
86: end
Extends this Rule‘s selector with the given `extends`.
@see Node#do_extend
# File lib/sass/tree/rule_node.rb, line 111
111: def do_extend(extends)
112: node = dup
113: node.resolved_rules = resolved_rules.do_extend(extends)
114: node
115: end
@see Node#to_sass
# File lib/sass/tree/rule_node.rb, line 89
89: def to_sass(tabs, opts = {})
90: name = selector_to_sass(rule, opts)
91: name = "\\" + name if name[0] == ?:
92: name.gsub(/^/, ' ' * tabs) + children_to_src(tabs, opts, :sass)
93: end
@see Node#to_scss
# File lib/sass/tree/rule_node.rb, line 96
96: def to_scss(tabs, opts = {})
97: name = selector_to_scss(rule, tabs, opts)
98: res = name + children_to_src(tabs, opts, :scss)
99:
100: if children.last.is_a?(CommentNode) && children.last.silent
101: res.slice!(-3..-1)
102: res << "\n" << (' ' * tabs) << "}\n"
103: end
104:
105: res
106: end
Converts nested rules into a flat list of rules.
@param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
The extensions defined for this tree
@param parent [RuleNode, nil] The parent node of this node,
or nil if the parent isn't a {RuleNode}
# File lib/sass/tree/rule_node.rb, line 200
200: def _cssize(extends, parent)
201: node = super
202: rules = node.children.select {|c| c.is_a?(RuleNode)}
203: props = node.children.reject {|c| c.is_a?(RuleNode) || c.invisible?}
204:
205: unless props.empty?
206: node.children = props
207: rules.each {|r| r.tabs += 1} if style == :nested
208: rules.unshift(node)
209: end
210:
211: rules.last.group_end = true unless parent || rules.empty?
212:
213: rules
214: end
Computes the CSS for the rule.
@param tabs [Fixnum] The level of indentation for the CSS @return [String] The resulting CSS
# File lib/sass/tree/rule_node.rb, line 123
123: def _to_s(tabs)
124: tabs = tabs + self.tabs
125:
126: rule_separator = style == :compressed ? ',' : ', '
127: line_separator =
128: case style
129: when :nested, :expanded; "\n"
130: when :compressed; ""
131: else; " "
132: end
133: rule_indent = ' ' * (tabs - 1)
134: per_rule_indent, total_indent = [:nested, :expanded].include?(style) ? [rule_indent, ''] : ['', rule_indent]
135:
136: total_rule = total_indent + resolved_rules.members.
137: map {|seq| seq.to_a.join}.
138: join(rule_separator).split("\n").map do |line|
139: per_rule_indent + line.strip
140: end.join(line_separator)
141:
142: to_return = ''
143: old_spaces = ' ' * (tabs - 1)
144: spaces = ' ' * tabs
145: if style != :compressed
146: if @options[:debug_info]
147: to_return << debug_info_rule.to_s(tabs) << "\n"
148: elsif @options[:line_comments]
149: to_return << "#{old_spaces}/* line #{line}"
150:
151: if filename
152: relative_filename = if @options[:css_filename]
153: begin
154: Pathname.new(filename).relative_path_from(
155: Pathname.new(File.dirname(@options[:css_filename]))).to_s
156: rescue ArgumentError
157: nil
158: end
159: end
160: relative_filename ||= filename
161: to_return << ", #{relative_filename}"
162: end
163:
164: to_return << " */\n"
165: end
166: end
167:
168: if style == :compact
169: properties = children.map { |a| a.to_s(1) }.join(' ')
170: to_return << "#{total_rule} { #{properties} }#{"\n" if group_end}"
171: elsif style == :compressed
172: properties = children.map { |a| a.to_s(1) }.join(';')
173: to_return << "#{total_rule}{#{properties}}"
174: else
175: properties = children.map { |a| a.to_s(tabs + 1) }.join("\n")
176: end_props = (style == :expanded ? "\n" + old_spaces : ' ')
177: to_return << "#{total_rule} {\n#{properties}#{end_props}}#{"\n" if group_end}"
178: end
179:
180: to_return
181: end
Resolves parent references and nested selectors, and updates the indentation based on the parent‘s indentation.
@param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
The extensions defined for this tree
@param parent [RuleNode, nil] The parent node of this node,
or nil if the parent isn't a {RuleNode}
@raise [Sass::SyntaxError] if the rule has no parents but uses `&`
# File lib/sass/tree/rule_node.rb, line 224
224: def cssize!(extends, parent)
225: self.resolved_rules = @parsed_rules.resolve_parent_refs(parent && parent.resolved_rules)
226: super
227: end
A hash that will be associated with this rule in the CSS document if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled. This data is used by e.g. [the FireSass Firebug extension](addons.mozilla.org/en-US/firefox/addon/103988).
@return [{to_s => to_s}]
# File lib/sass/tree/rule_node.rb, line 246
246: def debug_info
247: {:filename => filename && ("file://" + URI.escape(File.expand_path(filename))),
248: :line => self.line}
249: end
Returns an error message if the given child node is invalid, and false otherwise.
{ExtendNode}s are valid within {RuleNode}s.
@param child [Tree::Node] A potential child node. @return [Boolean, String] Whether or not the child node is valid,
as well as the error message to display if it is invalid
# File lib/sass/tree/rule_node.rb, line 237
237: def invalid_child?(child)
238: super unless child.is_a?(ExtendNode)
239: end
Runs SassScript interpolation in the selector, and then parses the result into a {Sass::Selector::CommaSequence}.
@param environment [Sass::Environment] The lexical environment containing
variable and mixin values
# File lib/sass/tree/rule_node.rb, line 188
188: def perform!(environment)
189: @parsed_rules = Sass::SCSS::StaticParser.new(run_interp(@rule, environment), self.line).
190: parse_selector(self.filename)
191: super
192: end
# File lib/sass/tree/rule_node.rb, line 253
253: def debug_info_rule
254: node = DirectiveNode.new("@media -sass-debug-info")
255: debug_info.map {|k, v| [k.to_s, v.to_s]}.sort.each do |k, v|
256: rule = RuleNode.new([""])
257: rule.resolved_rules = Sass::Selector::CommaSequence.new(
258: [Sass::Selector::Sequence.new(
259: [Sass::Selector::SimpleSequence.new(
260: [Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)])
261: ])
262: ])
263: prop = PropNode.new([""], "", :new)
264: prop.resolved_name = "font-family"
265: prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
266: rule << prop
267: node << rule
268: end
269: node.options = @options.merge(:debug_info => false, :line_comments => false, :style => :compressed)
270: node
271: end