File indexing completed on 2024-04-28 15:24:52
0001 /* 0002 * This file is part of the DOM implementation for KDE. 0003 * 0004 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 0005 * (C) 1999 Antti Koivisto (koivisto@kde.org) 0006 * (C) 2001 Dirk Mueller (mueller@kde.org) 0007 * (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 0008 * (C) 2007 David Smith (catfish.man@gmail.com) 0009 * (C) 2005, 2009 Maksim Orlovich (maksim@kde.org) 0010 * 0011 * This library is free software; you can redistribute it and/or 0012 * modify it under the terms of the GNU Library General Public 0013 * License as published by the Free Software Foundation; either 0014 * version 2 of the License, or (at your option) any later version. 0015 * 0016 * This library is distributed in the hope that it will be useful, 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0019 * Library General Public License for more details. 0020 * 0021 * You should have received a copy of the GNU Library General Public License 0022 * along with this library; see the file COPYING.LIB. If not, write to 0023 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0024 * Boston, MA 02110-1301, USA. 0025 * 0026 * The code for ClassNodeListImpl was originally licensed under the following terms 0027 * (but in this version is available only as above): 0028 * Redistribution and use in source and binary forms, with or without 0029 * modification, are permitted provided that the following conditions 0030 * are met: 0031 * 0032 * 1. Redistributions of source code must retain the above copyright 0033 * notice, this list of conditions and the following disclaimer. 0034 * 2. Redistributions in binary form must reproduce the above copyright 0035 * notice, this list of conditions and the following disclaimer in the 0036 * documentation and/or other materials provided with the distribution. 0037 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 0038 * its contributors may be used to endorse or promote products derived 0039 * from this software without specific prior written permission. 0040 * 0041 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 0042 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 0043 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 0044 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 0045 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 0046 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 0047 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 0048 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0049 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0050 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0051 */ 0052 #ifndef _DOM_NodeListImpl_h_ 0053 #define _DOM_NodeListImpl_h_ 0054 0055 #include "dom/dom_string.h" 0056 #include "misc/shared.h" 0057 #include "misc/htmlnames.h" 0058 #include "ClassNames.h" 0059 0060 namespace DOM 0061 { 0062 0063 class NodeImpl; 0064 class DocumentImpl; 0065 0066 class NodeListImpl : public khtml::Shared<NodeListImpl> 0067 { 0068 public: 0069 // DOM methods & attributes for NodeList 0070 virtual unsigned long length() const = 0; 0071 virtual NodeImpl *item(unsigned long index) const = 0; 0072 0073 virtual ~NodeListImpl() {} 0074 }; 0075 0076 class DynamicNodeListImpl : public NodeListImpl 0077 { 0078 public: 0079 //Type of the item stored in the cache. 0080 enum Type { 0081 UNCACHEABLE, // Too complex to remember in document -- we still track the position 0082 CHILD_NODES, 0083 LAST_NODE_LIST = CHILD_NODES 0084 }; 0085 0086 struct CacheKey { 0087 NodeImpl *baseNode; 0088 int type; 0089 0090 CacheKey(): type(UNCACHEABLE) {} 0091 0092 CacheKey(NodeImpl *_baseNode, int _type): 0093 baseNode(_baseNode), type(_type) 0094 {} 0095 0096 int hash() const 0097 { 0098 return int(reinterpret_cast<quintptr>(baseNode) >> 2) ^ 0099 (unsigned(type) << 26); 0100 } 0101 0102 bool operator==(const CacheKey &other) const 0103 { 0104 return baseNode == other.baseNode && 0105 type == other.type; 0106 } 0107 }; 0108 0109 struct Cache: public khtml::Shared<Cache> { 0110 static Cache *makeStructuralOnly(); 0111 static Cache *makeNameOrID(); 0112 static Cache *makeClassName(); 0113 0114 Cache(unsigned short relSecondaryVer); 0115 0116 CacheKey key;//### We must store this in here due to QCache in Qt3 sucking 0117 0118 unsigned int version; // structural version. 0119 unsigned int secondaryVersion; 0120 union { 0121 NodeImpl *node; 0122 unsigned int index; 0123 } current; 0124 unsigned int position; 0125 unsigned int length; 0126 bool hasLength; 0127 unsigned short relevantSecondaryVer; 0128 0129 void updateNodeListInfo(DocumentImpl *doc); 0130 0131 virtual void clear(DocumentImpl *doc); 0132 virtual ~Cache(); 0133 }; 0134 0135 typedef Cache *CacheFactory(); 0136 0137 DynamicNodeListImpl(NodeImpl *node, int type, CacheFactory *factory); 0138 virtual ~DynamicNodeListImpl(); 0139 0140 // DOM methods & attributes for NodeList 0141 unsigned long length() const override; 0142 NodeImpl *item(unsigned long index) const override; 0143 0144 // Other methods (not part of DOM) 0145 0146 protected: 0147 virtual unsigned long calcLength(NodeImpl *start) const; 0148 // helper functions for searching all ElementImpls in a tree 0149 0150 NodeImpl *recursiveItem(NodeImpl *absStart, NodeImpl *start, unsigned long &offset) const; 0151 NodeImpl *recursiveItemBack(NodeImpl *absStart, NodeImpl *start, unsigned long &offset) const; 0152 0153 // Override this to determine what nodes to return. Set doRecurse to 0154 // false if the children of this node do not need to be entered. 0155 virtual bool nodeMatches(NodeImpl *testNode, bool &doRecurse) const = 0; 0156 0157 NodeImpl *m_refNode; 0158 mutable Cache *m_cache; 0159 }; 0160 0161 class ChildNodeListImpl : public DynamicNodeListImpl 0162 { 0163 public: 0164 0165 ChildNodeListImpl(NodeImpl *n); 0166 0167 protected: 0168 bool nodeMatches(NodeImpl *testNode, bool &doRecurse) const override; 0169 }; 0170 0171 /** 0172 * NodeList which lists all Nodes in a document with a given tag name 0173 */ 0174 class TagNodeListImpl : public DynamicNodeListImpl 0175 { 0176 public: 0177 TagNodeListImpl(NodeImpl *n, NamespaceName namespaceName, LocalName localName, PrefixName); 0178 TagNodeListImpl(NodeImpl *n, const DOMString &namespaceURI, const DOMString &localName); 0179 0180 // Other methods (not part of DOM) 0181 0182 protected: 0183 bool nodeMatches(NodeImpl *testNode, bool &doRecurse) const override; 0184 NamespaceName m_namespace; 0185 LocalName m_localName; 0186 PrefixName m_prefix; 0187 0188 bool m_namespaceAware; 0189 }; 0190 0191 /** 0192 * NodeList which lists all Nodes in a Element with a given "name=" tag 0193 */ 0194 class NameNodeListImpl : public DynamicNodeListImpl 0195 { 0196 public: 0197 NameNodeListImpl(NodeImpl *doc, const DOMString &t); 0198 0199 // Other methods (not part of DOM) 0200 0201 protected: 0202 bool nodeMatches(NodeImpl *testNode, bool &doRecurse) const override; 0203 0204 DOMString nodeName; 0205 }; 0206 0207 /** For getElementsByClassName */ 0208 class ClassNodeListImpl : public DynamicNodeListImpl 0209 { 0210 public: 0211 ClassNodeListImpl(NodeImpl *rootNode, const DOMString &classNames); 0212 0213 private: 0214 bool nodeMatches(NodeImpl *testNode, bool &doRecurse) const override; 0215 0216 ClassNames m_classNames; 0217 }; 0218 0219 class StaticNodeListImpl : public NodeListImpl 0220 { 0221 public: 0222 StaticNodeListImpl(); 0223 ~StaticNodeListImpl(); 0224 0225 // Implementation of the NodeList API 0226 unsigned long length() const override; 0227 NodeImpl *item(unsigned long index) const override; 0228 0229 // Methods specific to StaticNodeList 0230 void append(NodeImpl *n); 0231 NodeImpl *first() 0232 { 0233 return item(0); 0234 } 0235 bool isEmpty() const 0236 { 0237 return length() == 0; 0238 } 0239 0240 // For XPath, we may have collection nodes that are either ordered 0241 // by the axis, are in random order, or strongly normalized. We represent 0242 // this knowledge by this enum 0243 enum NormalizationKind { 0244 Unnormalized, 0245 AxisOrder, 0246 DocumentOrder 0247 }; 0248 0249 // If the list isn't up to the given level of normalization, put it into 0250 // document order. Note that if we're asked for AxisOrder but have 0251 // DocumentOrder already, it's left to be. 0252 void normalizeUpto(NormalizationKind kind); 0253 0254 // Reports to list outside knowledge of how normalized the data currently is. 0255 void setKnownNormalization(NormalizationKind kind); 0256 0257 NormalizationKind knownNormalization() const; 0258 private: 0259 WTF::Vector<SharedPtr<NodeImpl> > m_kids; 0260 NormalizationKind m_knownNormalization; 0261 }; 0262 0263 } //namespace 0264 #endif