]> err.no Git - sope/blob - sope-xml/DOM/DOMNodeWithChildren.m
added svn:keywords and svn:ignore where appropriate. removed CVS artifacts.
[sope] / sope-xml / DOM / DOMNodeWithChildren.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include <DOM/DOMNode.h>
24 #include "common.h"
25
26 @implementation DOMNodeWithChildren
27
28 - (void)dealloc {
29   [self->childNodes makeObjectsPerformSelector:
30                       @selector(_domNodeForgetParentNode:)
31                     withObject:nil];
32   
33   [self->childNodes release];
34   [super dealloc];
35 }
36
37 - (void)_ensureChildNodes {
38   if (self->childNodes == nil)
39     self->childNodes = [[NSMutableArray alloc] init];
40 }
41
42 - (BOOL)_isValidChildNode:(id)_node {
43   return YES;
44 }
45
46 /* navigation */
47
48 - (id)childNodes {
49   [self _ensureChildNodes];
50   return self->childNodes;
51 }
52 - (BOOL)hasChildNodes {
53   return [self->childNodes count] > 0 ? YES : NO;
54 }
55 - (id)firstChild {
56   return [self->childNodes count] > 0 
57     ? [self->childNodes objectAtIndex:0]
58     : nil;
59 }
60 - (id)lastChild {
61   unsigned count;
62
63   return (count = [self->childNodes count]) > 0 
64     ? [self->childNodes objectAtIndex:(count - 1)]
65     : nil;
66 }
67
68 /* modification */
69
70 - (id)removeChild:(id)_node {
71   unsigned idx;
72
73   if (self->childNodes == nil)
74     /* this node has no childnodes ! */
75     return nil;
76   
77   if ((idx = [self->childNodes indexOfObject:_node]) == NSNotFound)
78     /* given node is not a child of this node ! */
79     return nil;
80   
81   [[_node retain] autorelease];
82   [self->childNodes removeObjectAtIndex:idx];
83   [_node _domNodeForgetParentNode:self];
84   
85   return _node;
86 }
87
88 - (id)appendChild:(id)_node {
89   if (_node == nil)
90     /* adding a 'nil' node ?? */
91     return nil;
92   
93   if ([_node nodeType] == DOM_DOCUMENT_FRAGMENT_NODE) {
94     id             fragNodes;
95     unsigned       i, count;
96     NSMutableArray *cache;
97     
98     fragNodes = [_node childNodes];
99     
100     if ((count = [fragNodes count]) == 0)
101       /* no nodes to add */
102       return nil;
103
104     /* 
105        copy to cache, since 'childNodes' result is 'live' and 
106        appendChild modifies the tree 
107     */
108     cache = [NSMutableArray arrayWithCapacity:count];
109     for (i = 0; i < count; i++)
110       [cache addObject:[fragNodes objectAtIndex:i]];
111     
112     /* append nodes (in reverse order [array implemention is assumed]) .. */
113     for (i = count = [cache count]; i > 0; i--)
114       [self appendChild:[cache objectAtIndex:(i - 1)]];
115   }
116   else {
117     id oldParent;
118     
119     if ((oldParent = [_node parentNode]))
120       [oldParent removeChild:_node];
121     
122     [self _ensureChildNodes];
123     
124     [self->childNodes addObject:_node];
125     [_node _domNodeRegisterParentNode:self];
126   }
127   
128   /* return the node 'added' */
129   return _node;
130 }
131
132 /* sibling navigation */
133
134 - (id)_domNodeBeforeNode:(id)_node {
135   unsigned idx;
136   
137   if ((idx = [self->childNodes indexOfObject:_node]) == NSNotFound)
138     /* given node isn't a child of this node */
139     return nil;
140   if (idx == 0)
141     /* given node is the first child */
142     return nil;
143   
144   return [self->childNodes objectAtIndex:(idx - 1)];
145 }
146 - (id)_domNodeAfterNode:(id)_node {
147   unsigned idx, count;
148
149   if ((count = [self->childNodes count]) == 0)
150     /* this node has no children at all .. */
151     return nil;
152   
153   if ((idx = [self->childNodes indexOfObject:_node]) == NSNotFound)
154     /* given node isn't a child of this node */
155     return nil;
156   if (idx == (count - 1))
157     /* given node is the last child */
158     return nil;
159   
160   return [self->childNodes objectAtIndex:(idx + 1)];
161 }
162
163 @end /* DOMNodeWithChildren */