Use references and more const in SVGPathUtilities
[WebKit-https.git] / Source / WebCore / html / shadow / InsertionPoint.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "InsertionPoint.h"
33
34 #include "QualifiedName.h"
35 #include "StaticNodeList.h"
36 #include "Text.h"
37
38 namespace WebCore {
39
40 using namespace HTMLNames;
41
42 InsertionPoint::InsertionPoint(const QualifiedName& tagName, Document& document)
43     : HTMLElement(tagName, document, CreateInsertionPoint)
44     , m_hasDistribution(false)
45 {
46 }
47
48 InsertionPoint::~InsertionPoint()
49 {
50 }
51
52 bool InsertionPoint::shouldUseFallbackElements() const
53 {
54     return isActive() && !hasDistribution();
55 }
56
57 bool InsertionPoint::isActive() const
58 {
59     if (!containingShadowRoot())
60         return false;
61     const Node* node = parentNode();
62     while (node) {
63         if (node->isInsertionPoint())
64             return false;
65
66         node = node->parentNode();
67     }
68     return true;
69 }
70
71 bool InsertionPoint::rendererIsNeeded(const RenderStyle& style)
72 {
73     return !isActive() && HTMLElement::rendererIsNeeded(style);
74 }
75
76 void InsertionPoint::childrenChanged(const ChildChange& change)
77 {
78     HTMLElement::childrenChanged(change);
79     if (ShadowRoot* root = containingShadowRoot()) {
80         RELEASE_ASSERT(root->distributor());
81         root->distributor()->invalidateDistribution(root->host());
82     }
83 }
84
85 Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode& insertionPoint)
86 {
87     HTMLElement::insertedInto(insertionPoint);
88
89     if (ShadowRoot* root = containingShadowRoot()) {
90         RELEASE_ASSERT(root->distributor());
91         root->distributor()->didShadowBoundaryChange(root->host());
92         root->distributor()->invalidateInsertionPointList();
93     }
94
95     return InsertionDone;
96 }
97
98 void InsertionPoint::removedFrom(ContainerNode& insertionPoint)
99 {
100     ShadowRoot* root = containingShadowRoot();
101     if (!root)
102         root = insertionPoint.containingShadowRoot();
103
104     if (root && root->host()) {
105         RELEASE_ASSERT(root->distributor());
106         root->distributor()->invalidateDistribution(root->host());
107         root->distributor()->invalidateInsertionPointList();
108     }
109
110     // Since this insertion point is no longer visible from the shadow subtree, it need to clean itself up.
111     clearDistribution();
112
113     HTMLElement::removedFrom(insertionPoint);
114 }
115     
116 Node* InsertionPoint::firstDistributed() const
117 {
118     if (!m_hasDistribution)
119         return 0;
120     for (Node* current = shadowHost()->firstChild(); current; current = current->nextSibling()) {
121         if (matchTypeFor(current) == InsertionPoint::AlwaysMatches)
122             return current;
123     }
124     return 0;
125 }
126
127 Node* InsertionPoint::lastDistributed() const
128 {
129     if (!m_hasDistribution)
130         return 0;
131     for (Node* current = shadowHost()->lastChild(); current; current = current->previousSibling()) {
132         if (matchTypeFor(current) == InsertionPoint::AlwaysMatches)
133             return current;
134     }
135     return 0;
136 }
137
138 Node* InsertionPoint::nextDistributedTo(const Node* node) const
139 {
140     for (Node* current = node->nextSibling(); current; current = current->nextSibling()) {
141         if (matchTypeFor(current) == InsertionPoint::AlwaysMatches)
142             return current;
143     }
144     return 0;
145 }
146
147 Node* InsertionPoint::previousDistributedTo(const Node* node) const
148 {
149     for (Node* current = node->previousSibling(); current; current = current->previousSibling()) {
150         if (matchTypeFor(current) == InsertionPoint::AlwaysMatches)
151             return current;
152     }
153     return 0;
154 }
155
156 InsertionPoint* findInsertionPointOf(const Node* projectedNode)
157 {
158     if (ShadowRoot* shadowRoot = shadowRootOfParentForDistribution(projectedNode)) {
159         if (ShadowRoot* root = projectedNode->containingShadowRoot())
160             ContentDistributor::ensureDistribution(root);
161         if (auto* distributor = shadowRoot->distributor())
162             return distributor->findInsertionPointFor(projectedNode);
163     }
164     return 0;
165 }
166
167 void ShadowRootWithInsertionPoints::childrenChanged(const ChildChange& change)
168 {
169     ContainerNode::childrenChanged(change);
170     
171     if (!isOrphan())
172         m_distributor.invalidateDistribution(host());
173 }
174
175 } // namespace WebCore