2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include <DOM/DOMTreeWalker.h>
23 #include <DOM/DOMNodeFilter.h>
24 #include <DOM/DOMNode.h>
27 @implementation NGDOMTreeWalker
29 - (id)initWithRootNode:(id)_rootNode
30 whatToShow:(unsigned long)_whatToShow
32 expandEntityReferences:(BOOL)_flag
34 NSAssert(_rootNode, @"missing root-node !");
36 if ((self = [super init])) {
37 self->root = [_rootNode retain];
38 self->whatToShow = _whatToShow;
39 self->filter = [_filter retain];
40 self->expandEntityReferences = _flag;
42 [self setCurrentNode:_rootNode];
48 [self->visibleChildren release];
49 [self->currentNode release];
51 [self->filter release];
60 - (unsigned long)whatToShow {
61 return self->whatToShow;
66 - (BOOL)expandEntityReferences {
67 return self->expandEntityReferences;
70 - (void)setCurrentNode:(id)_node {
71 if (_node == self->currentNode)
75 ASSIGN(self->currentNode, _node);
77 /* clear state caches */
78 [self->visibleChildren release]; self->visibleChildren = nil;
81 return self->currentNode;
86 - (BOOL)_shouldShowNode:(id)_node {
87 if (self->whatToShow == DOM_SHOW_ALL)
90 switch([_node nodeType]) {
91 case DOM_ATTRIBUTE_NODE:
92 return (self->whatToShow & DOM_SHOW_ATTRIBUTE) != 0 ? YES : NO;
93 case DOM_CDATA_SECTION_NODE:
94 return (self->whatToShow & DOM_SHOW_CDATA_SECTION) != 0 ? YES : NO;
95 case DOM_COMMENT_NODE:
96 return (self->whatToShow & DOM_SHOW_COMMENT) != 0 ? YES : NO;
97 case DOM_DOCUMENT_NODE:
98 return (self->whatToShow & DOM_SHOW_DOCUMENT) != 0 ? YES : NO;
99 case DOM_DOCUMENT_FRAGMENT_NODE:
100 return (self->whatToShow & DOM_SHOW_DOCUMENT_FRAGMENT) != 0 ? YES : NO;
101 case DOM_ELEMENT_NODE:
102 return (self->whatToShow & DOM_SHOW_ELEMENT) != 0 ? YES : NO;
103 case DOM_PROCESSING_INSTRUCTION_NODE:
104 return (self->whatToShow & DOM_SHOW_PROCESSING_INSTRUCTION) != 0 ? YES:NO;
106 return (self->whatToShow & DOM_SHOW_TEXT) != 0 ? YES : NO;
107 case DOM_DOCUMENT_TYPE_NODE:
108 return (self->whatToShow & DOM_SHOW_DOCUMENT_TYPE) != 0 ? YES : NO;
109 case DOM_ENTITY_NODE:
110 return (self->whatToShow & DOM_SHOW_ENTITY) != 0 ? YES : NO;
111 case DOM_ENTITY_REFERENCE_NODE:
112 return (self->whatToShow & DOM_SHOW_ENTITY_REFERENCE) != 0 ? YES : NO;
113 case DOM_NOTATION_NODE:
114 return (self->whatToShow & DOM_SHOW_NOTATION) != 0 ? YES : NO;
120 - (BOOL)_isVisibleNode:(id)_node {
121 if (![self _shouldShowNode:_node])
124 return [self->filter acceptNode:_node] == DOM_FILTER_ACCEPT ? YES : NO;
127 - (unsigned short)_navTypeOfNode:(id)_node {
128 if (![self _shouldShowNode:_node])
129 return DOM_FILTER_SKIP;
131 return [self->filter acceptNode:_node] == DOM_FILTER_ACCEPT ? YES : NO;
132 return DOM_FILTER_ACCEPT;
135 - (NSArray *)_ensureVisibleChildren {
136 static NSArray *emptyArray = nil;
140 if (self->visibleChildren)
141 return self->visibleChildren;
143 children = [[self currentNode] childNodes];
145 if ((count = [children count]) > 0) {
149 ma = [[NSMutableArray alloc] initWithCapacity:(count + 1)];
151 for (i = 0; i < count; i++) {
154 childNode = [children objectAtIndex:i];
156 if ([self _isVisibleNode:childNode])
157 [ma addObject:childNode];
160 self->visibleChildren = [ma copy];
161 [ma release]; ma = nil;
164 if (emptyArray == nil) emptyArray = [[NSArray alloc] init];
165 self->visibleChildren = [emptyArray retain];
167 return self->visibleChildren;
170 - (BOOL)_hasVisibleChildren {
171 return [[self _ensureVisibleChildren] count] > 0 ? YES : NO;
173 - (id)_visibleChildren {
174 return [self _ensureVisibleChildren];
176 - (id)_firstVisibleChild {
177 NSArray *a = [self _ensureVisibleChildren];
180 return [a objectAtIndex:0];
182 - (id)_lastVisibleChild {
183 NSArray *a = [self _ensureVisibleChildren];
186 if ((count = [a count]) == 0)
188 return [a objectAtIndex:(count - 1)];
191 - (id<NSObject,DOMNode>)_visibleParentNode {
192 id<NSObject,DOMNode> node;
194 for (node = [[self currentNode] parentNode]; node; node =[node parentNode]) {
195 if ([self _isVisibleNode:node])
198 if (node == [self root])
199 /* do not step above root */
205 - (id<NSObject,DOMNode>)_nextVisibleSibling {
206 id<NSObject,DOMNode> node;
208 for (node = [(id<NSObject,DOMNode>)[self currentNode] nextSibling];
210 node = [node nextSibling]) {
211 if ([self _isVisibleNode:node])
216 - (id<NSObject,DOMNode>)_previousVisibleSibling {
217 id<NSObject,DOMNode> node;
219 for (node = [(id<NSObject,DOMNode>)[self currentNode] previousSibling];
221 node = [node previousSibling]) {
222 if ([self _isVisibleNode:node])
230 - (id<NSObject,DOMNode>)parentNode {
233 if ((parent = [self _visibleParentNode])) {
234 [self setCurrentNode:parent];
241 - (id<NSObject,DOMNode>)firstChild {
242 if ([self _hasVisibleChildren]) {
245 child = [self _firstVisibleChild];
246 [self setCurrentNode:child];
253 - (id<NSObject,DOMNode>)lastChild {
254 if ([self _hasVisibleChildren]) {
257 child = [self _lastVisibleChild];
258 [self setCurrentNode:child];
265 - (id<NSObject,DOMNode>)previousSibling {
268 if ((node = [self _previousVisibleSibling])) {
269 [self setCurrentNode:node];
276 - (id<NSObject,DOMNode>)nextSibling {
279 if ((node = [self _nextVisibleSibling])) {
280 [self setCurrentNode:node];
287 - (id<NSObject,DOMNode>)previousNode {
288 [self doesNotRecognizeSelector:_cmd];
291 - (id<NSObject,DOMNode>)nextNode {
292 [self doesNotRecognizeSelector:_cmd];
296 @end /* NGDOMTreeWalker */