4 # A parent has children, and has methods for accessing them. The Parent
5 # class is never encountered except as the superclass for some other
11 # @param parent if supplied, will be set as the parent of this object
12 def initialize parent=nil
18 #puts "PARENT GOTS #{size} CHILDREN"
21 #puts "PARENT NOW GOTS #{size} CHILDREN"
30 @children.unshift object
35 @children.delete_if {|c| c.equal?(object) and found = true }
36 object.parent = nil if found
40 @children.each(&block)
43 def delete_if( &block )
44 @children.delete_if(&block)
47 def delete_at( index )
48 @children.delete_at index
51 def each_index( &block )
52 @children.each_index(&block)
55 # Fetches a child at a given index
56 # @param index the Integer index of the child to fetch
61 alias :each_child :each
65 # Set an index entry. See Array.[]=
66 # @param index the index of the element to set
67 # @param opt either the object to set, or an Integer length
68 # @param child if opt is an Integer, this is the child to set
69 # @return the parent (self)
71 args[-1].parent = self
72 @children[*args[0..-2]] = args[-1]
75 # Inserts an child before another child
76 # @param child1 this is either an xpath or an Element. If an Element,
77 # child2 will be inserted before child1 in the child list of the parent.
78 # If an xpath, child2 will be inserted before the first child to match
80 # @param child2 the child to insert
81 # @return the parent (self)
82 def insert_before( child1, child2 )
83 if child1.kind_of? String
84 child1 = XPath.first( self, child1 )
85 child1.parent.insert_before child1, child2
88 child2.parent.delete(child2) if child2.parent
89 @children[ind,0] = child2
95 # Inserts an child after another child
96 # @param child1 this is either an xpath or an Element. If an Element,
97 # child2 will be inserted after child1 in the child list of the parent.
98 # If an xpath, child2 will be inserted after the first child to match
100 # @param child2 the child to insert
101 # @return the parent (self)
102 def insert_after( child1, child2 )
103 if child1.kind_of? String
104 child1 = XPath.first( self, child1 )
105 child1.parent.insert_after child1, child2
107 ind = index(child1)+1
108 child2.parent.delete(child2) if child2.parent
109 @children[ind,0] = child2
119 # Fetches the index of a given child
120 # @param child the child to get the index of
121 # @return the index of the child, or nil if the object is not a child
125 @children.find { |i| count += 1 ; i.hash == child.hash }
129 # @return the number of children of this parent
136 # Replaces one child with another, making sure the nodelist is correct
137 # @param to_replace the child to replace (must be a Child)
138 # @param replacement the child to insert into the nodelist (must be a
140 def replace_child( to_replace, replacement )
141 @children.map! {|c| c.equal?( to_replace ) ? replacement : c }
142 to_replace.parent = nil
143 replacement.parent = self
146 # Deeply clones this object. This creates a complete duplicate of this
147 # Parent, including all descendants.
151 if child.kind_of? Parent
152 cl << child.deep_clone
160 alias :children :to_a