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 NSUInteger 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 NSUInteger 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 NSUInteger 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 implementation 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 NSUInteger 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 NSUInteger 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 */ 165