#ifndef HTMLCollection_h
#define HTMLCollection_h
#include "Shared.h"
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
namespace WebCore {
class AtomicString;
class AtomicStringImpl;
class Node;
class NodeList;
class String;
class HTMLCollection : public Shared<HTMLCollection> {
public:
enum Type {
DocImages = 0, DocApplets, DocEmbeds, DocObjects, DocForms, DocLinks, DocAnchors, DocScripts, TableRows, TableTBodies, TSectionRows, TRCells, SelectOptions,
MapAreas,
DocAll, NodeChildren, WindowNamedItems,
DocumentNamedItems
};
enum {
UnnamedCollectionTypes = NodeChildren + 1,
CollectionTypes = DocumentNamedItems + 1
};
HTMLCollection(Node *_base, HTMLCollection::Type _type);
virtual ~HTMLCollection();
unsigned length() const;
virtual Node *item(unsigned index) const;
virtual Node *firstItem() const;
virtual Node *nextItem() const;
virtual Node *namedItem(const String &name, bool caseSensitive = true) const;
virtual Node *nextNamedItem(const String &name) const;
PassRefPtr<NodeList> tags(const String&);
void namedItems(const AtomicString &name, Vector<RefPtr<Node> >&) const;
Node *base() { return m_base.get(); }
struct CollectionInfo {
CollectionInfo();
CollectionInfo(const CollectionInfo&);
CollectionInfo& operator=(const CollectionInfo& other)
{
CollectionInfo tmp(other);
swap(tmp);
return *this;
}
~CollectionInfo();
void reset();
void swap(CollectionInfo&);
unsigned int version;
Node *current;
unsigned int position;
unsigned int length;
int elementsArrayPosition;
typedef HashMap<AtomicStringImpl*, Vector<Node*>*> NodeCacheMap;
NodeCacheMap idCache;
NodeCacheMap nameCache;
bool haslength;
bool hasNameCache;
private:
static void copyCacheMap(NodeCacheMap& dest, const NodeCacheMap& src)
{
ASSERT(dest.isEmpty());
NodeCacheMap::const_iterator end = src.end();
for (NodeCacheMap::const_iterator it = src.begin(); it != end; ++it)
dest.add(it->first, new Vector<Node*>(*it->second));
}
};
Type collectionType() const { return type; }
protected:
virtual void updateNameCache() const;
virtual Node *traverseNextItem(Node *start) const;
bool checkForNameMatch(Node *node, bool checkName, const String &name, bool caseSensitive) const;
virtual unsigned calcLength() const;
virtual void resetCollectionInfo() const;
RefPtr<Node> m_base;
Type type;
mutable CollectionInfo *info;
mutable bool idsDone;
mutable bool m_ownsInfo;
};
}
#endif