]> err.no Git - sope/blob - sope-xml/DOM/DOMNodeWithChildren.m
fixed some comments
[sope] / sope-xml / DOM / DOMNodeWithChildren.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE 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   SOPE 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 SOPE; 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
22 #include <DOM/DOMNode.h>
23 #include "common.h"
24
25 @implementation NGDOMNodeWithChildren
26
27 - (void)dealloc {
28   [self->childNodes makeObjectsPerformSelector:
29                       @selector(_domNodeForgetParentNode:)
30                     withObject:nil];
31   
32   [self->childNodes release];
33   [super dealloc];
34 }
35
36 - (void)_ensureChildNodes {
37   if (self->childNodes == nil)
38     self->childNodes = [[NSMutableArray alloc] init];
39 }
40
41 - (BOOL)_isValidChildNode:(id)_node {
42   return YES;
43 }
44
45 /* navigation */
46
47 - (id<NSObject,DOMNodeList>)childNodes {
48   [self _ensureChildNodes];
49
50   /* casting NSMutableArray to DOMNodeList */
51   return (id<NSObject,DOMNodeList>)self->childNodes;
52 }
53 - (BOOL)hasChildNodes {
54   return [self->childNodes count] > 0 ? YES : NO;
55 }
56 - (id<NSObject,DOMNode>)firstChild {
57   return [self->childNodes count] > 0 
58     ? [self->childNodes objectAtIndex:0]
59     : nil;
60 }
61 - (id<NSObject,DOMNode>)lastChild {
62   unsigned count;
63
64   return (count = [self->childNodes count]) > 0 
65     ? [self->childNodes objectAtIndex:(count - 1)]
66     : nil;
67 }
68
69 /* modification */
70
71 - (id<NSObject,DOMNode>)removeChild:(id<NSObject,DOMNode>)_node {
72   unsigned idx;
73
74   if (self->childNodes == nil)
75     /* this node has no childnodes ! */
76     return nil;
77   
78   if ((idx = [self->childNodes indexOfObject:_node]) == NSNotFound)
79     /* given node is not a child of this node ! */
80     return nil;
81   
82   [[_node retain] autorelease];
83   [self->childNodes removeObjectAtIndex:idx];
84   [(id)_node _domNodeForgetParentNode:self];
85   
86   return _node;
87 }
88
89 - (id<NSObject,DOMNode>)appendChild:(id<NSObject,DOMNode>)_node {
90   if (_node == nil)
91     /* adding a 'nil' node ?? */
92     return nil;
93   
94   if ([_node nodeType] == DOM_DOCUMENT_FRAGMENT_NODE) {
95     id             fragNodes;
96     unsigned       i, count;
97     NSMutableArray *cache;
98     
99     fragNodes = [_node childNodes];
100     
101     if ((count = [fragNodes count]) == 0)
102       /* no nodes to add */
103       return nil;
104
105     /* 
106        copy to cache, since 'childNodes' result is 'live' and 
107        appendChild modifies the tree 
108     */
109     cache = [NSMutableArray arrayWithCapacity:count];
110     for (i = 0; i < count; i++)
111       [cache addObject:[fragNodes objectAtIndex:i]];
112     
113     /* append nodes (in reverse order [array implemention is assumed]) .. */
114     for (i = count = [cache count]; i > 0; i--)
115       [self appendChild:[cache objectAtIndex:(i - 1)]];
116   }
117   else {
118     id oldParent;
119     
120     if ((oldParent = [_node parentNode]))
121       [oldParent removeChild:_node];
122     
123     [self _ensureChildNodes];
124     
125     [self->childNodes addObject:_node];
126     [(id)_node _domNodeRegisterParentNode:self];
127   }
128   
129   /* return the node 'added' */
130   return _node;
131 }
132
133 /* sibling navigation */
134
135 - (id)_domNodeBeforeNode:(id)_node {
136   unsigned idx;
137   
138   if ((idx = [self->childNodes indexOfObject:_node]) == NSNotFound)
139     /* given node isn't a child of this node */
140     return nil;
141   if (idx == 0)
142     /* given node is the first child */
143     return nil;
144   
145   return [self->childNodes objectAtIndex:(idx - 1)];
146 }
147 - (id)_domNodeAfterNode:(id)_node {
148   unsigned idx, count;
149
150   if ((count = [self->childNodes count]) == 0)
151     /* this node has no children at all .. */
152     return nil;
153   
154   if ((idx = [self->childNodes indexOfObject:_node]) == NSNotFound)
155     /* given node isn't a child of this node */
156     return nil;
157   if (idx == (count - 1))
158     /* given node is the last child */
159     return nil;
160   
161   return [self->childNodes objectAtIndex:(idx + 1)];
162 }
163
164 @end /* NGDOMNodeWithChildren */