void ElementShadow::distribute() { host()->setNeedsStyleRecalc(); Vector<HTMLShadowElement*, 32> shadowInsertionPoints; DistributionPool pool(*host()); for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { HTMLShadowElement* shadowInsertionPoint = 0; const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints(); for (size_t i = 0; i < insertionPoints.size(); ++i) { InsertionPoint* point = insertionPoints[i].get(); if (!point->isActive()) continue; if (isHTMLShadowElement(point)) { if (!shadowInsertionPoint) shadowInsertionPoint = toHTMLShadowElement(point); } else { pool.distributeTo(point, this); if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*point)) shadow->setNeedsDistributionRecalc(); } } if (shadowInsertionPoint) { shadowInsertionPoints.append(shadowInsertionPoint); if (shadowInsertionPoint->hasChildNodes()) pool.populateChildren(*shadowInsertionPoint); } else { pool.clear(); } } for (size_t i = shadowInsertionPoints.size(); i > 0; --i) { HTMLShadowElement* shadowInsertionPoint = shadowInsertionPoints[i - 1]; ShadowRoot* root = shadowInsertionPoint->containingShadowRoot(); ASSERT(root); if (root->isOldest()) { pool.distributeTo(shadowInsertionPoint, this); } else if (root->olderShadowRoot()->type() == root->type()) { // Only allow reprojecting older shadow roots between the same type to // disallow reprojecting UA elements into author shadows. DistributionPool olderShadowRootPool(*root->olderShadowRoot()); olderShadowRootPool.distributeTo(shadowInsertionPoint, this); root->olderShadowRoot()->setShadowInsertionPointOfYoungerShadowRoot(shadowInsertionPoint); } if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*shadowInsertionPoint)) shadow->setNeedsDistributionRecalc(); } }
bool InsertionPoint::isActive() const { if (!canBeActive()) return false; ShadowRoot* shadowRoot = containingShadowRoot(); ASSERT(shadowRoot); if (!isHTMLShadowElement(*this) || shadowRoot->descendantShadowElementCount() <= 1) return true; // Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case. const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint>>& insertionPoints = shadowRoot->descendantInsertionPoints(); for (size_t i = 0; i < insertionPoints.size(); ++i) { InsertionPoint* point = insertionPoints[i].get(); if (isHTMLShadowElement(*point)) return point == this; } return true; }
void ElementShadowV0::distribute() { HeapVector<Member<HTMLShadowElement>, 32> shadowInsertionPoints; DistributionPool pool(m_elementShadow->host()); for (ShadowRoot* root = &youngestShadowRoot(); root; root = root->olderShadowRoot()) { HTMLShadowElement* shadowInsertionPoint = 0; for (const auto& point : root->descendantInsertionPoints()) { if (!point->isActive()) continue; if (isHTMLShadowElement(*point)) { DCHECK(!shadowInsertionPoint); shadowInsertionPoint = toHTMLShadowElement(point); shadowInsertionPoints.append(shadowInsertionPoint); } else { pool.distributeTo(point, this); if (ElementShadow* shadow = shadowWhereNodeCanBeDistributedForV0(*point)) shadow->setNeedsDistributionRecalc(); } } } for (size_t i = shadowInsertionPoints.size(); i > 0; --i) { HTMLShadowElement* shadowInsertionPoint = shadowInsertionPoints[i - 1]; ShadowRoot* root = shadowInsertionPoint->containingShadowRoot(); DCHECK(root); if (root->isOldest()) { pool.distributeTo(shadowInsertionPoint, this); } else if (root->olderShadowRoot()->type() == root->type()) { // Only allow reprojecting older shadow roots between the same type to // disallow reprojecting UA elements into author shadows. DistributionPool olderShadowRootPool(*root->olderShadowRoot()); olderShadowRootPool.distributeTo(shadowInsertionPoint, this); root->olderShadowRoot()->setShadowInsertionPointOfYoungerShadowRoot( shadowInsertionPoint); } if (ElementShadow* shadow = shadowWhereNodeCanBeDistributedForV0(*shadowInsertionPoint)) shadow->setNeedsDistributionRecalc(); } InspectorInstrumentation::didPerformElementShadowDistribution( &m_elementShadow->host()); }
void ElementShadow::distributeV0() { host()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Shadow)); WillBeHeapVector<RawPtrWillBeMember<HTMLShadowElement>, 32> shadowInsertionPoints; DistributionPool pool(*host()); for (ShadowRoot* root = &youngestShadowRoot(); root; root = root->olderShadowRoot()) { HTMLShadowElement* shadowInsertionPoint = 0; const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint>>& insertionPoints = root->descendantInsertionPoints(); for (size_t i = 0; i < insertionPoints.size(); ++i) { InsertionPoint* point = insertionPoints[i].get(); if (!point->isActive()) continue; if (isHTMLShadowElement(*point)) { ASSERT(!shadowInsertionPoint); shadowInsertionPoint = toHTMLShadowElement(point); shadowInsertionPoints.append(shadowInsertionPoint); } else { pool.distributeTo(point, this); if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*point)) shadow->setNeedsDistributionRecalc(); } } } for (size_t i = shadowInsertionPoints.size(); i > 0; --i) { HTMLShadowElement* shadowInsertionPoint = shadowInsertionPoints[i - 1]; ShadowRoot* root = shadowInsertionPoint->containingShadowRoot(); ASSERT(root); if (root->isOldest()) { pool.distributeTo(shadowInsertionPoint, this); } else if (root->olderShadowRoot()->type() == root->type()) { // Only allow reprojecting older shadow roots between the same type to // disallow reprojecting UA elements into author shadows. DistributionPool olderShadowRootPool(*root->olderShadowRoot()); olderShadowRootPool.distributeTo(shadowInsertionPoint, this); root->olderShadowRoot()->setShadowInsertionPointOfYoungerShadowRoot(shadowInsertionPoint); } if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*shadowInsertionPoint)) shadow->setNeedsDistributionRecalc(); } InspectorInstrumentation::didPerformElementShadowDistribution(host()); }