Changeset 140299 in webkit
- Timestamp:
- Jan 20, 2013 10:59:35 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r140296 r140299 1 2013-01-20 Shinya Kawanaka <shinyak@chromium.org> 2 3 Distribution state becomes inconsistent with content/shadow reprojection 4 https://bugs.webkit.org/show_bug.cgi?id=106634 5 6 Reviewed by Hajime Morita. 7 8 * fast/dom/shadow/distribution-crash-expected.txt: Added. 9 * fast/dom/shadow/distribution-crash.html: Added. 10 * fast/dom/shadow/nested-reprojection-inconsistent-expected.txt: Added. 11 * fast/dom/shadow/nested-reprojection-inconsistent.html: Added. 12 1 13 2013-01-20 Kent Tamura <tkent@chromium.org> 2 14 -
trunk/Source/WebCore/ChangeLog
r140297 r140299 1 2013-01-20 Shinya Kawanaka <shinyak@chromium.org> 2 3 Distribution state becomes inconsistent with content/shadow reprojection 4 https://bugs.webkit.org/show_bug.cgi?id=106634 5 6 Reviewed by Hajime Morita. 7 8 Distribution should be resolved from shallower ShadowDOM to deeper Shadow DOM. However, in the current implementation, 9 there is a case that distribution for deeper ShadowDOM happens to be resolved before distribution 10 for shallower ShadowDOM is resolved. 11 12 Here, we have 2 problems about distribution. 13 1) Invalidation state is not propagated to nested (= deeper) ShadowDOM. 14 - This causes deeper ShadowDOM looks having a valid distribution though it should be invalid. 15 2) We are not resolving shallower ShadowDOM when deeper ShadowDOM's distribution is needed. 16 - Because of (1), we have to check all the ancestor ShadowDOM. 17 18 For (1), we change invalidate() to invalidate nested ShadowDOM's distribution as well. 19 For (2), when resolving distribution, we will check the ancestor ShadowDOM's distribution state. If the ancestor's 20 distribution is not valid, we resolve it first. 21 22 For optimization of (1), actually we can skip invalidating distribution of some ShadowDOMs. 23 If ShadowRoot of deeper ShadowDOM does not have an InsertionPoint as children, we can skip invalidating 24 its distribution, because only children can be distributed to InsertionPoint. 25 26 Tests: fast/dom/shadow/distribution-crash.html 27 fast/dom/shadow/nested-reprojection-inconsistent.html 28 29 * dom/ElementShadow.cpp: 30 (WebCore::ElementShadow::attach): Should resolve distribution from ancestor. 31 * dom/ElementShadow.h: 32 * html/shadow/ContentDistributor.cpp: 33 (WebCore::ContentDistributor::distribute): Added ASSERT that the parent ShadowRoot's distribution is resolved. 34 (WebCore::ContentDistributor::invalidate): For each InsertionPoint, we have to invalidate 35 its parent element's distribution (if it has ElementShadow). 36 (WebCore::ContentDistributor::ensureDistribution): 37 * html/shadow/ContentDistributor.h: 38 (WebCore::ContentDistributor::isValid): 39 * html/shadow/HTMLShadowElement.cpp: 40 (WebCore::HTMLShadowElement::olderShadowRoot): Should resolve distribution from ancestor. 41 * html/shadow/InsertionPoint.cpp: 42 (WebCore::InsertionPoint::attach): ditto. 43 (WebCore::InsertionPoint::detach): ditto. 44 (WebCore::InsertionPoint::getDistributedNodes): ditto. 45 (WebCore::resolveReprojection): ditto. 46 1 47 2013-01-20 Dominic Mazzoni <dmazzoni@google.com> 2 48 -
trunk/Source/WebCore/dom/ElementShadow.cpp
r139269 r140299 123 123 void ElementShadow::attach() 124 124 { 125 ensureDistribution(); 125 ContentDistributor::ensureDistribution(youngestShadowRoot()); 126 126 127 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { 127 128 if (!root->attached()) -
trunk/Source/WebCore/dom/ElementShadow.h
r139325 r140299 65 65 66 66 void invalidateDistribution() { m_distributor.invalidateDistribution(host()); } 67 void ensureDistribution() { m_distributor.ensureDistribution(host()); }68 67 void didAffectSelector(AffectedSelectorMask mask) { m_distributor.didAffectSelector(host(), mask); } 69 68 void willAffectSelector() { m_distributor.willAffectSelector(host()); } -
trunk/Source/WebCore/html/shadow/ContentDistributor.cpp
r139410 r140299 214 214 ASSERT(needsDistribution()); 215 215 ASSERT(m_nodeToInsertionPoint.isEmpty()); 216 ASSERT(!host->containingShadowRoot() || host->containingShadowRoot()->owner()->distributor().isValid()); 216 217 217 218 m_validity = Valid; … … 281 282 needsReattach = needsReattach || true; 282 283 insertionPoints[i]->clearDistribution(); 284 285 // After insertionPoint's distribution is invalidated, its reprojection should also be invalidated. 286 if (!insertionPoints[i]->isActive()) 287 continue; 288 289 if (Element* parent = insertionPoints[i]->parentElement()) { 290 if (ElementShadow* shadow = parent->shadow()) 291 shadow->invalidateDistribution(); 292 } 283 293 } 284 294 } … … 339 349 } 340 350 341 void ContentDistributor::ensureDistribution(Element* host) 342 { 343 if (!needsDistribution()) 344 return; 345 distribute(host); 346 } 347 348 void ContentDistributor::ensureDistributionFromDocument(Element* source) 349 { 350 ContainerNode* mayShadow = source->treeScope()->rootNode(); 351 if (!mayShadow->isShadowRoot()) 352 return; 353 354 Vector<Element*, 8> hosts; 355 for (Element* current = toShadowRoot(mayShadow)->host(); current; current = current->shadowHost()) 356 hosts.append(current); 357 358 for (size_t i = hosts.size(); i > 0; --i) 359 hosts[i - 1]->shadow()->ensureDistribution(); 351 void ContentDistributor::ensureDistribution(ShadowRoot* shadowRoot) 352 { 353 ASSERT(shadowRoot); 354 355 Vector<ElementShadow*, 8> elementShadows; 356 for (Element* current = shadowRoot->host(); current; current = current->shadowHost()) { 357 ElementShadow* elementShadow = current->shadow(); 358 if (!elementShadow->distributor().needsDistribution()) 359 break; 360 361 elementShadows.append(elementShadow); 362 } 363 364 for (size_t i = elementShadows.size(); i > 0; --i) 365 elementShadows[i - 1]->distributor().distribute(elementShadows[i - 1]->host()); 360 366 } 361 367 -
trunk/Source/WebCore/html/shadow/ContentDistributor.h
r139269 r140299 129 129 void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*); 130 130 131 void ensureDistribution(Element* host);132 131 void invalidateDistribution(Element* host); 133 132 void didShadowBoundaryChange(Element* host); … … 135 134 void willAffectSelector(Element* host); 136 135 137 static void ensureDistribution FromDocument(Element* source);136 static void ensureDistribution(ShadowRoot*); 138 137 139 138 private: … … 147 146 148 147 void setValidity(Validity validity) { m_validity = validity; } 148 bool isValid() const { return m_validity == Valid; } 149 149 bool needsDistribution() const; 150 150 bool needsInvalidation() const { return m_validity != Invalidated; } -
trunk/Source/WebCore/html/shadow/HTMLShadowElement.cpp
r139410 r140299 59 59 ShadowRoot* HTMLShadowElement::olderShadowRoot() 60 60 { 61 if (!treeScope()->rootNode()->isShadowRoot()) 61 ShadowRoot* containingRoot = containingShadowRoot(); 62 if (!containingRoot) 62 63 return 0; 63 64 64 ContentDistributor::ensureDistribution FromDocument(this);65 ContentDistributor::ensureDistribution(containingRoot); 65 66 66 ShadowRoot* older = toShadowRoot(treeScope()->rootNode())->olderShadowRoot();67 ShadowRoot* older = containingRoot->olderShadowRoot(); 67 68 if (!older || older->type() != ShadowRoot::AuthorShadowRoot || ScopeContentDistribution::assignedTo(older) != this) 68 69 return 0; -
trunk/Source/WebCore/html/shadow/InsertionPoint.cpp
r139400 r140299 54 54 void InsertionPoint::attach() 55 55 { 56 if (ShadowRoot* root = containingShadowRoot())57 root->owner()->ensureDistribution();56 if (ShadowRoot* shadowRoot = containingShadowRoot()) 57 ContentDistributor::ensureDistribution(shadowRoot); 58 58 for (size_t i = 0; i < m_distribution.size(); ++i) { 59 59 if (!m_distribution.at(i)->attached()) … … 66 66 void InsertionPoint::detach() 67 67 { 68 if (ShadowRoot* root = containingShadowRoot()) 69 root->owner()->ensureDistribution(); 68 if (ShadowRoot* shadowRoot = containingShadowRoot()) 69 ContentDistributor::ensureDistribution(shadowRoot); 70 70 71 for (size_t i = 0; i < m_distribution.size(); ++i) 71 72 m_distribution.at(i)->detach(); … … 100 101 PassRefPtr<NodeList> InsertionPoint::getDistributedNodes() const 101 102 { 102 ContentDistributor::ensureDistributionFromDocument(const_cast<InsertionPoint*>(this)); 103 if (ShadowRoot* shadowRoot = containingShadowRoot()) 104 ContentDistributor::ensureDistribution(shadowRoot); 103 105 104 106 Vector<RefPtr<Node> > nodes; … … 205 207 while (current) { 206 208 if (ElementShadow* shadow = shadowOfParentForDistribution(current)) { 207 shadow->ensureDistribution(); 209 if (ShadowRoot* root = current->containingShadowRoot()) 210 ContentDistributor::ensureDistribution(root); 208 211 if (InsertionPoint* insertedTo = shadow->distributor().findInsertionPointFor(projectedNode)) { 209 212 current = insertedTo;
Note: See TracChangeset
for help on using the changeset viewer.