File indexing completed on 2024-04-28 11:39:36

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