1 /**
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@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
ChildNodeList(PassRefPtr<Node> rootNode,DynamicNodeList::Caches * info)30 ChildNodeList::ChildNodeList(PassRefPtr<Node> rootNode, DynamicNodeList::Caches* info)
31 : DynamicNodeList(rootNode, info)
32 {
33 }
34
length() const35 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
item(unsigned index) const50 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
nodeMatches(Element * testNode) const101 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