summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/shadow/ContentDistributor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/shadow/ContentDistributor.cpp')
-rw-r--r--Source/WebCore/html/shadow/ContentDistributor.cpp122
1 files changed, 82 insertions, 40 deletions
diff --git a/Source/WebCore/html/shadow/ContentDistributor.cpp b/Source/WebCore/html/shadow/ContentDistributor.cpp
index af650a3bf..b3fdd32ad 100644
--- a/Source/WebCore/html/shadow/ContentDistributor.cpp
+++ b/Source/WebCore/html/shadow/ContentDistributor.cpp
@@ -28,6 +28,7 @@
#include "ContentDistributor.h"
#include "ContentSelectorQuery.h"
+#include "ElementShadow.h"
#include "HTMLContentElement.h"
#include "ShadowRoot.h"
@@ -35,72 +36,113 @@
namespace WebCore {
ContentDistributor::ContentDistributor()
- : m_phase(Prevented)
- , m_needsRedistributing(false)
+ : m_validity(Undetermined)
{
}
ContentDistributor::~ContentDistributor()
{
- ASSERT(m_pool.isEmpty());
}
-void ContentDistributor::distribute(InsertionPoint* insertionPoint, ContentDistribution* distribution)
+InsertionPoint* ContentDistributor::findInsertionPointFor(const Node* key) const
{
- ASSERT(m_phase == Prepared);
- ASSERT(distribution->isEmpty());
-
- ContentSelectorQuery query(insertionPoint);
+ return m_nodeToInsertionPoint.get(key);
+}
- for (size_t i = 0; i < m_pool.size(); ++i) {
- Node* child = m_pool[i].get();
- if (!child)
- continue;
- if (!query.matches(child))
- continue;
- distribution->append(child);
- m_nodeToInsertionPoint.add(child, insertionPoint);
- m_pool[i] = 0;
+void ContentDistributor::distribute(Element* host)
+{
+ ASSERT(needsDistribution());
+ ASSERT(m_nodeToInsertionPoint.isEmpty());
+
+ m_validity = Valid;
+
+ ContentDistribution pool;
+ for (Node* node = host->firstChild(); node; node = node->nextSibling())
+ pool.append(node);
+
+ for (ShadowRoot* root = host->youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ for (Node* node = root; node; node = node->traverseNextNode(root)) {
+ if (!isInsertionPoint(node))
+ continue;
+ InsertionPoint* point = toInsertionPoint(node);
+ if (!point->isActive())
+ continue;
+ ShadowRoot* older = root->olderShadowRoot();
+ if (point->doesSelectFromHostChildren())
+ distributeSelectionsTo(point, pool);
+ else if (older && !older->assignedTo()) {
+ distributeShadowChildrenTo(point, older);
+ older->setAssignedTo(point);
+ }
+ }
}
}
-void ContentDistributor::clearDistribution(ContentDistribution* list)
+bool ContentDistributor::invalidate(Element* host)
{
- for (size_t i = 0; i < list->size(); ++i)
- m_nodeToInsertionPoint.remove(list->at(i).get());
- list->clear();
-}
+ ASSERT(needsInvalidation());
+ bool needsReattach = (m_validity == Undetermined) || !m_nodeToInsertionPoint.isEmpty();
+
+ for (ShadowRoot* root = host->youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ root->setAssignedTo(0);
+
+ for (Node* node = root; node; node = node->traverseNextNode(root)) {
+ if (!isInsertionPoint(node))
+ continue;
+ needsReattach = needsReattach || true;
+ InsertionPoint* point = toInsertionPoint(node);
+ point->clearDistribution();
+ }
+ }
-InsertionPoint* ContentDistributor::findInsertionPointFor(const Node* key) const
-{
- return m_nodeToInsertionPoint.get(key);
+ m_validity = Invalidating;
+ m_nodeToInsertionPoint.clear();
+ return needsReattach;
}
-void ContentDistributor::willDistribute()
+void ContentDistributor::finishInivalidation()
{
- m_phase = Started;
+ ASSERT(m_validity == Invalidating);
+ m_validity = Invalidated;
}
-void ContentDistributor::didDistribute()
+void ContentDistributor::distributeSelectionsTo(InsertionPoint* insertionPoint, ContentDistribution& pool)
{
- ASSERT(m_phase != Prevented);
- m_phase = Prevented;
- m_pool.clear();
+ ContentDistribution distribution;
+ ContentSelectorQuery query(insertionPoint);
+
+ for (size_t i = 0; i < pool.size(); ++i) {
+ Node* child = pool[i].get();
+ if (!child)
+ continue;
+ if (!query.matches(child))
+ continue;
+
+ distribution.append(child);
+ m_nodeToInsertionPoint.add(child, insertionPoint);
+ pool[i] = 0;
+ }
+
+ insertionPoint->setDistribution(distribution);
}
-void ContentDistributor::preparePoolFor(Element* shadowHost)
+void ContentDistributor::distributeShadowChildrenTo(InsertionPoint* insertionPoint, ShadowRoot* root)
{
- if (poolIsReady())
- return;
+ ContentDistribution distribution;
+ for (Node* node = root->firstChild(); node; node = node->nextSibling()) {
+ distribution.append(node);
+ m_nodeToInsertionPoint.add(node, insertionPoint);
+ }
- ASSERT(m_pool.isEmpty());
- ASSERT(shadowHost);
- ASSERT(m_phase == Started);
+ insertionPoint->setDistribution(distribution);
+}
- m_phase = Prepared;
- for (Node* node = shadowHost->firstChild(); node; node = node->nextSibling())
- m_pool.append(node);
+void ContentDistributor::invalidateDistributionIn(ContentDistribution* list)
+{
+ for (size_t i = 0; i < list->size(); ++i)
+ m_nodeToInsertionPoint.remove(list->at(i).get());
+ list->clear();
}
}