Class: Sass::Tree::RuleNode

Inherits:
Node
  • Object
show all
Defined in:
lib/sass/tree/rule_node.rb

Overview

A static node reprenting a CSS rule.

See Also:

Constant Summary collapse

PARENT =

The character used to include the parent selector

'&'

Instance Attribute Summary collapse

Attributes inherited from Node

#children, #filename, #has_children, #line, #options

Instance Method Summary collapse

Methods inherited from Node

#<<, #_perform, #balance, #check_child!, #children_to_src, #cssize, #dasherize, #each, #invisible?, #perform, #perform_children, #render, #run_interp, #semi, #style, #to_s, #to_src

Constructor Details

#initialize(rule) ⇒ RuleNode

Returns a new instance of RuleNode.

Parameters:



55
56
57
58
59
60
# File 'lib/sass/tree/rule_node.rb', line 55

def initialize(rule)
  @rule = Haml::Util.strip_string_array(
    Haml::Util.merge_adjacent_strings(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)


51
52
53
# File 'lib/sass/tree/rule_node.rb', line 51

def group_end
  @group_end
end

#parsed_rulesSelector::CommaSequence

The CSS selector for this rule, without any unresolved interpolation but with parent references still intact. It's only set once Node#perform has been called.



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

def parsed_rules
  @parsed_rules
end

#resolved_rulesSelector::CommaSequence

The CSS selector for this rule, without any unresolved interpolation or parent references. It's only set once Node#cssize has been called.



33
34
35
# File 'lib/sass/tree/rule_node.rb', line 33

def resolved_rules
  @resolved_rules
end

#ruleArray<String, Sass::Script::Node>

The CSS selector for this rule, interspersed with Script::Nodes representing #{}-interpolation. Any adjacent strings will be merged together.

Returns:



18
19
20
# File 'lib/sass/tree/rule_node.rb', line 18

def rule
  @rule
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)


45
46
47
# File 'lib/sass/tree/rule_node.rb', line 45

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



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

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

#_cssize(extends, parent) (protected)

Converts nested rules into a flat list of rules.

Parameters:



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/sass/tree/rule_node.rb', line 205

def _cssize(extends, 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



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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/sass/tree/rule_node.rb', line 128

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

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

  total_rule = total_indent + resolved_rules.members.
    map {|seq| seq.to_a.join}.
    join(rule_separator).split("\n").map do |line|
    per_rule_indent + line.strip
  end.join(line_separator)

  to_return = ''
  old_spaces = '  ' * (tabs - 1)
  spaces = '  ' * tabs
  if style != :compressed
    if @options[:debug_info]
      to_return << debug_info_rule.to_s(tabs) << "\n"
    elsif @options[:line_comments]
      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
  end

  if style == :compact
    properties = children.map { |a| a.to_s(1) }.join(' ')
    to_return << "#{total_rule} { #{properties} }#{"\n" if group_end}"
  elsif style == :compressed
    properties = children.map { |a| a.to_s(1) }.join(';')
    to_return << "#{total_rule}{#{properties}}"
  else
    properties = children.map { |a| a.to_s(tabs + 1) }.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:



74
75
76
77
# File 'lib/sass/tree/rule_node.rb', line 74

def add_rules(node)
  @rule = Haml::Util.strip_string_array(
    Haml::Util.merge_adjacent_strings(@rule + ["\n"] + node.rule))
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



80
81
82
83
# File 'lib/sass/tree/rule_node.rb', line 80

def continued?
  last = @rule.last
  last.is_a?(String) && last[-1] == ?,
end

#cssize!(extends, parent) (protected)

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

Parameters:

Raises:



229
230
231
232
# File 'lib/sass/tree/rule_node.rb', line 229

def cssize!(extends, parent)
  self.resolved_rules = @parsed_rules.resolve_parent_refs(parent && parent.resolved_rules)
  super
end

#debug_info{#to_s => #to_s} (protected)

A hash that will be associated with this rule in the CSS document if the :debug_info option is enabled. This data is used by e.g. the FireSass Firebug extension.

Returns:



251
252
253
254
# File 'lib/sass/tree/rule_node.rb', line 251

def debug_info
  {:filename => filename && ("file://" + URI.escape(File.expand_path(filename))),
   :line => self.line}
end

#do_extend(extends)

Extends this Rule's selector with the given extends.

See Also:



116
117
118
119
120
# File 'lib/sass/tree/rule_node.rb', line 116

def do_extend(extends)
  node = dup
  node.resolved_rules = resolved_rules.do_extend(extends)
  node
end

#invalid_child?(child) ⇒ Boolean, String (protected)

Returns an error message if the given child node is invalid, and false otherwise.

ExtendNodes are valid within Sass::Tree::RuleNodes.

Parameters:

  • child (Tree::Node)

    A potential child nodecompact.

Returns:

  • (Boolean, String)

    Whether or not the child node is valid, as well as the error message to display if it is invalid



242
243
244
# File 'lib/sass/tree/rule_node.rb', line 242

def invalid_child?(child)
  super unless child.is_a?(ExtendNode)
end

#perform!(environment) (protected)

Runs SassScript interpolation in the selector, and then parses the result into a Selector::CommaSequence.

Parameters:

  • environment (Sass::Environment)

    The lexical environment containing variable and mixin values



193
194
195
196
197
# File 'lib/sass/tree/rule_node.rb', line 193

def perform!(environment)
  @parsed_rules = Sass::SCSS::StaticParser.new(run_interp(@rule, environment), self.line).
    parse_selector(self.filename)
  super
end

#to_sass(tabs, opts = {})

See Also:



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/sass/tree/rule_node.rb', line 86

def to_sass(tabs, opts = {})
  name = rule.map do |r|
    if r.is_a?(String)
      r.gsub(/(,[ \t]*)?\n\s*/) {$1 ? $1 + "\n" : " "}
    else
      "\#{#{r.to_sass(opts)}}"
    end
  end.join
  name = "\\" + name if name[0] == ?:
  name.gsub(/^/, '  ' * tabs) + children_to_src(tabs, opts, :sass)
end

#to_scss(tabs, opts = {})

See Also:



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/sass/tree/rule_node.rb', line 99

def to_scss(tabs, opts = {})
  name = rule.map {|r| r.is_a?(String) ? r : "\#{#{r.to_sass(opts)}}"}.
    join.gsub(/^[ \t]*/, '  ' * tabs)

  res = name + children_to_src(tabs, opts, :scss)

  if children.last.is_a?(CommentNode) && children.last.silent
    res.slice!(-3..-1)
    res << "\n" << ('  ' * tabs) << "}\n"
  end

  res
end