Class: Sass::Tree::RuleNode

Inherits:
Node show all
Defined in:
lib/sass/tree/rule_node.rb,
lib/sass/css.rb

Overview

A static node reprenting a CSS rule.

See Also:

Instance Attribute Summary collapse

Attributes inherited from Node

#children, #filename, #line, #options

Instance Method Summary collapse

Methods inherited from Node

#<<, #_perform, #balance, #cssize, #interpolate, #invalid_child?, #invisible?, #last, #perform, #perform_children, #render, #style, #to_s

Constructor Details

#initialize(rule) ⇒ RuleNode

Returns a new instance of RuleNode.

Parameters:

  • rule (String)

    The first CSS rule. See #rules



87
88
89
90
91
# File 'lib/sass/tree/rule_node.rb', line 87

def initialize(rule)
  @rules = [rule]
  @tabs = 0
  super()
end

Instance Attribute Details

#group_endBoolean

Whether or not this rule is the last rule in a nested group. This is only set in a CSS tree.

Returns:

  • (Boolean)


84
85
86
# File 'lib/sass/tree/rule_node.rb', line 84

def group_end
  @group_end
end

#parsed_rulesArray<Array<Array<String|Symbol>>>

The CSS selectors for this rule, parsed for commas and parent-references. It's only set once Node#perform has been called.

It's an array of arrays of arrays. The first level of arrays represents distinct lines in the Sass file; the second level represents comma-separated selectors; the third represents structure within those selectors, currently only parent-refs (represented by :parent). For example,

&.foo, bar, baz,
bip, &.bop, bup

would be

[[[:parent, ".foo"], ["bar"], ["baz"]],
 [["bip"], [:parent, ".bop"], ["bup"]]]

Returns:

  • (Array<Array<Array<String|Symbol>>>)


47
48
49
# File 'lib/sass/tree/rule_node.rb', line 47

def parsed_rules
  @parsed_rules
end

#resolved_rulesArray<Array<String>>

The CSS selectors for this rule, with all nesting and parent references resolved. It's only set once Node#cssize has been called.

The first level of arrays represents distinct lines in the Sass file; the second level represents comma-separated selectors. For example,

foo bar, baz,
bang, bip bop, blip

would be

[["foo bar", "baz"],
 ["bang", "bip bop", "blip"]]

Returns:

  • (Array<Array<String>>)


66
67
68
# File 'lib/sass/tree/rule_node.rb', line 66

def resolved_rules
  @resolved_rules
end

#rulesArray<String>

The CSS selectors for this rule. Each string is a selector line, and the lines are meant to be separated by commas. For example,

foo, bar, baz,
bip, bop, bup

would be

["foo, bar, baz",
 "bip, bop, bup"]

Returns:

  • (Array<String>)


25
26
27
# File 'lib/sass/tree/rule_node.rb', line 25

def rules
  @rules
end

#tabsFixnum

How deep this rule is indented relative to a base-level rule. This is only greater than 0 in the case that:

  • This node is in a CSS tree
  • The style is :nested
  • This is a child rule of another rule
  • The parent rule has properties, and thus will be rendered

Returns:

  • (Fixnum)


78
79
80
# File 'lib/sass/tree/rule_node.rb', line 78

def tabs
  @tabs
end

Instance Method Details

#==(other) ⇒ Boolean

Compares the contents of two rules.

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)

    Whether or not this node and the other object are the same



98
99
100
# File 'lib/sass/tree/rule_node.rb', line 98

def ==(other)
  self.class == other.class && rules == other.rules && super
end

#_cssize(parent) (protected)

Converts nested rules into a flat list of rules.

Parameters:



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/sass/tree/rule_node.rb', line 183

def _cssize(parent)
  node = super
  rules = node.children.select {|c| c.is_a?(RuleNode)}
  props = node.children.reject {|c| c.is_a?(RuleNode) || c.invisible?}

  unless props.empty?
    node.children = props
    rules.each {|r| r.tabs += 1} if style == :nested
    rules.unshift(node)
  end

  rules.last.group_end = true unless parent || rules.empty?

  rules
end

#_to_s(tabs) ⇒ String (protected)

Computes the CSS for the rule.

Parameters:

  • tabs (Fixnum)

    The level of indentation for the CSS

Returns:

  • (String)

    The resulting CSS



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/sass/tree/rule_node.rb', line 120

def _to_s(tabs)
  tabs = tabs + self.tabs

  rule_separator = style == :compressed ? ',' : ', '
  line_separator = [:nested, :expanded].include?(style) ? ",\n" : rule_separator
  rule_indent = '  ' * (tabs - 1)
  per_rule_indent, total_indent = [:nested, :expanded].include?(style) ? [rule_indent, ''] : ['', rule_indent]

  total_rule = total_indent + resolved_rules.map do |line|
    per_rule_indent + line.join(rule_separator)
  end.join(line_separator)

  to_return = ''
  old_spaces = '  ' * (tabs - 1)
  spaces = '  ' * tabs
  if @options[:line_comments] && style != :compressed
    to_return << "#{old_spaces}/* line #{line}"

    if filename
      relative_filename = if @options[:css_filename]
        begin
          Pathname.new(filename).relative_path_from(
            Pathname.new(File.dirname(@options[:css_filename]))).to_s
        rescue ArgumentError
          nil
        end
      end
      relative_filename ||= filename
      to_return << ", #{relative_filename}"
    end

    to_return << " */\n"
  end

  if style == :compact
    properties = children.map { |a| a.to_s(1) }.select{|a| a && a.length > 0}.join(' ')
    to_return << "#{total_rule} { #{properties} }#{"\n" if group_end}"
  elsif style == :compressed
    properties = children.map { |a| a.to_s(1) }.select{|a| a && a.length > 0}.join(';')
    to_return << "#{total_rule}{#{properties}}"
  else
    properties = children.map { |a| a.to_s(tabs + 1) }.select{|a| a && a.length > 0}.join("\n")
    end_props = (style == :expanded ? "\n" + old_spaces : ' ')
    to_return << "#{total_rule} {\n#{properties}#{end_props}}#{"\n" if group_end}"
  end

  to_return
end

#add_rules(node)

Adds another Sass::Tree::RuleNode's rules to this one's.

Parameters:



105
106
107
# File 'lib/sass/tree/rule_node.rb', line 105

def add_rules(node)
  @rules += node.rules
end

#continued?Boolean

Returns Whether or not this rule is continued on the next line.

Returns:

  • (Boolean)

    Whether or not this rule is continued on the next line



110
111
112
# File 'lib/sass/tree/rule_node.rb', line 110

def continued?
  @rules.last[-1] == ?,
end

#cssize!(parent) (protected)

Resolves parent references and nested selectors, and updates the indentation based on the parent's indentation.

Parameters:

Raises:



205
206
207
208
# File 'lib/sass/tree/rule_node.rb', line 205

def cssize!(parent)
  self.resolved_rules = resolve_parent_refs(parent && parent.resolved_rules)
  super
end

#perform!(environment) (protected)

Runs any SassScript that may be embedded in the rule, and parses the selectors for commas.

Parameters:

  • environment (Sass::Environment)

    The lexical environment containing variable and mixin values



174
175
176
177
# File 'lib/sass/tree/rule_node.rb', line 174

def perform!(environment)
  @parsed_rules = @rules.map {|r| parse_selector(interpolate(r, environment))}
  super
end

#to_sass(tabs, opts = {})

See Also:



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/sass/css.rb', line 26

def to_sass(tabs, opts = {})
  name = rules.first
  name = "\\" + name if name[0] == ?:
  str = "\n#{'  ' * tabs}#{name}#{children.any? { |c| c.is_a? PropNode } ? "\n" : ''}"

  children.each do |child|
    str << "#{child.to_sass(tabs + 1, opts)}"
  end

  str
end