Class: Sass::Tree::Node

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/sass/tree/node.rb

Overview

The abstract superclass of all parse-tree nodes.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeNode

Returns a new instance of Node.



59
60
61
# File 'lib/sass/tree/node.rb', line 59

def initialize
  @children = []
end

Instance Attribute Details

#childrenArray<Tree::Node>

The child nodes of this node.

Returns:



34
35
36
# File 'lib/sass/tree/node.rb', line 34

def children
  @children
end

#filenameString

The name of the document on which this node appeared.

Returns:

  • (String)


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

def filename
  @filename || (@options && @options[:filename])
end

#has_childrenBoolean

Whether or not this node has child nodes. This may be true even when #children is empty, in which case this node has an empty block (e.g. {}).

Returns:

  • (Boolean)


41
42
43
# File 'lib/sass/tree/node.rb', line 41

def has_children
  @has_children
end

#lineFixnum

The line of the document on which this node appeared.

Returns:

  • (Fixnum)


46
47
48
# File 'lib/sass/tree/node.rb', line 46

def line
  @line
end

#options{Symbol => Object}

The options hash for the node. See the Sass options documentation.

Returns:

  • ({Symbol => Object})


57
58
59
# File 'lib/sass/tree/node.rb', line 57

def options
  @options
end

Instance Method Details

#<<(child)

Appends a child to the node.

Parameters:

Raises:

See Also:



90
91
92
93
94
95
# File 'lib/sass/tree/node.rb', line 90

def <<(child)
  return if child.nil?
  check_child! child
  self.has_children = true
  @children << child
end

#==(other) ⇒ Boolean

Compares this node and another object (only other Sass::Tree::Nodes will be equal). This does a structural comparison; if the contents of the nodes and all the child nodes are equivalent, then the nodes are as well.

Only static nodes need to override this.

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)

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

See Also:



119
120
121
# File 'lib/sass/tree/node.rb', line 119

def ==(other)
  self.class == other.class && other.children == children
end

#_cssize(extends, parent) ⇒ Tree::Node+ (protected)

Converts this static Sass node into a static CSS node, returning the new node. This doesn't modify this node or any of its children.

Parameters:

Returns:

Raises:

See Also:



272
273
274
275
276
# File 'lib/sass/tree/node.rb', line 272

def _cssize(extends, parent)
  node = dup
  node.cssize!(extends, parent)
  node
end

#_perform(environment) ⇒ Tree::Node+ (protected)

Runs any dynamic Sass code in this particular node. This doesn't modify this node or any of its children.

Parameters:

  • environment (Sass::Environment)

    The lexical environment containing variable and mixin values

Returns:

See Also:



299
300
301
302
303
# File 'lib/sass/tree/node.rb', line 299

def _perform(environment)
  node = dup
  node.perform!(environment)
  node
end

#_to_sString? (protected)

Computes the CSS corresponding to this particular Sass node.

This method should never raise SyntaxErrors. Such errors will not be properly annotated with Sass backtrace information. All error conditions should be checked in earlier transformations, such as #cssize and #perform.

Parameters:

  • args (Array)

    ignored

Returns:

  • (String, nil)

    The resulting CSS

Raises:

  • (NotImplementedError)

See Also:



256
257
258
# File 'lib/sass/tree/node.rb', line 256

def _to_s
  raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #_to_s or #to_s.")
end

#balance(*args) (protected)

Raises:

See Also:

  • Haml::Shared.balance


344
345
346
347
348
# File 'lib/sass/tree/node.rb', line 344

def balance(*args)
  res = Haml::Shared.balance(*args)
  return res if res
  raise Sass::SyntaxError.new("Unbalanced brackets.", :line => line)
end

#check_child!(child)

Raises an error if the given child node is invalid.

Parameters:

Raises:

See Also:



102
103
104
105
106
# File 'lib/sass/tree/node.rb', line 102

def check_child!(child)
  if msg = invalid_child?(child)
    raise Sass::SyntaxError.new(msg, :line => child.line)
  end
end

#children_to_src(tabs, opts, fmt) ⇒ String (protected)

Converts the children of this node to a Sass or SCSS string. This will return the trailing newline for the previous line, including brackets if this is SCSS.

Parameters:

  • tabs (Fixnum)

    The amount of tabulation to use for the Sass code

  • opts ({Symbol => Object})

    An options hash (see CSS#initialize)

  • fmt (Symbol)

    :sass or :scss

Returns:

  • (String)

    The Sass or SCSS code corresponding to the children



393
394
395
396
397
398
399
# File 'lib/sass/tree/node.rb', line 393

def children_to_src(tabs, opts, fmt)
  return fmt == :sass ? "\n" : " {}\n" if children.empty?

  (fmt == :sass ? "\n" : " {\n") +
    children.map {|c| c.send("to_#{fmt}", tabs + 1, opts)}.join.rstrip +
    (fmt == :sass ? "\n" : " }\n")
end

#cssize(extends, parent = nil) ⇒ Tree::Node

Converts a static Sass tree (e.g. the output of #perform) into a static CSS tree.

#cssize shouldn't be overridden directly; instead, override #_cssize or #cssize!.

Parameters:

Returns:

  • (Tree::Node)

    The resulting tree of static nodes

Raises:

See Also:



188
189
190
191
192
193
# File 'lib/sass/tree/node.rb', line 188

def cssize(extends, parent = nil)
  _cssize(extends, (parent if parent.class == self.class))
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => filename, :line => line)
  raise e
end

#cssize!(extends, parent) (protected)

Destructively converts this static Sass node into a static CSS node. This does modify this node, but will be run non-destructively by #_cssize.

Parameters:

See Also:



287
288
289
# File 'lib/sass/tree/node.rb', line 287

def cssize!(extends, parent)
  self.children = children.map {|c| c.cssize(extends, self)}.flatten
end

#dasherize(s, opts) ⇒ String (protected)

Convert any underscores in a string into hyphens, but only if the :dasherize option is set.

Parameters:

  • s (String)

    The string to convert

  • opts ({Symbol => Object})

    The options hash

Returns:

  • (String)

    The converted string



444
445
446
447
448
449
450
# File 'lib/sass/tree/node.rb', line 444

def dasherize(s, opts)
  if opts[:dasherize]
    s.gsub('_', '-')
  else
    s
  end
end

#do_extend(extends) ⇒ Tree::Node

TODO:

Link this to the reference documentation on @extend when such a thing exists.

Converts a static CSS tree (e.g. the output of #cssize) into another static CSS tree, with the given extensions applied to all relevant RuleNodes.

Parameters:

Returns:

  • (Tree::Node)

    The resulting tree of static CSS nodes.

Raises:

  • (Sass::SyntaxError)

    Only if there's a programmer error and this is not a static CSS tree



166
167
168
169
170
171
172
173
# File 'lib/sass/tree/node.rb', line 166

def do_extend(extends)
  node = dup
  node.children = children.map {|c| c.do_extend(extends)}
  node
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => filename, :line => line)
  raise e
end

#each {|node| ... }

Iterates through each node in the tree rooted at this node in a pre-order walk.

Yields:

  • node

Yield Parameters:

  • node (Node)

    a node in the tree



220
221
222
223
# File 'lib/sass/tree/node.rb', line 220

def each(&block)
  yield self
  children.each {|c| c.each(&block)}
end

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

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

By default, all child nodes except those only allowed under specific nodes (MixinDefNode, ImportNode, ExtendNode) are valid. This is expected to be overriden by subclasses for which some children are invalid.

Parameters:

Returns:

  • (Boolean, String)

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



361
362
363
364
365
366
367
368
369
370
# File 'lib/sass/tree/node.rb', line 361

def invalid_child?(child)
  case child
  when Tree::MixinDefNode
    "Mixins may only be defined at the root of a document."
  when Tree::ImportNode
    "Import directives may only be used at the root of a document."
  when Tree::ExtendNode
    "Extend directives may only be used within rules."
  end
end

#invisible?Boolean

True if #to_s will return nil; that is, if the node shouldn't be rendered. Should only be called in a static tree.

Returns:

  • (Boolean)


128
# File 'lib/sass/tree/node.rb', line 128

def invisible?; false; end

#perform(environment) ⇒ Tree::Node

Converts a dynamic tree into a static Sass tree. That is, runs the dynamic Sass code: mixins, variables, control directives, and so forth. This doesn't modify this node or any of its children.

#perform shouldn't be overridden directly; instead, override #_perform or #perform!.

Parameters:

  • environment (Sass::Environment)

    The lexical environment containing variable and mixin values

Returns:

  • (Tree::Node)

    The resulting tree of static nodes

Raises:

See Also:



208
209
210
211
212
213
# File 'lib/sass/tree/node.rb', line 208

def perform(environment)
  _perform(environment)
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => filename, :line => line)
  raise e
end

#perform!(environment) (protected)

Destructively runs dynamic Sass code in this particular node. This does modify this node, but will be run non-destructively by #_perform.

Parameters:

  • environment (Sass::Environment)

    The lexical environment containing variable and mixin values

See Also:



312
313
314
# File 'lib/sass/tree/node.rb', line 312

def perform!(environment)
  self.children = perform_children(Environment.new(environment))
end

#perform_children(environment) ⇒ Array<Tree::Node> (protected)

Non-destructively runs #perform on all children of the current node.

Parameters:

  • environment (Sass::Environment)

    The lexical environment containing variable and mixin values

Returns:

  • (Array<Tree::Node>)

    The resulting static nodes



321
322
323
# File 'lib/sass/tree/node.rb', line 321

def perform_children(environment)
  children.map {|c| c.perform(environment)}.flatten
end

#run_interp(text, environment) ⇒ String (protected)

Replaces SassScript in a chunk of text with the resulting value.

Parameters:

Returns:

  • (String)

    The interpolated text



332
333
334
335
336
337
338
339
340
# File 'lib/sass/tree/node.rb', line 332

def run_interp(text, environment)
  text.map do |r|
    next r if r.is_a?(String)
    val = r.perform(environment)
    # Interpolated strings should never render with quotes
    next val.value if val.is_a?(Sass::Script::String)
    val.to_s
  end.join.strip
end

#selector_to_sass(sel, opts) ⇒ String (protected)

Converts a selector to a Sass string.

Parameters:

Returns:

  • (String)

    The Sass code corresponding to the selector



417
418
419
420
421
422
423
424
425
# File 'lib/sass/tree/node.rb', line 417

def selector_to_sass(sel, opts)
  sel.map do |r|
    if r.is_a?(String)
      r.gsub(/(,[ \t]*)?\n\s*/) {$1 ? $1 + "\n" : " "}
    else
      "\#{#{r.to_sass(opts)}}"
    end
  end.join
end

#selector_to_scss(sel, tabs, opts) ⇒ String (protected)

Converts a selector to a SCSS string.

Parameters:

  • sel (Array<String, Sass::Script::Node>)

    The selector to convert

  • tabs (Fixnum)

    The indentation of the selector

  • opts ({Symbol => Object})

    An options hash (see CSS#initialize)

Returns:

  • (String)

    The SCSS code corresponding to the selector



433
434
435
436
# File 'lib/sass/tree/node.rb', line 433

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

#selector_to_src(sel, tabs, opts, fmt) ⇒ String (protected)

Converts a selector to a Sass or SCSS string.

Parameters:

  • sel (Array<String, Sass::Script::Node>)

    The selector to convert

  • tabs (Fixnum)

    The indentation of the selector

  • opts ({Symbol => Object})

    An options hash (see CSS#initialize)

  • fmt (Symbol)

    :sass or :scss

Returns:

  • (String)

    The Sass or SCSS code corresponding to the selector



408
409
410
# File 'lib/sass/tree/node.rb', line 408

def selector_to_src(sel, tabs, opts, fmt)
  fmt == :sass ? selector_to_sass(sel, opts) : selector_to_scss(sel, tabs, opts)
end

#semi(fmt) ⇒ String (protected)

Returns a semicolon if this is SCSS, or an empty string if this is Sass.

Parameters:

  • fmt (Symbol)

    :sass or :scss

Returns:

  • (String)

    A semicolon or the empty string



456
457
458
# File 'lib/sass/tree/node.rb', line 456

def semi(fmt)
  fmt == :sass ? "" : ";"
end

#styleSymbol

The output style. See the Sass options documentation.

Returns:

  • (Symbol)


133
134
135
# File 'lib/sass/tree/node.rb', line 133

def style
  @options[:style]
end

#to_s(*args) ⇒ String?

Computes the CSS corresponding to this static CSS tree.

#to_s shouldn't be overridden directly; instead, override #_to_s. Only static-node subclasses need to implement #to_s.

This may return nil, but it will only do so if #invisible? is true.

Parameters:

  • args (Array)

    Passed on to #_to_s

Returns:

  • (String, nil)

    The resulting CSS

See Also:



147
148
149
150
151
152
# File 'lib/sass/tree/node.rb', line 147

def to_s(*args)
  _to_s(*args)
rescue Sass::SyntaxError => e
  e.modify_backtrace(:filename => filename, :line => line)
  raise e
end

#to_sass(tabs = 0, opts = {}) ⇒ String

Converts a node to Sass code that will generate it.

Parameters:

  • tabs (Fixnum) (defaults to: 0)

    The amount of tabulation to use for the Sass code

  • opts ({Symbol => Object}) (defaults to: {})

    An options hash (see CSS#initialize)

Returns:

  • (String)

    The Sass code corresponding to the node



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

def to_sass(tabs = 0, opts = {})
  to_src(tabs, opts, :sass)
end

#to_scss(tabs = 0, opts = {}) ⇒ String

Converts a node to SCSS code that will generate it.

Parameters:

  • tabs (Fixnum) (defaults to: 0)

    The amount of tabulation to use for the SCSS code

  • opts ({Symbol => Object}) (defaults to: {})

    An options hash (see CSS#initialize)

Returns:

  • (String)

    The Sass code corresponding to the node



239
240
241
# File 'lib/sass/tree/node.rb', line 239

def to_scss(tabs = 0, opts = {})
  to_src(tabs, opts, :scss)
end

#to_src(tabs, opts, fmt) ⇒ String (protected)

Converts a node to Sass or SCSS code that will generate it.

This method is called by the default #to_sass and #to_scss methods, so that the same code can be used for both with minor variations.

Parameters:

  • tabs (Fixnum)

    The amount of tabulation to use for the SCSS code

  • opts ({Symbol => Object})

    An options hash (see CSS#initialize)

  • fmt (Symbol)

    :sass or :scss

Returns:

  • (String)

    The Sass or SCSS code corresponding to the node

Raises:

  • (NotImplementedError)


381
382
383
# File 'lib/sass/tree/node.rb', line 381

def to_src(tabs, opts, fmt)
  raise NotImplementedError.new("All static-node subclasses of Sass::Tree::Node must override #to_#{fmt}.")
end