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