dom2_traversalimpl.cpp
00001
00024 #include "dom/dom_exception.h"
00025 #include "xml/dom_docimpl.h"
00026
00027 using namespace DOM;
00028
00029 NodeIteratorImpl::NodeIteratorImpl(NodeImpl *_root, unsigned long _whatToShow,
00030 NodeFilter _filter, bool _entityReferenceExpansion)
00031 {
00032 m_root = _root;
00033 m_whatToShow = _whatToShow;
00034 m_filter = _filter;
00035 m_expandEntityReferences = _entityReferenceExpansion;
00036
00037 m_referenceNode = _root;
00038 m_inFront = false;
00039
00040 m_doc = m_root->getDocument();
00041 m_doc->attachNodeIterator(this);
00042 m_doc->ref();
00043
00044 m_detached = false;
00045 }
00046
00047 NodeIteratorImpl::~NodeIteratorImpl()
00048 {
00049 m_doc->detachNodeIterator(this);
00050 m_doc->deref();
00051 }
00052
00053 NodeImpl *NodeIteratorImpl::root()
00054 {
00055 return m_root;
00056 }
00057
00058 unsigned long NodeIteratorImpl::whatToShow()
00059 {
00060 return m_whatToShow;
00061 }
00062
00063 NodeFilter NodeIteratorImpl::filter()
00064 {
00065 return m_filter;
00066 }
00067
00068 bool NodeIteratorImpl::expandEntityReferences()
00069 {
00070 return m_expandEntityReferences;
00071 }
00072
00073 NodeImpl *NodeIteratorImpl::nextNode( int &exceptioncode )
00074 {
00075 if (m_detached) {
00076 exceptioncode = DOMException::INVALID_STATE_ERR;
00077 return 0;
00078 }
00079
00080 if (!m_referenceNode) {
00081 m_inFront = true;
00082 return 0;
00083 }
00084
00085 if (!m_inFront) {
00086 m_inFront = true;
00087 if (isAccepted(m_referenceNode) == NodeFilter::FILTER_ACCEPT)
00088 return m_referenceNode;
00089 }
00090
00091 NodeImpl *_tempCurrent = getNextNode(m_referenceNode);
00092 while( _tempCurrent ) {
00093 m_referenceNode = _tempCurrent;
00094 if(isAccepted(_tempCurrent) == NodeFilter::FILTER_ACCEPT)
00095 return m_referenceNode;
00096 _tempCurrent = getNextNode(_tempCurrent);
00097 }
00098
00099 return 0;
00100 }
00101
00102 NodeImpl *NodeIteratorImpl::getNextNode(NodeImpl *n)
00103 {
00104
00105
00106
00107
00108
00109
00110 if( !n )
00111 return 0;
00112
00113 if( n->hasChildNodes() )
00114 return n->firstChild();
00115
00116 if( n->nextSibling() )
00117 return n->nextSibling();
00118
00119 if( m_root == n)
00120 return 0;
00121
00122 NodeImpl *parent = n->parentNode();
00123 while( parent )
00124 {
00125 n = parent->nextSibling();
00126 if( n )
00127 return n;
00128
00129 if( m_root == parent )
00130 return 0;
00131
00132 parent = parent->parentNode();
00133 }
00134 return 0;
00135 }
00136
00137 NodeImpl *NodeIteratorImpl::previousNode( int &exceptioncode )
00138 {
00139 if (m_detached) {
00140 exceptioncode = DOMException::INVALID_STATE_ERR;
00141 return 0;
00142 }
00143
00144 if (!m_referenceNode) {
00145 m_inFront = false;
00146 return 0;
00147 }
00148
00149 if (m_inFront) {
00150 m_inFront = false;
00151 if (isAccepted(m_referenceNode) == NodeFilter::FILTER_ACCEPT)
00152 return m_referenceNode;
00153 }
00154
00155 NodeImpl *_tempCurrent = getPreviousNode(m_referenceNode);
00156 while( _tempCurrent ) {
00157 m_referenceNode = _tempCurrent;
00158 if(isAccepted(_tempCurrent) == NodeFilter::FILTER_ACCEPT)
00159 return m_referenceNode;
00160 _tempCurrent = getPreviousNode(_tempCurrent);
00161 }
00162
00163 return 0;
00164 }
00165
00166 NodeImpl *NodeIteratorImpl::getPreviousNode(NodeImpl *n)
00167 {
00168
00169
00170
00171
00172 NodeImpl *_tempCurrent;
00173
00174 if( !n )
00175 return 0;
00176
00177 _tempCurrent = n->previousSibling();
00178 if( _tempCurrent )
00179 {
00180 if( _tempCurrent->lastChild() )
00181 {
00182 while( _tempCurrent->lastChild() )
00183 _tempCurrent = _tempCurrent->lastChild();
00184 return _tempCurrent;
00185 }
00186 else
00187 return _tempCurrent;
00188 }
00189
00190
00191 if(n == m_root)
00192 return 0;
00193
00194 return n->parentNode();
00195
00196
00197 }
00198
00199 void NodeIteratorImpl::detach(int &)
00200 {
00201 m_doc->detachNodeIterator(this);
00202 m_detached = true;
00203 }
00204
00205
00206 void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *removed)
00207 {
00208
00209 if (removed == m_root)
00210 return;
00211
00212 NodeImpl *maybeRoot = removed->parentNode();
00213 while (maybeRoot && maybeRoot != m_root)
00214 maybeRoot = maybeRoot->parentNode();
00215 if (!maybeRoot)
00216 return;
00217
00218
00219 NodeImpl *_tempDeleted = m_referenceNode;
00220 while( _tempDeleted && _tempDeleted != removed)
00221 _tempDeleted = _tempDeleted->parentNode();
00222
00223 if( !_tempDeleted )
00224 return;
00225
00226 if( !m_inFront)
00227 {
00228 NodeImpl *_next = getNextNode(_tempDeleted);
00229 if( _next )
00230 m_referenceNode = _next;
00231 else
00232 {
00233
00234 m_inFront = true;
00235 m_referenceNode = getPreviousNode(_tempDeleted);
00236 }
00237 }
00238 else {
00239 NodeImpl *_prev = getPreviousNode(_tempDeleted);
00240 if ( _prev )
00241 m_referenceNode = _prev;
00242 else
00243 {
00244
00245 m_inFront = false;
00246 m_referenceNode = getNextNode(_tempDeleted);
00247 }
00248 }
00249
00250 }
00251
00252 short NodeIteratorImpl::isAccepted(NodeImpl *n)
00253 {
00254
00255 if( ( ( 1 << n->nodeType()-1) & m_whatToShow) != 0 )
00256 {
00257 if(!m_filter.isNull())
00258 return m_filter.acceptNode(n);
00259 else
00260 return NodeFilter::FILTER_ACCEPT;
00261 }
00262 return NodeFilter::FILTER_SKIP;
00263 }
00264
00265
00266
00267
00268 NodeFilterImpl::NodeFilterImpl()
00269 {
00270 m_customNodeFilter = 0;
00271 }
00272
00273 NodeFilterImpl::~NodeFilterImpl()
00274 {
00275 if (m_customNodeFilter)
00276 m_customNodeFilter->deref();
00277 }
00278
00279 short NodeFilterImpl::acceptNode(const Node &n)
00280 {
00281 if (m_customNodeFilter)
00282 return m_customNodeFilter->acceptNode(n);
00283 else
00284 return NodeFilter::FILTER_ACCEPT;
00285 }
00286
00287 void NodeFilterImpl::setCustomNodeFilter(CustomNodeFilter *custom)
00288 {
00289 m_customNodeFilter = custom;
00290 if (m_customNodeFilter)
00291 m_customNodeFilter->ref();
00292 }
00293
00294 CustomNodeFilter *NodeFilterImpl::customNodeFilter()
00295 {
00296 return m_customNodeFilter;
00297 }
00298
00299
00300
00301 TreeWalkerImpl::TreeWalkerImpl()
00302 {
00303 m_filter = 0;
00304 m_whatToShow = 0x0000FFFF;
00305 m_expandEntityReferences = true;
00306 }
00307
00308 TreeWalkerImpl::TreeWalkerImpl(const TreeWalkerImpl &other)
00309 : khtml::Shared<TreeWalkerImpl>()
00310 {
00311 m_expandEntityReferences = other.m_expandEntityReferences;
00312 m_filter = other.m_filter;
00313 m_whatToShow = other.m_whatToShow;
00314 m_currentNode = other.m_currentNode;
00315 m_rootNode = other.m_rootNode;
00316 }
00317
00318 TreeWalkerImpl::TreeWalkerImpl(Node n, NodeFilter *f)
00319 {
00320 m_currentNode = n;
00321 m_rootNode = n;
00322 m_whatToShow = 0x0000FFFF;
00323 m_filter = f;
00324 }
00325
00326 TreeWalkerImpl::TreeWalkerImpl(Node n, long _whatToShow, NodeFilter *f)
00327 {
00328 m_currentNode = n;
00329 m_rootNode = n;
00330 m_whatToShow = _whatToShow;
00331 m_filter = f;
00332 }
00333
00334 TreeWalkerImpl &TreeWalkerImpl::operator = (const TreeWalkerImpl &other)
00335 {
00336 m_expandEntityReferences = other.m_expandEntityReferences;
00337 m_filter = other.m_filter;
00338 m_whatToShow = other.m_whatToShow;
00339 m_currentNode = other.m_currentNode;
00340 return *this;
00341 }
00342
00343 TreeWalkerImpl::~TreeWalkerImpl()
00344 {
00345 if(m_filter)
00346 {
00347 delete m_filter;
00348 m_filter = 0;
00349 }
00350 }
00351
00352
00353
00354
00355
00356 Node TreeWalkerImpl::getRoot()
00357 {
00358
00359 return 0;
00360 }
00361
00362 unsigned long TreeWalkerImpl::getWhatToShow()
00363 {
00364
00365 return 0;
00366 }
00367
00368 NodeFilter TreeWalkerImpl::getFilter()
00369 {
00370
00371 return 0;
00372 }
00373
00374 bool TreeWalkerImpl::getExpandEntityReferences()
00375 {
00376
00377 return 0;
00378 }
00379
00380 Node TreeWalkerImpl::getCurrentNode()
00381 {
00382 return m_currentNode;
00383 }
00384
00385 void TreeWalkerImpl::setWhatToShow(long _whatToShow)
00386 {
00387
00388 m_whatToShow = _whatToShow;
00389 }
00390
00391 void TreeWalkerImpl::setFilter(NodeFilter *_filter)
00392 {
00393
00394 if(_filter)
00395 m_filter = _filter;
00396 }
00397
00398 void TreeWalkerImpl::setExpandEntityReferences(bool value)
00399 {
00400 m_expandEntityReferences = value;
00401 }
00402
00403 void TreeWalkerImpl::setCurrentNode( const Node n )
00404 {
00405 if( !n.isNull() )
00406 {
00407 m_rootNode = n;
00408 m_currentNode = n;
00409 }
00410
00411
00412 }
00413
00414 Node TreeWalkerImpl::parentNode( )
00415 {
00416 Node n = getParentNode(m_currentNode);
00417 if( !n.isNull() )
00418 m_currentNode = n;
00419 return n;
00420 }
00421
00422
00423 Node TreeWalkerImpl::firstChild( )
00424 {
00425 Node n = getFirstChild(m_currentNode);
00426 if( !n.isNull() )
00427 m_currentNode = n;
00428 return n;
00429 }
00430
00431
00432 Node TreeWalkerImpl::lastChild( )
00433 {
00434 Node n = getLastChild(m_currentNode);
00435 if( !n.isNull() )
00436 m_currentNode = n;
00437 return n;
00438 }
00439
00440 Node TreeWalkerImpl::previousSibling( )
00441 {
00442 Node n = getPreviousSibling(m_currentNode);
00443 if( !n.isNull() )
00444 m_currentNode = n;
00445 return n;
00446 }
00447
00448 Node TreeWalkerImpl::nextSibling( )
00449 {
00450 Node n = getNextSibling(m_currentNode);
00451 if( !n.isNull() )
00452 m_currentNode = n;
00453 return n;
00454 }
00455
00456 Node TreeWalkerImpl::previousNode( )
00457 {
00458
00459
00460
00461
00462
00463 Node n = getPreviousSibling(m_currentNode);
00464 if( n.isNull() )
00465 {
00466 n = getParentNode(m_currentNode);
00467 if( !n.isNull() )
00468 {
00469 m_currentNode = n;
00470 return m_currentNode;
00471 }
00472 else
00473 return Node();
00474 }
00475
00476 Node child = getLastChild(n);
00477 if( !child.isNull() )
00478 {
00479 m_currentNode = child;
00480 return m_currentNode;
00481 }
00482 else
00483 {
00484 m_currentNode = n;
00485 return m_currentNode;
00486 }
00487 return Node();
00488 }
00489
00490 Node TreeWalkerImpl::nextNode( )
00491 {
00492
00493
00494
00495
00496
00497
00498 Node n = getFirstChild(m_currentNode);
00499 if( !n.isNull() )
00500 {
00501 m_currentNode = n;
00502 return n;
00503 }
00504
00505 n = getNextSibling(m_currentNode);
00506 if( !n.isNull() )
00507 {
00508 m_currentNode = n;
00509 return m_currentNode;
00510 }
00511 Node parent = getParentNode(m_currentNode);
00512 while( !parent.isNull() )
00513 {
00514 n = getNextSibling(parent);
00515 if( !n.isNull() )
00516 {
00517 m_currentNode = n;
00518 return m_currentNode;
00519 }
00520 else
00521 parent = getParentNode(parent);
00522 }
00523 return Node();
00524 }
00525
00526 short TreeWalkerImpl::isAccepted(Node n)
00527 {
00528
00529 if( ( ( 1 << n.nodeType()-1 ) & m_whatToShow) != 0 )
00530 {
00531 if(m_filter)
00532 return m_filter->acceptNode(n);
00533 else
00534 return NodeFilter::FILTER_ACCEPT;
00535 }
00536 return NodeFilter::FILTER_SKIP;
00537 }
00538
00539 Node TreeWalkerImpl::getParentNode(Node n)
00540 {
00541 short _result = NodeFilter::FILTER_ACCEPT;
00542
00543 if( n == m_rootNode )
00544 return Node();
00545
00546 Node _tempCurrent = n.parentNode();
00547
00548 if( _tempCurrent.isNull() )
00549 return Node();
00550
00551 _result = isAccepted(_tempCurrent );
00552 if(_result == NodeFilter::FILTER_ACCEPT)
00553 return _tempCurrent;
00554
00555 return getParentNode(_tempCurrent);
00556 }
00557
00558 Node TreeWalkerImpl::getFirstChild(Node n)
00559 {
00560 short _result;
00561
00562 if( n.isNull() || n.firstChild().isNull() )
00563 return Node();
00564 n = n.firstChild();
00565
00566 _result = isAccepted(n);
00567
00568 switch(_result)
00569 {
00570 case NodeFilter::FILTER_ACCEPT:
00571 return n;
00572 break;
00573 case NodeFilter::FILTER_SKIP:
00574 if( n.hasChildNodes() )
00575 return getFirstChild(n);
00576 else
00577 return getNextSibling(n);
00578 break;
00579
00580 case NodeFilter::FILTER_REJECT:
00581 return getNextSibling(n);
00582 break;
00583 }
00584 return Node();
00585 }
00586
00587 Node TreeWalkerImpl::getLastChild(Node n)
00588 {
00589 short _result;
00590
00591 if( n.isNull() || n.lastChild().isNull() )
00592 return Node();
00593 n = n.lastChild();
00594 _result = isAccepted(n);
00595 switch(_result)
00596 {
00597 case NodeFilter::FILTER_ACCEPT:
00598 return n;
00599 break;
00600
00601 case NodeFilter::FILTER_SKIP:
00602 if( n.hasChildNodes() )
00603 return getLastChild(n);
00604 else
00605 return getPreviousSibling(n);
00606 break;
00607
00608 case NodeFilter::FILTER_REJECT:
00609 return getPreviousSibling(n);
00610 break;
00611 }
00612 return Node();
00613 }
00614
00615 Node TreeWalkerImpl::getPreviousSibling(Node n)
00616 {
00617 short _result;
00618 Node _tempCurrent;
00619
00620 if( n.isNull() )
00621 return Node();
00622
00623 _tempCurrent = n.previousSibling();
00624 if( !_tempCurrent.isNull() )
00625 {
00626 _result = isAccepted(_tempCurrent);
00627 switch(_result)
00628 {
00629 case NodeFilter::FILTER_ACCEPT:
00630 return _tempCurrent;
00631 break;
00632
00633 case NodeFilter::FILTER_SKIP:
00634 {
00635 Node nskip = getLastChild(_tempCurrent);
00636 if( !nskip.isNull() )
00637 return nskip;
00638 return getPreviousSibling(_tempCurrent);
00639 break;
00640 }
00641
00642 case NodeFilter::FILTER_REJECT:
00643 return getPreviousSibling(_tempCurrent);
00644 break;
00645 }
00646 }
00647
00648 else
00649 {
00650 _tempCurrent = _tempCurrent.parentNode();
00651 if(_tempCurrent.isNull() || _tempCurrent == m_rootNode)
00652 return Node();
00653 _result = isAccepted(_tempCurrent);
00654 if(_result == NodeFilter::FILTER_SKIP)
00655 return getPreviousSibling(_tempCurrent);
00656
00657 return Node();
00658
00659 }
00660 return Node();
00661 }
00662
00663 Node TreeWalkerImpl::getNextSibling(Node n)
00664 {
00665 Node _tempCurrent;
00666 short _result;
00667
00668 if( n.isNull() || _tempCurrent == m_rootNode)
00669 return Node();
00670
00671 _tempCurrent = n.nextSibling();
00672 if( !_tempCurrent.isNull() )
00673 {
00674 _result = isAccepted(_tempCurrent);
00675 switch(_result)
00676 {
00677 case NodeFilter::FILTER_ACCEPT:
00678 return _tempCurrent;
00679 break;
00680
00681 case NodeFilter::FILTER_SKIP:
00682 {
00683 Node nskip = getFirstChild(_tempCurrent);
00684 if( !nskip.isNull() )
00685 return nskip;
00686 return getNextSibling(_tempCurrent);
00687 break;
00688 }
00689
00690 case NodeFilter::FILTER_REJECT:
00691 return getNextSibling(_tempCurrent);
00692 break;
00693 }
00694 }
00695 else
00696 {
00697 _tempCurrent = _tempCurrent.parentNode();
00698 if(_tempCurrent.isNull() || _tempCurrent == m_rootNode)
00699 return Node();
00700 _result = isAccepted(_tempCurrent);
00701 if(_result == NodeFilter::FILTER_SKIP)
00702 return getNextSibling(_tempCurrent);
00703
00704 return Node();
00705 }
00706 return Node();
00707 }
00708
This file is part of the documentation for kdelibs Version 3.1.0.