Class: ActiveComponent::Base
- Includes:
- ActiveComponent, Enumerable, Haml::Helpers, Haml::Helpers::XssMods
- Defined in:
- lib/active_component/base.rb
Constant Summary
Constants included from ActiveComponent
BLOCK_ELEMENTS, EMPTY_ELEMENTS, HEADING_ELEMENTS, HTML5_ELEMENTS, PHRASING_ELEMENTS, SECTION_ELEMENTS
Instance Attribute Summary collapse
-
#attributes ⇒ Object
require ‘forwardable’ extend ::Forwardable.
-
#childrenHash ⇒ Object
TODO: was not necessary to provide in Tree::TreeNode.
-
#node_content ⇒ Object
node_content of this node.
-
#node_name ⇒ Object
node_name of this node.
-
#parent ⇒ Object
readonly
Parent of this node.
-
#title ⇒ Object
require ‘forwardable’ extend ::Forwardable.
Class Method Summary collapse
- .def_component_helper(component_class) ⇒ Object
-
.def_html_sub_components(names, super_class) ⇒ Object
This helper creates HTML wrapper components that become sub classes of the given super_class (e.g. Section).
- .inherited(component_class) ⇒ Object
-
.json_create(json_hash) ⇒ Tree::TreeNode
Creates a Tree::TreeNode object instance from a given JSON Hash representation.
Instance Method Summary collapse
-
#<<(child) ⇒ Tree::TreeNode
Convenience synonym for Tree::TreeNode#add method.
-
#<=>(other) ⇒ Number
Provides a comparision operation for the nodes.
-
#[](node_name_or_index) ⇒ Tree::TreeNode
Returns the requested node from the set of immediate children.
-
#add(child, prepend = false) ⇒ Tree::TreeNode
Overridden / own methods ——————– Adds the specified child node to the receiver node.
-
#breadth ⇒ Number
Returns breadth of the tree at the receiver node’s level.
-
#breadth_each {|child| ... } ⇒ Object
Performs breadth-first traversal of the (sub)tree rooted at the receiver node.
-
#children {|child| ... } ⇒ Array<Tree::TreeNode>
Returns an array of all the immediate children of the receiver node.
- #class_name ⇒ Object
- #content ⇒ Object
- #content=(cont) ⇒ Object
-
#depth ⇒ Number
deprecated
Deprecated.
This method returns an incorrect value. Use the ‘nodeDepth’ method instead.
-
#detached_copy ⇒ Tree::TreeNode
Returns a copy of the receiver node, with its parent and children links removed.
-
#each {|child| ... } ⇒ Object
Traverses each node (including the receiver node) of the (sub)tree rooted at this node by yielding the nodes to the specified block.
-
#each_leaf {|node| ... } ⇒ Object
Yields every leaf node of the (sub)tree rooted at the receiver node to the specified block.
-
#firstChild ⇒ Tree::TreeNode
Returns the first child of the receiver node.
-
#firstSibling ⇒ Tree::TreeNode
Returns the first sibling of the receiver node.
-
#freezeTree! ⇒ Object
Freezes all nodes in the (sub)tree rooted at the receiver node.
-
#hasChildren? ⇒ Boolean
Returns
true
if the receiver node has any child node. -
#hasnode_content? ⇒ Boolean
Returns
true
if the receiver node has node_content. - #html_class ⇒ Object
-
#in_degree ⇒ Number
Returns the incoming edge-count of the receiver node.
-
#init_component(args, var_names = [:content, :title, :attributes], &content_block) ⇒ Object
Initializes component by fetching arguments of a flexible method call as well as initializing the node and buffer Example def initialize(*args, &content_block) fetch_args(args, [:content, :title, :special_param, :attributes], &content_block).
-
#init_node(node_name = object_id, node_content = nil) ⇒ Object
Creates a new node with a node_name and optional node_content.
- #is_html_tag_wrapper? ⇒ Boolean
-
#is_root? ⇒ Boolean
(also: #isRoot?)
Returns
true
if the receiver is a root node. -
#isFirstSibling? ⇒ Boolean
Returns
true
if the receiver node is the first sibling at its level. -
#isLastSibling? ⇒ Boolean
Returns
true
if the receiver node is the last sibling at its level. -
#isLeaf? ⇒ Boolean
Returns
true
if the receiver node is a ‘leaf’ - i.e., one without any children. -
#isOnlyChild? ⇒ Boolean
Returns
true
if the receiver node is the only child of its parent. -
#lastChild ⇒ Tree::TreeNode
Returns the last child of the receiver node.
-
#lastSibling ⇒ Tree::TreeNode
Returns the last sibling of the receiver node.
-
#length ⇒ Number
deprecated
Deprecated.
This method node_name is ambiguous and may be removed. Use TreeNode#size instead.
-
#marshal_dump ⇒ Object
Returns a marshal-dump represention of the (sub)tree rooted at the receiver node.
-
#marshal_load(dumped_tree_array) ⇒ Object
Loads a marshalled dump of a tree and returns the root node of the reconstructed tree.
-
#nextSibling ⇒ Tree::treeNode
Returns the next sibling for the receiver node.
-
#nodeDepth ⇒ Number
(also: #level)
Returns depth of the receiver node in its tree.
-
#nodeHeight ⇒ Number
Returns height of the (sub)tree from the receiver node.
-
#out_degree ⇒ Number
Returns the outgoing edge-count of the receiver node.
-
#parentage ⇒ Array?
Returns an array of ancestors of the receiver node in reversed order (the first element is the immediate parent of the receiver).
-
#preordered_each {|child| ... } ⇒ Object
Traverses the (sub)tree rooted at the receiver node in pre-ordered sequence.
- #prepend(child) ⇒ Object
-
#previousSibling ⇒ Tree::treeNode
Returns the previous sibling of the receiver node.
-
#printTree(level = 0) ⇒ Object
Pretty prints the (sub)tree rooted at the receiver node.
-
#remove!(child) ⇒ Tree::TreeNode
Removes the specified child node from the receiver node.
-
#removeAll! ⇒ Tree::TreeNode
Removes all children from the receiver node.
-
#removeFromParent! ⇒ Tree:TreeNode
Removes the receiver node from its parent.
-
#root ⇒ Tree::TreeNode
Returns root node for the (sub)tree to which the receiver node belongs.
-
#siblings {|sibling| ... } ⇒ Array<Tree::TreeNode>
Returns an array of siblings for the receiver node.
-
#size ⇒ Number
Returns the total number of nodes in this (sub)tree, including the receiver node.
- #to_html ⇒ Object
-
#to_json(*a) ⇒ Object
Creates a JSON representation of this node including all it’s children.
- #to_s ⇒ Object
Methods included from Enumerable
#find_a, #includes_a?, #transmogrify
Methods included from ActiveComponent
#print_contents, #print_object, #print_tag, #wrap_contents
Instance Attribute Details
#attributes ⇒ Object
require ‘forwardable’ extend ::Forwardable
14 15 16 |
# File 'lib/active_component/base.rb', line 14 def attributes @attributes end |
#childrenHash ⇒ Object
TODO: was not necessary to provide in Tree::TreeNode. Why here?
209 210 211 |
# File 'lib/active_component/base.rb', line 209 def childrenHash @childrenHash end |
#node_content ⇒ Object
node_content of this node. Can be nil
.
206 207 208 |
# File 'lib/active_component/base.rb', line 206 def node_content @node_content end |
#node_name ⇒ Object
node_name of this node. Expected to be unique within the tree.
203 204 205 |
# File 'lib/active_component/base.rb', line 203 def node_name @node_name end |
#parent ⇒ Object
Parent of this node. Will be nil
for a root node.
212 213 214 |
# File 'lib/active_component/base.rb', line 212 def parent @parent end |
#title ⇒ Object
require ‘forwardable’ extend ::Forwardable
14 15 16 |
# File 'lib/active_component/base.rb', line 14 def title @title end |
Class Method Details
.def_component_helper(component_class) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/active_component/base.rb', line 115 def self.def_component_helper(component_class) raise ArgumentError, "Anonymous classes are not allowed because a name is needed." if component_class.to_s =~ /#/ ActiveComponent.class_eval do # New way of defining methods with a block parameter (1.9 only) # Attention: evaluation context seems to differ! #define_method(component_class.to_s.underscore) do |*args, &block| #component_class.new(*args, &block) #end # Old way of defining methods with a block parameter (supported by 1.8) eval %( def #{component_class.to_s.underscore}(*args, &block) #{component_class}.new(*args, &block) end ) end end |
.def_html_sub_components(names, super_class) ⇒ Object
This helper creates HTML wrapper components that become sub classes of the given super_class (e.g. Section)
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/active_component/base.rb', line 135 def self.def_html_sub_components(names, super_class) for name in names # Creating an anonymous subclass and set according constant new_component = Object.const_set(name.to_s.camelize, Class.new(super_class)) # Register component instantiation helper manually with the class constant def_component_helper(new_component) new_component.class_eval do # FIXME: Remove eval wrap as soon as Ruby 1.9.2 support can be dropped # Problem: "super from singleton method that is defined to multiple classes is not supported; this will be fixed in 1.9.3 or later" # See https://gist.github.com/455547 eval %( def initialize(*args, &block) args << {:tag_type => self.class.to_s.underscore.to_sym} super *args, &block end ) end end end |
.inherited(component_class) ⇒ Object
111 112 113 |
# File 'lib/active_component/base.rb', line 111 def self.inherited(component_class) def_component_helper(component_class) unless component_class.to_s =~ /#/ end |
.json_create(json_hash) ⇒ Tree::TreeNode
Creates a Tree::TreeNode object instance from a given JSON Hash representation. This requires the JSON gem to be available, or else the operation fails with a warning message.
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 |
# File 'lib/active_component/base.rb', line 817 def self.json_create(json_hash) begin require 'json' node = new(json_hash["node_name"], json_hash["node_content"]) json_hash["children"].each do |child| node << child end if json_hash["children"] return node rescue LoadError => e warn "The JSON gem couldn't be loaded. Due to this we cannot serialize the tree to a JSON representation." end end |
Instance Method Details
#<<(child) ⇒ Tree::TreeNode
Convenience synonym for Tree::TreeNode#add method.
This method allows an easy mechanism to add node hierarchies to the tree on a given path via chaining the method calls to successive child nodes.
284 285 286 |
# File 'lib/active_component/base.rb', line 284 def <<(child) add(child) end |
#<=>(other) ⇒ Number
Provides a comparision operation for the nodes.
Comparision is based on the natural character-set ordering of the node node_name.
725 726 727 728 |
# File 'lib/active_component/base.rb', line 725 def <=>(other) return +1 if other == nil self.node_name <=> other.node_name end |
#[](node_name_or_index) ⇒ Tree::TreeNode
Returns the requested node from the set of immediate children.
If the argument is numeric, then the in-sequence array of children is accessed using the argument as the index (zero-based).
If the argument is NOT numeric, then it is taken to be the node_name of the child node to be returned.
An ArgumentError exception is raised if neither node_name nor an index is provided.
523 524 525 526 527 528 529 530 531 |
# File 'lib/active_component/base.rb', line 523 def [](node_name_or_index) raise ArgumentError, "node_name_or_index needs to be provided!" if node_name_or_index == nil if node_name_or_index.kind_of?(Integer) @children[node_name_or_index] || @childrenHash[node_name_or_index] else @childrenHash[node_name_or_index] end end |
#add(child, prepend = false) ⇒ Tree::TreeNode
Overridden / own methods
Adds the specified child node to the receiver node.
This method can also be used for grafting a subtree into the receiver node’s tree, if the specified child node is the root of a subtree (i.e., has child nodes under it).
The receiver node becomes parent of the node passed in as the argument, and the child is added as the last child (“right most”) in the current set of children of the receiver node.
node_name exists.
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/active_component/base.rb', line 184 def add(child, prepend = false) raise ArgumentError, "Attempting to add a nil node" unless child raise "Child #{child.node_name} already added!" if @childrenHash.has_key?(child.node_name) @childrenHash[child.node_name] = child prepend ? @children.unshift(child) : (@children << child) raise "Great Scott! I just added a ghost child!" if !(@children.include?(child)) || @children.empty? child.parent = self child end |
#breadth ⇒ Number
Returns breadth of the tree at the receiver node’s level. A single node without siblings has a breadth of 1.
Breadth is defined to be:
- Breadth
-
Number of sibling nodes to this node + 1 (this node itself),
i.e., the number of children the parent of this node has.
895 896 897 |
# File 'lib/active_component/base.rb', line 895 def breadth isRoot? ? 1 : parent.children.size end |
#breadth_each {|child| ... } ⇒ Object
Performs breadth-first traversal of the (sub)tree rooted at the receiver node. The traversal at a given level is from left-to-right. The receiver node itself is the first node to be traversed.
480 481 482 483 484 485 486 487 488 489 490 |
# File 'lib/active_component/base.rb', line 480 def breadth_each(&block) node_queue = [self] # Create a queue with self as the initial entry # Use a queue to do breadth traversal until node_queue.empty? node_to_traverse = node_queue.shift yield node_to_traverse # Enqueue the children from left to right. node_to_traverse.children { |child| node_queue.push child } end end |
#children {|child| ... } ⇒ Array<Tree::TreeNode>
Returns an array of all the immediate children of the receiver node. The child nodes are ordered “left-to-right” in the returned array.
If a block is given, yields each child node to the block traversing from left to right.
418 419 420 421 422 423 424 |
# File 'lib/active_component/base.rb', line 418 def children if block_given? @children.each {|child| yield child} else @children end end |
#class_name ⇒ Object
95 96 97 |
# File 'lib/active_component/base.rb', line 95 def class_name self.class.to_s.hyphenize end |
#content ⇒ Object
83 84 85 86 |
# File 'lib/active_component/base.rb', line 83 def content # If content is not given yet, return node children @content || children end |
#content=(cont) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/active_component/base.rb', line 75 def content=(cont) @content = cont # Add content as a child if it is also a component cont.transmogrify do |c| self << c if c.is_a? ActiveComponent end end |
#depth ⇒ Number
This method returns an incorrect value. Use the ‘nodeDepth’ method instead.
Returns depth of the tree from the receiver node. A single leaf node has a depth of 1.
This method is DEPRECATED and may be removed in the subsequent releases. Note that the value returned by this method is actually the:
height + 1 of the node, NOT the depth.
For correct and conventional behavior, please use Tree::TreeNode#nodeDepth and Tree::TreeNode#nodeHeight methods instead.
874 875 876 877 878 879 880 881 882 883 884 885 |
# File 'lib/active_component/base.rb', line 874 def depth begin require 'structured_warnings' # To enable a nice way of deprecating of the depth method. warn DeprecatedMethodWarning, 'This method is deprecated. Please use nodeDepth() or nodeHeight() instead (bug # 22535)' rescue LoadError # Oh well. Will use the standard Kernel#warn. Behavior will be identical. warn 'Tree::TreeNode#depth() method is deprecated. Please use nodeDepth() or nodeHeight() instead (bug # 22535)' end return 1 if isLeaf? 1 + @children.collect { |child| child.depth }.max end |
#detached_copy ⇒ Tree::TreeNode
Returns a copy of the receiver node, with its parent and children links removed. The original node remains attached to its tree.
237 238 239 |
# File 'lib/active_component/base.rb', line 237 def detached_copy Tree::TreeNode.new(@node_name, @node_content ? @node_content.clone : nil) end |
#each {|child| ... } ⇒ Object
Traverses each node (including the receiver node) of the (sub)tree rooted at this node by yielding the nodes to the specified block.
The traversal is depth-first and from left-to-right in pre-ordered sequence.
454 455 456 457 |
# File 'lib/active_component/base.rb', line 454 def each(&block) # :yields: node yield self children { |child| child.each(&block) } end |
#each_leaf {|node| ... } ⇒ Object
Yields every leaf node of the (sub)tree rooted at the receiver node to the specified block.
May yield this node as well if this is a leaf node. Leaf traversal is depth-first and left-to-right.
502 503 504 |
# File 'lib/active_component/base.rb', line 502 def each_leaf &block self.each { |node| yield(node) if node.isLeaf? } end |
#firstChild ⇒ Tree::TreeNode
Returns the first child of the receiver node.
Will return nil
if no children are present.
431 432 433 |
# File 'lib/active_component/base.rb', line 431 def firstChild children.first end |
#firstSibling ⇒ Tree::TreeNode
Fix the inconsistency of returning root as its first sibling, and returning a nil
array for siblings of the node.
Returns the first sibling of the receiver node. If this is the root node, then returns itself.
‘First’ sibling is defined as follows:
- First sibling
-
The left-most child of the receiver’s parent, which may be the receiver itself
603 604 605 |
# File 'lib/active_component/base.rb', line 603 def firstSibling isRoot? ? self : parent.children.first end |
#freezeTree! ⇒ Object
Freezes all nodes in the (sub)tree rooted at the receiver node.
The nodes become immutable after this operation. In effect, the entire tree’s structure and node_contents become read-only and cannot be changed.
734 735 736 |
# File 'lib/active_component/base.rb', line 734 def freezeTree! each {|node| node.freeze} end |
#hasChildren? ⇒ Boolean
Returns true
if the receiver node has any child node.
395 396 397 |
# File 'lib/active_component/base.rb', line 395 def hasChildren? @children.length != 0 end |
#hasnode_content? ⇒ Boolean
Returns true
if the receiver node has node_content.
369 370 371 |
# File 'lib/active_component/base.rb', line 369 def hasnode_content? @node_content != nil end |
#html_class ⇒ Object
88 89 90 91 92 93 |
# File 'lib/active_component/base.rb', line 88 def html_class class_arr = [] class_arr << @title.hyphenize unless @title.blank? class_arr << class_name unless is_html_tag_wrapper? class_arr.uniq end |
#in_degree ⇒ Number
Returns the incoming edge-count of the receiver node.
In-degree is defined as:
- In-degree
-
The number of edges arriving at the node (0 for root, 1 for all other nodes)
-
In-degree = 0 for a root or orphaned node
-
In-degree = 1 for a node which has a parent
908 909 910 |
# File 'lib/active_component/base.rb', line 908 def in_degree isRoot? ? 0 : 1 end |
#init_component(args, var_names = [:content, :title, :attributes], &content_block) ⇒ Object
Initializes component by fetching arguments of a flexible method call as well as initializing the node and buffer Example
def initialize(*args, &content_block)
fetch_args(args, [:content, :title, :special_param, :attributes], &content_block)
# Set defaults afterwards
@attributes ||= {:class => @title}
end
Arguments may be non-hash objects with certain order. Then, the arguments will be set to instance variables with the var_names entry at the same index. Though, it is always possible use a hash for assigning parameters to keywords (e.g. :title => “Blumenkübel”); As always, parenthesis can be omitted for this last hash.
The list of variable names will be iterated in order. The first element becomes an instance variable that gets the block assigned (if passed along). If the list of variable names iteration is complete, remaining key-value pairs of the Hash part of the arguments list are merged into @attributes.
Thus, all of the following signatures are legal for the **sender of fetch_args**: *Example 1*
new("content", "title", :class => "api")
*Example 2*
new(:class => "api", :title => "title") { content }
*Example 3*
new("content", {:attributes => {:class => "api"}, :title => "title"})
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/active_component/base.rb', line 47 def init_component(args, var_names = [:content, :title, :attributes], &content_block) init_node init_buffer # Fetch arguments non_hash_args = [] args_hash = {} # Collect all non-hash args and merge all hashs together for arg in args arg.is_a?(Hash) ? args_hash.merge!(arg) : non_hash_args << arg end # var_names.first is set to block if block given send(var_names.shift.to_s + "=", content_block.call) if content_block for var_name in var_names # Each value is extracted from args_hash, if resp. var_name present, otherwise the next non-hash argument is taken send var_name.to_s + "=", (args_hash.delete(var_name) or non_hash_args.shift) end @attributes ||= {} # All args in args_hash that have not been used for setting an instance variable become attributes. @attributes.set_defaults!(args_hash) # The class attribute will contain the component title and class_name (unless component is a html tag wrapper) @attributes[:class] = (html_class + [@attributes[:class]].flatten).compact.uniq end |
#init_node(node_name = object_id, node_content = nil) ⇒ Object
Creates a new node with a node_name and optional node_content. The node node_name is expected to be unique within the tree.
The node_content can be of any type, and defaults to nil
.
224 225 226 227 228 229 230 231 |
# File 'lib/active_component/base.rb', line 224 def init_node(node_name = object_id, node_content = nil) raise ArgumentError, "Node node_name HAS to be provided!" if node_name == nil @node_name, @node_content = node_name, node_content self.setAsRoot! @childrenHash = Hash.new @children = [] end |
#is_html_tag_wrapper? ⇒ Boolean
107 108 109 |
# File 'lib/active_component/base.rb', line 107 def is_html_tag_wrapper? ActiveComponent::HTML5_ELEMENTS.each_value {|category| break true if category.include?(class_name.to_sym)} == true end |
#is_root? ⇒ Boolean Also known as: isRoot?
Returns true
if the receiver is a root node. Note that orphaned children will also be reported as root nodes.
384 385 386 |
# File 'lib/active_component/base.rb', line 384 def is_root? @parent.nil? end |
#isFirstSibling? ⇒ Boolean
Returns true
if the receiver node is the first sibling at its level.
613 614 615 |
# File 'lib/active_component/base.rb', line 613 def isFirstSibling? firstSibling == self end |
#isLastSibling? ⇒ Boolean
Returns true
if the receiver node is the last sibling at its level.
640 641 642 |
# File 'lib/active_component/base.rb', line 640 def isLastSibling? lastSibling == self end |
#isLeaf? ⇒ Boolean
Returns true
if the receiver node is a ‘leaf’ - i.e., one without any children.
405 406 407 |
# File 'lib/active_component/base.rb', line 405 def isLeaf? !hasChildren? end |
#isOnlyChild? ⇒ Boolean
Returns true
if the receiver node is the only child of its parent.
As a special case, a root node will always return true
.
682 683 684 |
# File 'lib/active_component/base.rb', line 682 def isOnlyChild? isRoot? ? true : parent.children.size == 1 end |
#lastChild ⇒ Tree::TreeNode
Returns the last child of the receiver node.
Will return nil
if no children are present.
440 441 442 |
# File 'lib/active_component/base.rb', line 440 def lastChild children.last end |
#lastSibling ⇒ Tree::TreeNode
Fix the inconsistency of returning root as its last sibling, and returning a nil
array for siblings of the node.
Returns the last sibling of the receiver node. If this is the root node, then returns itself.
‘Last’ sibling is defined as follows:
- Last sibling
-
The right-most child of the receiver’s parent, which may be the receiver itself
630 631 632 |
# File 'lib/active_component/base.rb', line 630 def lastSibling isRoot? ? self : parent.children.last end |
#length ⇒ Number
This method node_name is ambiguous and may be removed. Use TreeNode#size instead.
The semantic of length is probably unclear. Should return the node depth instead to reflect the path length.
Convenience synonym for Tree::TreeNode#size.
553 554 555 |
# File 'lib/active_component/base.rb', line 553 def length size() end |
#marshal_dump ⇒ Object
Returns a marshal-dump represention of the (sub)tree rooted at the receiver node.
739 740 741 |
# File 'lib/active_component/base.rb', line 739 def marshal_dump self.collect { |node| node.createDumpRep } end |
#marshal_load(dumped_tree_array) ⇒ Object
This method probably should be a class method. It currently clobbers self and makes itself the root.
Loads a marshalled dump of a tree and returns the root node of the reconstructed tree. See the Marshal class for additional details.
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
# File 'lib/active_component/base.rb', line 755 def marshal_load(dumped_tree_array) nodes = { } for node_hash in dumped_tree_array do node_name = node_hash[:node_name] parent_node_name = node_hash[:parent] node_content = Marshal.load(node_hash[:node_content]) if parent_node_name then nodes[node_name] = current_node = Tree::TreeNode.new(node_name, node_content) nodes[parent_node_name].add current_node else # This is the root node, hence initialize self. initialize(node_name, node_content) nodes[node_name] = self # Add self to the list of nodes end end end |
#nextSibling ⇒ Tree::treeNode
Returns the next sibling for the receiver node. The ‘next’ node is defined as the node to right of the receiver node.
Will return nil
if no subsequent node is present, or if the receiver is a root node.
695 696 697 698 699 700 |
# File 'lib/active_component/base.rb', line 695 def nextSibling return nil if isRoot? if myidx = parent.children.index(self) parent.children.at(myidx + 1) end end |
#nodeDepth ⇒ Number Also known as: level
Returns depth of the receiver node in its tree. Depth of a node is defined as:
- Depth
-
Length of the node’s path to its root. Depth of a root node is zero.
‘level’ is an alias for this method.
853 854 855 856 |
# File 'lib/active_component/base.rb', line 853 def nodeDepth return 0 if isRoot? 1 + parent.nodeDepth end |
#nodeHeight ⇒ Number
Returns height of the (sub)tree from the receiver node. Height of a node is defined as:
- Height
-
Length of the longest downward path to a leaf from the node.
-
Height from a root node is height of the entire tree.
-
The height of a leaf node is zero.
841 842 843 844 |
# File 'lib/active_component/base.rb', line 841 def nodeHeight return 0 if isLeaf? 1 + @children.collect { |child| child.nodeHeight }.max end |
#out_degree ⇒ Number
Returns the outgoing edge-count of the receiver node.
Out-degree is defined as:
- Out-degree
-
The number of edges leaving the node (zero for leafs)
918 919 920 |
# File 'lib/active_component/base.rb', line 918 def out_degree isLeaf? ? 0 : children.size end |
#parentage ⇒ Array?
Returns an array of ancestors of the receiver node in reversed order (the first element is the immediate parent of the receiver).
Returns nil
if the receiver is a root node.
248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/active_component/base.rb', line 248 def parentage return nil if isRoot? parentageArray = [] prevParent = self.parent while (prevParent) parentageArray << prevParent prevParent = prevParent.parent end parentageArray end |
#preordered_each {|child| ... } ⇒ Object
Traverses the (sub)tree rooted at the receiver node in pre-ordered sequence. This is a synonym of Tree::TreeNode#each.
467 468 469 |
# File 'lib/active_component/base.rb', line 467 def preordered_each(&block) # :yields: node each(&block) end |
#prepend(child) ⇒ Object
195 196 197 |
# File 'lib/active_component/base.rb', line 195 def prepend(child) add(child, true) end |
#previousSibling ⇒ Tree::treeNode
Returns the previous sibling of the receiver node. ‘Previous’ node is defined to be the node to left of the receiver node.
Will return nil
if no predecessor node is present, or if the receiver is a root node.
711 712 713 714 715 716 |
# File 'lib/active_component/base.rb', line 711 def previousSibling return nil if isRoot? if myidx = parent.children.index(self) parent.children.at(myidx - 1) if myidx > 0 end end |
#printTree(level = 0) ⇒ Object
Pretty prints the (sub)tree rooted at the receiver node.
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/active_component/base.rb', line 560 def printTree(level = 0) if isRoot? print "*" else print "|" unless parent.isLastSibling? print(' ' * (level - 1) * 4) print(isLastSibling? ? "+" : "|") print "---" print(hasChildren? ? "+" : ">") end puts " #{node_name}" children { |child| child.printTree(level + 1)} end |
#remove!(child) ⇒ Tree::TreeNode
Removes the specified child node from the receiver node.
This method can also be used for pruning a sub-tree, in cases where the removed child node is the root of the sub-tree to be pruned.
The removed child node is orphaned but accessible if an alternate reference exists. If accessible via an alternate reference, the removed child will report itself as a root node for its sub-tree.
330 331 332 333 334 335 336 337 |
# File 'lib/active_component/base.rb', line 330 def remove!(child) return nil unless child @childrenHash.delete(child.node_name) @children.delete(child) child.setAsRoot! child end |
#removeAll! ⇒ Tree::TreeNode
Removes all children from the receiver node. If an indepedent reference exists to the child nodes, then these child nodes report themselves as roots after this operation.
357 358 359 360 361 362 363 364 |
# File 'lib/active_component/base.rb', line 357 def removeAll! for child in @children child.setAsRoot! end @childrenHash.clear @children.clear self end |
#removeFromParent! ⇒ Tree:TreeNode
Removes the receiver node from its parent. The reciever node becomes the new root for its subtree.
If this is the root node, then does nothing.
346 347 348 |
# File 'lib/active_component/base.rb', line 346 def removeFromParent! @parent.remove!(self) unless isRoot? end |
#root ⇒ Tree::TreeNode
We should perhaps return nil as root’s root.
Returns root node for the (sub)tree to which the receiver node belongs.
Note that a root node’s root is itself (beware of any loop construct that may become infinite!)
584 585 586 587 588 |
# File 'lib/active_component/base.rb', line 584 def root root = self root = root.parent while !root.isRoot? root end |
#siblings {|sibling| ... } ⇒ Array<Tree::TreeNode>
Fix the inconsistency of returning root as its own first/last sibling, and returning a nil
array for siblings of the same root node.
Also fix the inconsistency of returning nil
for a root node, and an empty array for nodes which have no siblings.
Returns an array of siblings for the receiver node. The receiver node is excluded.
If a block is provided, yields each of the sibling nodes to the block. The root always has nil
siblings.
661 662 663 664 665 666 667 668 669 670 671 672 673 |
# File 'lib/active_component/base.rb', line 661 def siblings return nil if is_root? if block_given? for sibling in parent.children yield sibling if sibling != self end else siblings = [] parent.children {|my_sibling| siblings << my_sibling if my_sibling != self} siblings end end |
#size ⇒ Number
Returns the total number of nodes in this (sub)tree, including the receiver node.
Size of the tree is defined as:
- Size
-
Total number nodes in the subtree including the receiver node.
540 541 542 |
# File 'lib/active_component/base.rb', line 540 def size @children.inject(1) {|sum, node| sum + node.size} end |
#to_html ⇒ Object
99 100 101 |
# File 'lib/active_component/base.rb', line 99 def to_html raise NotImplementedError, "to_html has to be implemented for every component that inherits from ActiveComponent::Base" end |
#to_json(*a) ⇒ Object
Creates a JSON representation of this node including all it’s children. This requires the JSON gem to be available, or else the operation fails with a warning message.
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
# File 'lib/active_component/base.rb', line 784 def to_json(*a) begin require 'json' json_hash = { "node_name" => node_name, "node_content" => node_content, JSON.create_id => self.class.node_name } if hasChildren? json_hash["children"] = children end return json_hash.to_json rescue LoadError => e warn "The JSON gem couldn't be loaded. Due to this we cannot serialize the tree to a JSON representation" end end |
#to_s ⇒ Object
103 104 105 |
# File 'lib/active_component/base.rb', line 103 def to_s to_html end |