Home | History | Annotate | Download | only in dom
      1 /**
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      5  * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  */
     22 
     23 #include "config.h"
     24 #include "ChildNodeList.h"
     25 
     26 #include "Element.h"
     27 
     28 namespace WebCore {
     29 
     30 ChildNodeList::ChildNodeList(PassRefPtr<Node> rootNode, DynamicNodeList::Caches* info)
     31     : DynamicNodeList(rootNode, info)
     32 {
     33 }
     34 
     35 unsigned ChildNodeList::length() const
     36 {
     37     if (m_caches->isLengthCacheValid)
     38         return m_caches->cachedLength;
     39 
     40     unsigned len = 0;
     41     for (Node* n = m_rootNode->firstChild(); n; n = n->nextSibling())
     42         len++;
     43 
     44     m_caches->cachedLength = len;
     45     m_caches->isLengthCacheValid = true;
     46 
     47     return len;
     48 }
     49 
     50 Node* ChildNodeList::item(unsigned index) const
     51 {
     52     unsigned int pos = 0;
     53     Node* n = m_rootNode->firstChild();
     54 
     55     if (m_caches->isItemCacheValid) {
     56         if (index == m_caches->lastItemOffset)
     57             return m_caches->lastItem;
     58 
     59         int diff = index - m_caches->lastItemOffset;
     60         unsigned dist = abs(diff);
     61         if (dist < index) {
     62             n = m_caches->lastItem;
     63             pos = m_caches->lastItemOffset;
     64         }
     65     }
     66 
     67     if (m_caches->isLengthCacheValid) {
     68         if (index >= m_caches->cachedLength)
     69             return 0;
     70 
     71         int diff = index - pos;
     72         unsigned dist = abs(diff);
     73         if (dist > m_caches->cachedLength - 1 - index) {
     74             n = m_rootNode->lastChild();
     75             pos = m_caches->cachedLength - 1;
     76         }
     77     }
     78 
     79     if (pos <= index) {
     80         while (n && pos < index) {
     81             n = n->nextSibling();
     82             ++pos;
     83         }
     84     } else {
     85         while (n && pos > index) {
     86             n = n->previousSibling();
     87             --pos;
     88         }
     89     }
     90 
     91     if (n) {
     92         m_caches->lastItem = n;
     93         m_caches->lastItemOffset = pos;
     94         m_caches->isItemCacheValid = true;
     95         return n;
     96     }
     97 
     98     return 0;
     99 }
    100 
    101 bool ChildNodeList::nodeMatches(Element* testNode) const
    102 {
    103     // Note: Due to the overrides of the length and item functions above,
    104     // this function will be called only by DynamicNodeList::itemWithName,
    105     // for an element that was located with getElementById.
    106     return testNode->parentNode() == m_rootNode;
    107 }
    108 
    109 } // namespace WebCore
    110