15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
32e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/InsertionPoint.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/Document.h"
3619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "core/dom/ElementTraversal.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/QualifiedName.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/StaticNodeList.h"
39e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ElementShadow.h"
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)using namespace HTMLNames;
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)InsertionPoint::InsertionPoint(const QualifiedName& tagName, Document& document)
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : HTMLElement(tagName, document, CreateInsertionPoint)
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_registeredWithShadowRoot(false)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
49521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    setHasCustomStyleCallbacks();
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InsertionPoint::~InsertionPoint()
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
56e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void InsertionPoint::setDistribution(ContentDistribution& distribution)
57e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
58e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (shouldUseFallbackElements()) {
59e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        for (Node* child = firstChild(); child; child = child->nextSibling())
60e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            child->lazyReattachIfAttached();
61e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
62e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
63e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // Attempt not to reattach nodes that would be distributed to the exact same
64e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // location by comparing the old and new distributions.
65e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    size_t i = 0;
67e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    size_t j = 0;
68e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
69e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for ( ; i < m_distribution.size() && j < distribution.size(); ++i, ++j) {
70e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (m_distribution.size() < distribution.size()) {
71e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // If the new distribution is larger than the old one, reattach all nodes in
72e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // the new distribution that were inserted.
73e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            for ( ; j < distribution.size() && m_distribution.at(i) != distribution.at(j); ++j)
74e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                distribution.at(j)->lazyReattachIfAttached();
75e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        } else if (m_distribution.size() > distribution.size()) {
76e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // If the old distribution is larger than the new one, reattach all nodes in
77e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // the old distribution that were removed.
78e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            for ( ; i < m_distribution.size() && m_distribution.at(i) != distribution.at(j); ++i)
79e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                m_distribution.at(i)->lazyReattachIfAttached();
80e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        } else if (m_distribution.at(i) != distribution.at(j)) {
81e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // If both distributions are the same length reattach both old and new.
82e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            m_distribution.at(i)->lazyReattachIfAttached();
83e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            distribution.at(j)->lazyReattachIfAttached();
84e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
85e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
86e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
87e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    // If we hit the end of either list above we need to reattach all remaining nodes.
88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
89e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for ( ; i < m_distribution.size(); ++i)
90e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        m_distribution.at(i)->lazyReattachIfAttached();
91e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
92e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for ( ; j < distribution.size(); ++j)
93e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        distribution.at(j)->lazyReattachIfAttached();
94e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
95e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    m_distribution.swap(distribution);
969bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    m_distribution.shrinkToFit();
97e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
98e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
99521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void InsertionPoint::attach(const AttachContext& context)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // We need to attach the distribution here so that they're inserted in the right order
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // otherwise the n^2 protection inside RenderTreeBuilder will cause them to be
10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // inserted in the wrong place later. This also lets distributed nodes benefit from
10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // the n^2 protection.
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < m_distribution.size(); ++i) {
1061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (m_distribution.at(i)->needsAttach())
107521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            m_distribution.at(i)->attach(context);
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
110521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    HTMLElement::attach(context);
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
113521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void InsertionPoint::detach(const AttachContext& context)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
115e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for (size_t i = 0; i < m_distribution.size(); ++i)
116e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        m_distribution.at(i)->lazyReattachIfAttached();
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
118521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    HTMLElement::detach(context);
119521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
120521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void InsertionPoint::willRecalcStyle(StyleRecalcChange change)
122521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
123521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (change < Inherit)
124521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
125f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    for (size_t i = 0; i < m_distribution.size(); ++i)
126f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_distribution.at(i)->setNeedsStyleRecalc(SubtreeStyleChange);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InsertionPoint::shouldUseFallbackElements() const
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return isActive() && !hasDistribution();
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)bool InsertionPoint::canBeActive() const
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (!isInShadowTree())
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1389e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return !Traversal<InsertionPoint>::firstAncestor(*this);
13919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)bool InsertionPoint::isActive() const
14219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
14319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (!canBeActive())
14419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return false;
14519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ShadowRoot* shadowRoot = containingShadowRoot();
14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!shadowRoot)
14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!isHTMLShadowElement(*this) || shadowRoot->descendantShadowElementCount() <= 1)
14919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        return true;
15019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
15119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    // Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case.
152d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
15319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    for (size_t i = 0; i < insertionPoints.size(); ++i) {
15419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        InsertionPoint* point = insertionPoints[i].get();
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isHTMLShadowElement(*point))
15619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return point == this;
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)bool InsertionPoint::isShadowInsertionPoint() const
16219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return isHTMLShadowElement(*this) && isActive();
16419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
16519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
16619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)bool InsertionPoint::isContentInsertionPoint() const
16719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles){
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return isHTMLContentElement(*this) && isActive();
16919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}
17019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
17176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)PassRefPtrWillBeRawPtr<StaticNodeList> InsertionPoint::getDistributedNodes()
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    document().updateDistributionForNodeIfNeeded(this);
174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
175f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
1769bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    nodes.reserveInitialCapacity(m_distribution.size());
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < m_distribution.size(); ++i)
1789bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        nodes.uncheckedAppend(m_distribution.at(i));
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return StaticNodeList::adopt(nodes);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)bool InsertionPoint::rendererIsNeeded(const RenderStyle& style)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return !isActive() && HTMLElement::rendererIsNeeded(style);
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
188197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid InsertionPoint::childrenChanged(const ChildrenChange& change)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
190197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HTMLElement::childrenChanged(change);
191f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (ShadowRoot* root = containingShadowRoot()) {
192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (ElementShadow* rootOwner = root->owner())
193f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            rootOwner->setNeedsDistributionRecalc();
194f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* insertionPoint)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement::insertedInto(insertionPoint);
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (ShadowRoot* root = containingShadowRoot()) {
201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (ElementShadow* rootOwner = root->owner()) {
202f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            rootOwner->setNeedsDistributionRecalc();
20319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (canBeActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                m_registeredWithShadowRoot = true;
205f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                root->didAddInsertionPoint(this);
206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (canAffectSelector())
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    rootOwner->willAffectSelector();
208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return InsertionDone;
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InsertionPoint::removedFrom(ContainerNode* insertionPoint)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ShadowRoot* root = containingShadowRoot();
218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!root)
219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        root = insertionPoint->containingShadowRoot();
220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
221f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (root) {
222f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        if (ElementShadow* rootOwner = root->owner())
223f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            rootOwner->setNeedsDistributionRecalc();
224f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
225f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // host can be null when removedFrom() is called from ElementShadow destructor.
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ElementShadow* rootOwner = root ? root->owner() : 0;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Since this insertion point is no longer visible from the shadow subtree, it need to clean itself up.
230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    clearDistribution();
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(root);
234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_registeredWithShadowRoot = false;
235f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        root->didRemoveInsertionPoint(this);
2363c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        if (rootOwner) {
2373c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            if (canAffectSelector())
2383c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                rootOwner->willAffectSelector();
2393c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        }
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    HTMLElement::removedFrom(insertionPoint);
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
245d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void InsertionPoint::trace(Visitor* visitor)
246d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
247d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_distribution);
248d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    HTMLElement::trace(visitor);
249d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
250d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
25119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)const InsertionPoint* resolveReprojection(const Node* projectedNode)
252926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
25319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ASSERT(projectedNode);
25419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    const InsertionPoint* insertionPoint = 0;
255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const Node* current = projectedNode;
25619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ElementShadow* lastElementShadow = 0;
25719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    while (true) {
25819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*current);
25919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (!shadow || shadow == lastElementShadow)
26019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            break;
26119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        lastElementShadow = shadow;
26219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        const InsertionPoint* insertedTo = shadow->finalDestinationInsertionPointFor(projectedNode);
26319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (!insertedTo)
26419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            break;
26519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        ASSERT(current != insertedTo);
26619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        current = insertedTo;
26719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        insertionPoint = insertedTo;
268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
269926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return insertionPoint;
270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
272d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void collectDestinationInsertionPoints(const Node& node, WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8>& results)
273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
27419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    const Node* current = &node;
27519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ElementShadow* lastElementShadow = 0;
276926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    while (true) {
27719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*current);
27819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (!shadow || shadow == lastElementShadow)
27919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return;
28019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        lastElementShadow = shadow;
28119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        const DestinationInsertionPoints* insertionPoints = shadow->destinationInsertionPointsFor(&node);
28219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (!insertionPoints)
28319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return;
28419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        for (size_t i = 0; i < insertionPoints->size(); ++i)
28519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            results.append(insertionPoints->at(i).get());
28619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        ASSERT(current != insertionPoints->last().get());
28719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        current = insertionPoints->last().get();
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
291c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
292