#ifndef SelectorFilter_h
#define SelectorFilter_h
#include "core/dom/Element.h"
#include "wtf/BloomFilter.h"
#include "wtf/Vector.h"
namespace WebCore {
class CSSSelector;
class SelectorFilter {
public:
void pushParentStackFrame(Element& parent);
void popParentStackFrame();
void setupParentStack(Element& parent);
void pushParent(Element& parent);
void popParent() { popParentStackFrame(); }
bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
bool parentStackIsConsistent(const ContainerNode* parentNode) const { return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode; }
template <unsigned maximumIdentifierCount>
inline bool fastRejectSelector(const unsigned* identifierHashes) const;
static void collectIdentifierHashes(const CSSSelector&, unsigned* identifierHashes, unsigned maximumIdentifierCount);
private:
struct ParentStackFrame {
ParentStackFrame() : element(0) { }
ParentStackFrame(Element& element) : element(&element) { }
Element* element;
Vector<unsigned, 4> identifierHashes;
};
Vector<ParentStackFrame> m_parentStack;
static const unsigned bloomFilterKeyBits = 12;
OwnPtr<BloomFilter<bloomFilterKeyBits> > m_ancestorIdentifierFilter;
};
template <unsigned maximumIdentifierCount>
inline bool SelectorFilter::fastRejectSelector(const unsigned* identifierHashes) const
{
ASSERT(m_ancestorIdentifierFilter);
for (unsigned n = 0; n < maximumIdentifierCount && identifierHashes[n]; ++n) {
if (!m_ancestorIdentifierFilter->mayContain(identifierHashes[n]))
return true;
}
return false;
}
}
#endif