#ifndef HTMLFormattingElementList_h
#define HTMLFormattingElementList_h
#include "core/html/parser/HTMLStackItem.h"
#include "wtf/Forward.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
class Element;
class HTMLFormattingElementList {
WTF_MAKE_NONCOPYABLE(HTMLFormattingElementList);
public:
HTMLFormattingElementList();
~HTMLFormattingElementList();
class Entry {
public:
explicit Entry(PassRefPtr<HTMLStackItem> item)
: m_item(item)
{
}
enum MarkerEntryType { MarkerEntry };
explicit Entry(MarkerEntryType)
: m_item(nullptr)
{
}
~Entry() {}
bool isMarker() const { return !m_item; }
PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
Element* element() const
{
ASSERT(m_item);
return m_item->element();
}
void replaceElement(PassRefPtr<HTMLStackItem> item) { m_item = item; }
bool operator==(Element* element) const { return !m_item ? !element : m_item->element() == element; }
bool operator!=(Element* element) const { return !m_item ? !!element : m_item->element() != element; }
private:
RefPtr<HTMLStackItem> m_item;
};
class Bookmark {
public:
explicit Bookmark(Entry* entry)
: m_hasBeenMoved(false)
, m_mark(entry)
{
}
void moveToAfter(Entry* before)
{
m_hasBeenMoved = true;
m_mark = before;
}
bool hasBeenMoved() const { return m_hasBeenMoved; }
Entry* mark() const { return m_mark; }
private:
bool m_hasBeenMoved;
Entry* m_mark;
};
bool isEmpty() const { return !size(); }
size_t size() const { return m_entries.size(); }
Element* closestElementInScopeWithName(const AtomicString&);
Entry* find(Element*);
bool contains(Element*);
void append(PassRefPtr<HTMLStackItem>);
void remove(Element*);
Bookmark bookmarkFor(Element*);
void swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark&);
void appendMarker();
void clearToLastMarker();
const Entry& at(size_t i) const { return m_entries[i]; }
Entry& at(size_t i) { return m_entries[i]; }
#ifndef NDEBUG
void show();
#endif
private:
Entry* first() { return &at(0); }
void tryToEnsureNoahsArkConditionQuickly(HTMLStackItem*, Vector<HTMLStackItem*>& remainingCandiates);
void ensureNoahsArkCondition(HTMLStackItem*);
Vector<Entry> m_entries;
};
}
#endif