# khtml Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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   /*  1. my first child
    00105    *  2. my next sibling
    00106    *  3. my parents sibling, or their parents sibling (loop)
    00107    *  4. not found
    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 /* 1. my previous sibling.lastchild
    00169  * 2. my previous sibling
    00170  * 3. my parent
    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 &/*exceptioncode*/)
    00200 {
    00201     m_doc->detachNodeIterator(this);
    00202     m_detached = true;
    00203 }
    00204
    00205
    00206 void NodeIteratorImpl::notifyBeforeNodeRemoval(NodeImpl *removed)
    00207 {
    00208     // make sure the deleted node is with the root (but not the root itself)
    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     // did I get deleted, or one of my parents?
    00219     NodeImpl *_tempDeleted = m_referenceNode;
    00220     while( _tempDeleted && _tempDeleted != removed)
    00221         _tempDeleted = _tempDeleted->parentNode();
    00222
    00223     if( !_tempDeleted )  // someone that didn't consern me got deleted
    00224         return;
    00225
    00226     if( !m_inFront)
    00227     {
    00228         NodeImpl *_next = getNextNode(_tempDeleted);
    00229         if( _next )
    00230             m_referenceNode = _next;
    00231         else
    00232         {
    00233             // deleted node was at end of list
    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             // deleted node was at start of list
    00245             m_inFront = false;
    00246             m_referenceNode = getNextNode(_tempDeleted);
    00247         }
    00248     }
    00249
    00250 }
    00251
    00252 short NodeIteratorImpl::isAccepted(NodeImpl *n)
    00253 {
    00254   // if XML is implemented we have to check expandEntityRerefences in this function
    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   // do some testing wether this is an accepted value
    00388   m_whatToShow = _whatToShow;
    00389 }
    00390
    00391 void TreeWalkerImpl::setFilter(NodeFilter *_filter)
    00392 {
    00393   // ### allow setting of filter to 0?
    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 //     else
    00411 //         throw( DOMException::NOT_SUPPORTED_ERR );
    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 /* 1. my previous sibling.lastchild
    00459  * 2. my previous sibling
    00460  * 3. my parent
    00461  */
    00462
    00463     Node n = getPreviousSibling(m_currentNode);
    00464     if( n.isNull() )
    00465     {
    00466         n = getParentNode(m_currentNode);
    00467         if( !n.isNull() )      //parent
    00468         {
    00469             m_currentNode = n;
    00470             return m_currentNode;
    00471         }
    00472         else                  // parent failed.. no previous node
    00473             return Node();
    00474     }
    00475
    00476     Node child = getLastChild(n);
    00477     if( !child.isNull() )     // previous siblings last child
    00478     {
    00479         m_currentNode = child;
    00480         return m_currentNode;
    00481     }
    00482     else                      // previous sibling
    00483     {
    00484         m_currentNode = n;
    00485         return m_currentNode;
    00486     }
    00487     return Node();            // should never get here!
    00488 }
    00489
    00490 Node TreeWalkerImpl::nextNode(  )
    00491 {
    00492 /*  1. my first child
    00493  *  2. my next sibling
    00494  *  3. my parents sibling, or their parents sibling (loop)
    00495  *  4. not found
    00496  */
    00497
    00498     Node n = getFirstChild(m_currentNode);
    00499     if( !n.isNull()  ) // my first child
    00500     {
    00501         m_currentNode = n;
    00502         return n;
    00503     }
    00504
    00505     n = getNextSibling(m_currentNode); // my next sibling
    00506     if( !n.isNull() )
    00507     {
    00508         m_currentNode = n;
    00509         return m_currentNode;
    00510     }
    00511     Node parent = getParentNode(m_currentNode);
    00512     while( !parent.isNull() ) // parents sibling
    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     // if XML is implemented we have to check expandEntityRerefences in this function
    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 /*|| n.isNull()*/ )
    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;       // match found
    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();      // should never get here!
    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     //first the cases if we have a previousSibling
    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     // now the case if we don't have previous sibling
    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();  // should never get here!
    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.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:38 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001