InsertionPoint.cpp [plain text]
#include "config.h"
#include "InsertionPoint.h"
#include "ShadowRoot.h"
#include "ShadowTree.h"
namespace WebCore {
InsertionPoint::InsertionPoint(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
, m_selections()
{
}
InsertionPoint::~InsertionPoint()
{
}
void InsertionPoint::attach()
{
if (isShadowBoundary()) {
ShadowRoot* root = toShadowRoot(treeScope()->rootNode());
if (doesSelectFromHostChildren()) {
distributeHostChildren(root->tree());
attachDistributedNode();
} else if (!root->olderShadowRoot()->assignedTo()) {
ASSERT(!root->olderShadowRoot()->attached());
assignShadowRoot(root->olderShadowRoot());
root->olderShadowRoot()->attach();
}
}
HTMLElement::attach();
}
void InsertionPoint::detach()
{
ShadowRoot* root = toShadowRoot(shadowTreeRootNode());
if (root && isActive()) {
ShadowTree* tree = root->tree();
if (doesSelectFromHostChildren())
clearDistribution(tree);
else if (ShadowRoot* assignedShadowRoot = assignedFrom())
clearAssignment(assignedShadowRoot);
tree->setNeedsReattachHostChildrenAndShadow();
}
ASSERT(m_selections.isEmpty());
HTMLElement::detach();
}
ShadowRoot* InsertionPoint::assignedFrom() const
{
Node* treeScopeRoot = treeScope()->rootNode();
if (!treeScopeRoot->isShadowRoot())
return 0;
ShadowRoot* olderShadowRoot = toShadowRoot(treeScopeRoot)->olderShadowRoot();
if (olderShadowRoot && olderShadowRoot->assignedTo() == this)
return olderShadowRoot;
return 0;
}
bool InsertionPoint::isShadowBoundary() const
{
return treeScope()->rootNode()->isShadowRoot() && isActive();
}
bool InsertionPoint::isActive() const
{
const Node* node = parentNode();
while (node) {
if (WebCore::isInsertionPoint(node))
return false;
node = node->parentNode();
}
return true;
}
bool InsertionPoint::rendererIsNeeded(const NodeRenderingContext& context)
{
return !isShadowBoundary() && HTMLElement::rendererIsNeeded(context);
}
inline void InsertionPoint::distributeHostChildren(ShadowTree* tree)
{
if (!tree->selector().isSelecting()) {
tree->setNeedsReattachHostChildrenAndShadow();
return;
}
tree->selector().populateIfNecessary(tree->host());
tree->selector().unselect(&m_selections);
tree->selector().select(this, &m_selections);
}
inline void InsertionPoint::clearDistribution(ShadowTree* tree)
{
tree->selector().unselect(&m_selections);
}
inline void InsertionPoint::attachDistributedNode()
{
for (HTMLContentSelection* selection = m_selections.first(); selection; selection = selection->next())
selection->node()->attach();
}
inline void InsertionPoint::assignShadowRoot(ShadowRoot* shadowRoot)
{
shadowRoot->setAssignedTo(this);
m_selections.clear();
for (Node* node = shadowRoot->firstChild(); node; node = node->nextSibling())
m_selections.append(HTMLContentSelection::create(this, node));
}
inline void InsertionPoint::clearAssignment(ShadowRoot* shadowRoot)
{
shadowRoot->setAssignedTo(0);
m_selections.clear();
}
}