Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: Source/core/dom/shadow/ElementShadow.cpp

Issue 23133006: Merge ContentDistributor into ElementShadow (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Don't find git copies Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Neither the name of Google Inc. nor the names of its 10 * * Neither the name of Google Inc. nor the names of its
(...skipping 10 matching lines...) Expand all
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "config.h" 27 #include "config.h"
28 #include "core/dom/shadow/ElementShadow.h" 28 #include "core/dom/shadow/ElementShadow.h"
29 29
30 #include "core/dom/ContainerNodeAlgorithms.h" 30 #include "core/dom/ContainerNodeAlgorithms.h"
31 #include "core/dom/NodeTraversal.h"
32 #include "core/dom/shadow/ContentDistribution.h"
33 #include "core/dom/shadow/InsertionPoint.h"
34 #include "core/dom/shadow/ScopeContentDistribution.h"
35 #include "core/dom/shadow/ShadowRoot.h"
36 #include "core/html/shadow/HTMLContentElement.h"
37 #include "core/html/shadow/HTMLShadowElement.h"
31 38
32 namespace WebCore { 39 namespace WebCore {
33 40
41 PassOwnPtr<ElementShadow> ElementShadow::create()
42 {
43 return adoptPtr(new ElementShadow());
44 }
45
46 ElementShadow::ElementShadow()
47 : m_needsDistributionRecalc(false)
48 , m_applyAuthorStyles(false)
49 , m_needsSelectFeatureSet(false)
50 {
51 }
52
53 ElementShadow::~ElementShadow()
54 {
55 removeAllShadowRoots();
56 }
57
34 ShadowRoot* ElementShadow::addShadowRoot(Element* shadowHost, ShadowRoot::Shadow RootType type) 58 ShadowRoot* ElementShadow::addShadowRoot(Element* shadowHost, ShadowRoot::Shadow RootType type)
35 { 59 {
36 RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(shadowHost->document(), t ype); 60 RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(shadowHost->document(), t ype);
37 61
38 shadowRoot->setParentOrShadowHostNode(shadowHost); 62 shadowRoot->setParentOrShadowHostNode(shadowHost);
39 shadowRoot->setParentTreeScope(shadowHost->treeScope()); 63 shadowRoot->setParentTreeScope(shadowHost->treeScope());
40 m_shadowRoots.push(shadowRoot.get()); 64 m_shadowRoots.push(shadowRoot.get());
41 ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get()); 65 ChildNodeInsertionNotifier(shadowHost).notify(shadowRoot.get());
42 setNeedsDistributionRecalc(); 66 setNeedsDistributionRecalc();
43 67
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 { 163 {
140 for (const ShadowRoot* shadowRoot = youngestShadowRoot(); shadowRoot; shadow Root = shadowRoot->olderShadowRoot()) { 164 for (const ShadowRoot* shadowRoot = youngestShadowRoot(); shadowRoot; shadow Root = shadowRoot->olderShadowRoot()) {
141 if (shadowRoot->applyAuthorStyles()) 165 if (shadowRoot->applyAuthorStyles())
142 return true; 166 return true;
143 if (!shadowRoot->containsShadowElements()) 167 if (!shadowRoot->containsShadowElements())
144 break; 168 break;
145 } 169 }
146 return false; 170 return false;
147 } 171 }
148 172
173 InsertionPoint* ElementShadow::findInsertionPointFor(const Node* key) const
174 {
175 return m_nodeToInsertionPoint.get(key);
176 }
177
178 void ElementShadow::populate(Node* node, Vector<Node*>& pool)
179 {
180 if (!isActiveInsertionPoint(node)) {
181 pool.append(node);
182 return;
183 }
184
185 InsertionPoint* insertionPoint = toInsertionPoint(node);
186 if (insertionPoint->hasDistribution()) {
187 for (size_t i = 0; i < insertionPoint->size(); ++i)
188 populate(insertionPoint->at(i), pool);
189 } else {
190 for (Node* fallbackNode = insertionPoint->firstChild(); fallbackNode; fa llbackNode = fallbackNode->nextSibling())
191 pool.append(fallbackNode);
192 }
193 }
194
195 void ElementShadow::distribute()
196 {
197 Vector<Node*> pool;
198 for (Node* node = host()->firstChild(); node; node = node->nextSibling())
199 populate(node, pool);
200
201 host()->setNeedsStyleRecalc();
202
203 Vector<bool> distributed(pool.size());
204 distributed.fill(false);
205
206 Vector<HTMLShadowElement*, 8> activeShadowInsertionPoints;
207 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadow Root()) {
208 HTMLShadowElement* firstActiveShadowInsertionPoint = 0;
209
210 if (ScopeContentDistribution* scope = root->scopeDistribution()) {
211 const Vector<RefPtr<InsertionPoint> >& insertionPoints = scope->ensu reInsertionPointList(root);
212 for (size_t i = 0; i < insertionPoints.size(); ++i) {
213 InsertionPoint* point = insertionPoints[i].get();
214 if (!point->isActive())
215 continue;
216
217 if (isHTMLShadowElement(point)) {
218 if (!firstActiveShadowInsertionPoint)
219 firstActiveShadowInsertionPoint = toHTMLShadowElement(po int);
220 } else {
221 distributeSelectionsTo(point, pool, distributed);
222 if (ElementShadow* shadow = shadowOfParentForDistribution(po int))
223 shadow->setNeedsDistributionRecalc();
224 }
225 }
226 }
227
228 if (firstActiveShadowInsertionPoint)
229 activeShadowInsertionPoints.append(firstActiveShadowInsertionPoint);
230 }
231
232 for (size_t i = activeShadowInsertionPoints.size(); i > 0; --i) {
233 HTMLShadowElement* shadowElement = activeShadowInsertionPoints[i - 1];
234 ShadowRoot* root = shadowElement->containingShadowRoot();
235 ASSERT(root);
236 if (!shadowElement->shouldSelect()) {
237 if (root->olderShadowRoot())
238 root->olderShadowRoot()->ensureScopeDistribution()->setInsertion PointAssignedTo(shadowElement);
239 } else if (root->olderShadowRoot()) {
240 distributeNodeChildrenTo(shadowElement, root->olderShadowRoot());
241 root->olderShadowRoot()->ensureScopeDistribution()->setInsertionPoin tAssignedTo(shadowElement);
242 } else {
243 distributeSelectionsTo(shadowElement, pool, distributed);
244 }
245 if (ElementShadow* shadow = shadowOfParentForDistribution(shadowElement) )
246 shadow->setNeedsDistributionRecalc();
247 }
248
249 // Detach all nodes that were not distributed and have a renderer.
250 for (size_t i = 0; i < pool.size(); ++i) {
251 if (distributed[i])
252 continue;
253 if (pool[i]->renderer())
254 pool[i]->lazyReattachIfAttached();
255 }
256 }
257
258 void ElementShadow::distributeSelectionsTo(InsertionPoint* insertionPoint, const Vector<Node*>& pool, Vector<bool>& distributed)
259 {
260 ContentDistribution distribution;
261
262 for (size_t i = 0; i < pool.size(); ++i) {
263 if (distributed[i])
264 continue;
265
266 if (isHTMLContentElement(insertionPoint) && !toHTMLContentElement(insert ionPoint)->canSelectNode(pool, i))
267 continue;
268
269 Node* child = pool[i];
270 distribution.append(child);
271 m_nodeToInsertionPoint.add(child, insertionPoint);
272 distributed[i] = true;
273 }
274
275 insertionPoint->setDistribution(distribution);
276 }
277
278 void ElementShadow::distributeNodeChildrenTo(InsertionPoint* insertionPoint, Con tainerNode* containerNode)
279 {
280 ContentDistribution distribution;
281 for (Node* node = containerNode->firstChild(); node; node = node->nextSiblin g()) {
282 if (isActiveInsertionPoint(node)) {
283 InsertionPoint* innerInsertionPoint = toInsertionPoint(node);
284 if (innerInsertionPoint->hasDistribution()) {
285 for (size_t i = 0; i < innerInsertionPoint->size(); ++i) {
286 distribution.append(innerInsertionPoint->at(i));
287 m_nodeToInsertionPoint.add(innerInsertionPoint->at(i), inser tionPoint);
288 }
289 } else {
290 for (Node* child = innerInsertionPoint->firstChild(); child; chi ld = child->nextSibling()) {
291 distribution.append(child);
292 m_nodeToInsertionPoint.add(child, insertionPoint);
293 }
294 }
295 } else {
296 distribution.append(node);
297 m_nodeToInsertionPoint.add(node, insertionPoint);
298 }
299 }
300
301 insertionPoint->setDistribution(distribution);
302 }
303
304 const SelectRuleFeatureSet& ElementShadow::ensureSelectFeatureSet()
305 {
306 if (!m_needsSelectFeatureSet)
307 return m_selectFeatures;
308
309 m_selectFeatures.clear();
310 for (ShadowRoot* root = oldestShadowRoot(); root; root = root->youngerShadow Root())
311 collectSelectFeatureSetFrom(root);
312 m_needsSelectFeatureSet = false;
313 return m_selectFeatures;
314 }
315
316 void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot* root)
317 {
318 if (!root->containsShadowRoots() && !root->containsContentElements())
319 return;
320
321 for (Element* element = ElementTraversal::firstWithin(root); element; elemen t = ElementTraversal::next(element, root)) {
322 if (ElementShadow* shadow = element->shadow())
323 m_selectFeatures.add(shadow->ensureSelectFeatureSet());
324 if (!isHTMLContentElement(element))
325 continue;
326 const CSSSelectorList& list = toHTMLContentElement(element)->selectorLis t();
327 for (const CSSSelector* selector = list.first(); selector; selector = CS SSelectorList::next(selector)) {
328 for (const CSSSelector* component = selector; component; component = component->tagHistory())
329 m_selectFeatures.collectFeaturesFromSelector(component);
330 }
331 }
332 }
333
334 void ElementShadow::didAffectSelector(AffectedSelectorMask mask)
335 {
336 if (ensureSelectFeatureSet().hasSelectorFor(mask))
337 setNeedsDistributionRecalc();
338 }
339
340 void ElementShadow::willAffectSelector()
341 {
342 for (ElementShadow* shadow = this; shadow; shadow = shadow->containingShadow ()) {
343 if (shadow->needsSelectFeatureSet())
344 break;
345 shadow->setNeedsSelectFeatureSet();
346 }
347 setNeedsDistributionRecalc();
348 }
349
350 void ElementShadow::clearDistribution()
351 {
352 m_nodeToInsertionPoint.clear();
353
354 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadow Root()) {
355 if (ScopeContentDistribution* scope = root->scopeDistribution())
356 scope->setInsertionPointAssignedTo(0);
357 }
358 }
359
149 } // namespace 360 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698