HTMLContentSelector.cpp [plain text]
#include "config.h"
#include "HTMLContentSelector.h"
#include "ContentSelectorQuery.h"
#include "HTMLContentElement.h"
#include "ShadowRoot.h"
namespace WebCore {
void HTMLContentSelection::append(PassRefPtr<HTMLContentSelection> next)
{
ASSERT(!m_next);
ASSERT(!next->previous());
m_next = next;
m_next->m_previous = this;
}
void HTMLContentSelection::unlink()
{
ASSERT(!m_previous); RefPtr<HTMLContentSelection> item = this;
while (item) {
ASSERT(!item->previous());
RefPtr<HTMLContentSelection> nextItem = item->m_next;
item->m_next.clear();
if (nextItem)
nextItem->m_previous.clear();
item = nextItem;
}
}
HTMLContentSelectionList::HTMLContentSelectionList()
{
}
HTMLContentSelectionList::~HTMLContentSelectionList()
{
ASSERT(isEmpty());
}
HTMLContentSelection* HTMLContentSelectionList::find(Node* node) const
{
for (HTMLContentSelection* item = first(); item; item = item->next()) {
if (node == item->node())
return item;
}
return 0;
}
void HTMLContentSelectionList::clear()
{
if (isEmpty()) {
ASSERT(!m_last);
return;
}
m_first->unlink();
m_first.clear();
m_last.clear();
}
void HTMLContentSelectionList::append(PassRefPtr<HTMLContentSelection> child)
{
if (isEmpty()) {
ASSERT(!m_last);
m_first = m_last = child;
return;
}
m_last->append(child);
m_last = m_last->next();
}
HTMLContentSelector::HTMLContentSelector()
: m_phase(SelectionPrevented)
{
}
HTMLContentSelector::~HTMLContentSelector()
{
ASSERT(m_candidates.isEmpty());
}
void HTMLContentSelector::select(InsertionPoint* insertionPoint, HTMLContentSelectionList* selections)
{
ASSERT(m_phase == HostChildrenPopulated);
ASSERT(selections->isEmpty());
ContentSelectorQuery query(insertionPoint);
for (size_t i = 0; i < m_candidates.size(); ++i) {
Node* child = m_candidates[i].get();
if (!child)
continue;
if (!query.matches(child))
continue;
RefPtr<HTMLContentSelection> selection = HTMLContentSelection::create(insertionPoint, child);
selections->append(selection);
m_selectionSet.add(selection.get());
m_candidates[i] = 0;
}
}
void HTMLContentSelector::unselect(HTMLContentSelectionList* list)
{
for (HTMLContentSelection* selection = list->first(); selection; selection = selection->next())
m_selectionSet.remove(selection);
list->clear();
}
HTMLContentSelection* HTMLContentSelector::findFor(const Node* key) const
{
return m_selectionSet.find(key);
}
void HTMLContentSelector::willSelect()
{
m_phase = SelectionStarted;
}
void HTMLContentSelector::didSelect()
{
ASSERT(m_phase != SelectionPrevented);
m_phase = SelectionPrevented;
m_candidates.clear();
}
void HTMLContentSelector::populateIfNecessary(Element* shadowHost)
{
if (hasPopulated())
return;
ASSERT(m_candidates.isEmpty());
ASSERT(shadowHost);
ASSERT(m_phase == SelectionStarted);
m_phase = HostChildrenPopulated;
for (Node* node = shadowHost->firstChild(); node; node = node->nextSibling())
m_candidates.append(node);
}
}