Changeset 206880 in webkit
- Timestamp:
- Oct 6, 2016, 1:53:08 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r206868 r206880 1 2016-10-06 Antti Koivisto <antti@apple.com> 2 3 Mutating styleSheet in shadow tree doesn't update the style 4 https://bugs.webkit.org/show_bug.cgi?id=162744 5 <rdar://problem/28550588> 6 7 Reviewed by Ryosuke Niwa. 8 9 * fast/shadow-dom/mutating-stylesheet-in-shadow-tree-expected.html: Added. 10 * fast/shadow-dom/mutating-stylesheet-in-shadow-tree.html: Added. 11 1 12 2016-10-06 Adam Bergkvist <adam.bergkvist@ericsson.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r206879 r206880 1 2016-10-06 Antti Koivisto <antti@apple.com> 2 3 Mutating styleSheet in shadow tree doesn't update the style 4 https://bugs.webkit.org/show_bug.cgi?id=162744 5 <rdar://problem/28550588> 6 7 Reviewed by Ryosuke Niwa. 8 9 We weren't always invalidating the right AuthorStyleSheets (to be renamed) instance 10 for the scope after mutations. 11 12 Test: fast/shadow-dom/mutating-stylesheet-in-shadow-tree.html 13 14 * css/CSSStyleSheet.cpp: 15 (WebCore::CSSStyleSheet::didMutateRules): 16 (WebCore::CSSStyleSheet::didMutate): 17 (WebCore::CSSStyleSheet::clearOwnerNode): 18 (WebCore::CSSStyleSheet::rootStyleSheet): 19 (WebCore::CSSStyleSheet::ownerDocument): 20 (WebCore::CSSStyleSheet::styleSheetScope): 21 22 Invalidate the right scope after stylesheet mutations. 23 24 * css/CSSStyleSheet.h: 25 * dom/AuthorStyleSheets.cpp: 26 (WebCore::AuthorStyleSheets::styleResolver): 27 (WebCore::AuthorStyleSheets::styleResolverIfExists): 28 29 Take care to update the right style resolver. 30 31 (WebCore::AuthorStyleSheets::forNode): 32 (WebCore::AuthorStyleSheets::removeStyleSheetCandidateNode): 33 34 Start the update timer so clients don't need to request update separately. 35 36 (WebCore::AuthorStyleSheets::analyzeStyleSheetChange): 37 (WebCore::AuthorStyleSheets::updateActiveStyleSheets): 38 (WebCore::AuthorStyleSheets::updateStyleResolver): 39 * dom/AuthorStyleSheets.h: 40 * dom/InlineStyleSheetOwner.cpp: 41 (WebCore::InlineStyleSheetOwner::insertedIntoDocument): 42 43 Save the scope we were inserted into so removals can be done reliably. 44 45 (WebCore::InlineStyleSheetOwner::removedFromDocument): 46 47 Use and clear the saved scope. 48 Remove didChangeCandidatesForActiveSet() as it is now done by removeStyleSheetCandidateNode() call. 49 50 (WebCore::InlineStyleSheetOwner::clearDocumentData): 51 (WebCore::InlineStyleSheetOwner::createSheet): 52 (WebCore::InlineStyleSheetOwner::sheetLoaded): 53 (WebCore::InlineStyleSheetOwner::startLoadingDynamicSheet): 54 (WebCore::authorStyleSheetsForElement): Deleted. 55 * dom/InlineStyleSheetOwner.h: 56 (WebCore::InlineStyleSheetOwner::styleSheetScope): 57 * dom/ShadowRoot.cpp: 58 (WebCore::ShadowRoot::styleResolverIfExists): 59 * dom/ShadowRoot.h: 60 * html/HTMLLinkElement.cpp: 61 (WebCore::HTMLLinkElement::removedFrom): 62 63 Remove didChangeCandidatesForActiveSet() as it is now done by removeStyleSheetCandidateNode() call. 64 65 * html/HTMLStyleElement.cpp: 66 (WebCore::HTMLStyleElement::~HTMLStyleElement): 67 (WebCore::HTMLStyleElement::parseAttribute): 68 69 Fix a bug where we wouldn't create stylesheet if a style element was activated by removing a media attribute. 70 71 (WebCore::HTMLStyleElement::insertedInto): 72 (WebCore::HTMLStyleElement::removedFrom): 73 * page/DOMWindow.cpp: 74 (WebCore::DOMWindow::getMatchedCSSRules): 75 * svg/SVGStyleElement.cpp: 76 (WebCore::SVGStyleElement::~SVGStyleElement): 77 (WebCore::SVGStyleElement::insertedInto): 78 (WebCore::SVGStyleElement::removedFrom): 79 1 80 2016-10-06 Alex Christensen <achristensen@webkit.org> 2 81 -
trunk/Source/WebCore/css/CSSStyleSheet.cpp
r206361 r206880 42 42 #include "SVGStyleElement.h" 43 43 #include "SecurityOrigin.h" 44 #include "ShadowRoot.h" 44 45 #include "StyleResolver.h" 45 46 #include "StyleRule.h" … … 170 171 ASSERT(m_contents->hasOneClient()); 171 172 172 Document* owner = ownerDocument();173 if (! owner)173 auto* scope = styleSheetScope(); 174 if (!scope) 174 175 return; 175 176 176 if (mutationType == RuleInsertion && !contentsWereClonedForMutation && ! owner->authorStyleSheets().activeStyleSheetsContains(this)) {177 if (mutationType == RuleInsertion && !contentsWereClonedForMutation && !scope->activeStyleSheetsContains(this)) { 177 178 if (insertedKeyframesRule) { 178 if ( StyleResolver* resolver = owner->styleResolverIfExists())179 if (auto* resolver = scope->styleResolverIfExists()) 179 180 resolver->addKeyframeStyle(*insertedKeyframesRule); 180 181 return; 181 182 } 182 owner->authorStyleSheets().scheduleActiveSetUpdate();183 scope->scheduleActiveSetUpdate(); 183 184 return; 184 185 } 185 186 186 owner->authorStyleSheets().didChangeContentsOrInterpretation();187 scope->didChangeContentsOrInterpretation(); 187 188 188 189 m_mutatedRules = true; … … 191 192 void CSSStyleSheet::didMutate() 192 193 { 193 Document* owner = ownerDocument();194 if (! owner)194 auto* scope = styleSheetScope(); 195 if (!scope) 195 196 return; 196 owner->authorStyleSheets().didChangeContentsOrInterpretation();197 scope->didChangeContentsOrInterpretation(); 197 198 } 198 199 199 200 void CSSStyleSheet::clearOwnerNode() 200 201 { 201 Document* owner = ownerDocument(); 202 m_ownerNode = 0; 203 if (!owner) 204 return; 205 owner->authorStyleSheets().didChangeCandidatesForActiveSet(); 202 m_ownerNode = nullptr; 206 203 } 207 204 … … 400 397 } 401 398 402 Document* CSSStyleSheet::ownerDocument() const 403 { 404 const CSSStyleSheet* root = this;399 CSSStyleSheet& CSSStyleSheet::rootStyleSheet() 400 { 401 auto* root = this; 405 402 while (root->parentStyleSheet()) 406 403 root = root->parentStyleSheet(); 407 return root->ownerNode() ? &root->ownerNode()->document() : nullptr; 404 return *root; 405 } 406 407 const CSSStyleSheet& CSSStyleSheet::rootStyleSheet() const 408 { 409 return const_cast<CSSStyleSheet&>(*this).rootStyleSheet(); 410 } 411 412 Document* CSSStyleSheet::ownerDocument() const 413 { 414 auto& root = rootStyleSheet(); 415 return root.ownerNode() ? &root.ownerNode()->document() : nullptr; 416 } 417 418 AuthorStyleSheets* CSSStyleSheet::styleSheetScope() 419 { 420 auto* ownerNode = rootStyleSheet().ownerNode(); 421 if (!ownerNode) 422 return nullptr; 423 return &AuthorStyleSheets::forNode(*ownerNode); 408 424 } 409 425 -
trunk/Source/WebCore/css/CSSStyleSheet.h
r205455 r206880 32 32 namespace WebCore { 33 33 34 class AuthorStyleSheets; 34 35 class CSSCharsetRule; 35 36 class CSSImportRule; … … 83 84 84 85 void clearOwnerRule() { m_ownerRule = 0; } 86 85 87 Document* ownerDocument() const; 88 CSSStyleSheet& rootStyleSheet(); 89 const CSSStyleSheet& rootStyleSheet() const; 90 AuthorStyleSheets* styleSheetScope(); 91 86 92 MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); } 87 93 void setMediaQueries(Ref<MediaQuerySet>&&); -
trunk/Source/WebCore/dom/AuthorStyleSheets.cpp
r206641 r206880 70 70 } 71 71 72 StyleResolver& AuthorStyleSheets::styleResolver() 73 { 74 if (m_shadowRoot) 75 return m_shadowRoot->styleResolver(); 76 77 return m_document.ensureStyleResolver(); 78 } 79 80 StyleResolver* AuthorStyleSheets::styleResolverIfExists() 81 { 82 if (m_shadowRoot) 83 return m_shadowRoot->styleResolverIfExists(); 84 85 return m_document.styleResolverIfExists(); 86 } 87 88 AuthorStyleSheets& AuthorStyleSheets::forNode(Node& node) 89 { 90 ASSERT(node.inDocument()); 91 auto* shadowRoot = node.containingShadowRoot(); 92 if (shadowRoot) 93 return shadowRoot->authorStyleSheets(); 94 return node.document().authorStyleSheets(); 95 } 96 72 97 // This method is called whenever a top-level stylesheet has finished loading. 73 98 void AuthorStyleSheets::removePendingSheet(RemovePendingSheetNotificationType notification) … … 134 159 void AuthorStyleSheets::removeStyleSheetCandidateNode(Node& node) 135 160 { 136 m_styleSheetCandidateNodes.remove(&node); 161 if (m_styleSheetCandidateNodes.remove(&node)) 162 scheduleActiveSetUpdate(); 137 163 } 138 164 … … 221 247 unsigned newStylesheetCount = newStylesheets.size(); 222 248 223 if (! m_document.styleResolverIfExists())249 if (!styleResolverIfExists()) 224 250 return Reconstruct; 225 251 226 StyleResolver& styleResolver = * m_document.styleResolverIfExists();252 StyleResolver& styleResolver = *styleResolverIfExists(); 227 253 228 254 // Find out which stylesheets are new. … … 307 333 } 308 334 335 // FIXME: Support optimized invalidation in shadow trees. 336 if (m_shadowRoot) 337 updateType = UpdateType::ContentsOrInterpretation; 338 309 339 m_didUpdateActiveStyleSheets = true; 310 340 … … 353 383 return; 354 384 } 355 auto& styleResolver = m_document.ensureStyleResolver(); 356 auto& userAgentShadowTreeStyleResolver = m_document.userAgentShadowTreeStyleResolver(); 385 auto& styleResolver = this->styleResolver(); 357 386 358 387 if (updateType == Reset) { … … 367 396 } 368 397 369 userAgentShadowTreeStyleResolver.ruleSets().resetAuthorStyle(); 370 auto& authorRuleSet = styleResolver.ruleSets().authorStyle(); 371 if (authorRuleSet.hasShadowPseudoElementRules()) 372 userAgentShadowTreeStyleResolver.ruleSets().authorStyle().copyShadowPseudoElementRulesFrom(authorRuleSet); 398 if (!m_shadowRoot) { 399 auto& userAgentShadowTreeStyleResolver = m_document.userAgentShadowTreeStyleResolver(); 400 userAgentShadowTreeStyleResolver.ruleSets().resetAuthorStyle(); 401 auto& authorRuleSet = styleResolver.ruleSets().authorStyle(); 402 if (authorRuleSet.hasShadowPseudoElementRules()) 403 userAgentShadowTreeStyleResolver.ruleSets().authorStyle().copyShadowPseudoElementRulesFrom(authorRuleSet); 404 } 373 405 } 374 406 … … 423 455 void AuthorStyleSheets::scheduleActiveSetUpdate() 424 456 { 457 if (m_shadowRoot) { 458 // FIXME: We need to flush updates recursively to support asynchronous updates in shadow trees. 459 didChangeCandidatesForActiveSet(); 460 return; 461 } 425 462 if (m_pendingUpdateTimer.isActive()) 426 463 return; -
trunk/Source/WebCore/dom/AuthorStyleSheets.h
r206641 r206880 43 43 class Document; 44 44 class Node; 45 class StyleResolver; 45 46 class StyleSheet; 46 47 class StyleSheetContents; … … 87 88 bool hasPendingUpdate() const { return !!m_pendingUpdateType; } 88 89 void flushPendingUpdate(); 90 91 StyleResolver& styleResolver(); 92 StyleResolver* styleResolverIfExists(); 93 94 static AuthorStyleSheets& forNode(Node&); 89 95 90 96 private: -
trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp
r206361 r206880 50 50 } 51 51 52 static AuthorStyleSheets& authorStyleSheetsForElement(Element& element)52 void InlineStyleSheetOwner::insertedIntoDocument(Element& element) 53 53 { 54 auto* shadowRoot = element.containingShadowRoot(); 55 return shadowRoot ? shadowRoot->authorStyleSheets() : element.document().authorStyleSheets(); 56 } 57 58 void InlineStyleSheetOwner::insertedIntoDocument(Document&, Element& element) 59 { 60 authorStyleSheetsForElement(element).addStyleSheetCandidateNode(element, m_isParsingChildren); 54 m_styleSheetScope = &AuthorStyleSheets::forNode(element); 55 m_styleSheetScope->addStyleSheetCandidateNode(element, m_isParsingChildren); 61 56 62 57 if (m_isParsingChildren) … … 65 60 } 66 61 67 void InlineStyleSheetOwner::removedFromDocument( Document& document,Element& element)62 void InlineStyleSheetOwner::removedFromDocument(Element& element) 68 63 { 69 authorStyleSheetsForElement(element).removeStyleSheetCandidateNode(element); 70 64 if (m_styleSheetScope) { 65 m_styleSheetScope->removeStyleSheetCandidateNode(element); 66 m_styleSheetScope = nullptr; 67 } 71 68 if (m_sheet) 72 69 clearSheet(); 73 74 // If we're in document teardown, then we don't need to do any notification of our sheet's removal.75 if (document.hasLivingRenderTree())76 document.authorStyleSheets().didChangeContentsOrInterpretation();77 70 } 78 71 79 void InlineStyleSheetOwner::clearDocumentData( Document&,Element& element)72 void InlineStyleSheetOwner::clearDocumentData(Element& element) 80 73 { 81 74 if (m_sheet) 82 75 m_sheet->clearOwnerNode(); 83 76 84 if (!element.inDocument()) 85 return; 86 authorStyleSheetsForElement(element).removeStyleSheetCandidateNode(element); 77 if (m_styleSheetScope) { 78 m_styleSheetScope->removeStyleSheetCandidateNode(element); 79 m_styleSheetScope = nullptr; 80 } 87 81 } 88 82 … … 131 125 Document& document = element.document(); 132 126 if (m_sheet) { 133 if (m_sheet->isLoading() )134 document.authorStyleSheets().removePendingSheet();127 if (m_sheet->isLoading() && m_styleSheetScope) 128 m_styleSheetScope->removePendingSheet(); 135 129 clearSheet(); 136 130 } … … 156 150 return; 157 151 158 authorStyleSheetsForElement(element).addPendingSheet(); 152 if (m_styleSheetScope) 153 m_styleSheetScope->addPendingSheet(); 159 154 160 155 m_loading = true; … … 178 173 } 179 174 180 bool InlineStyleSheetOwner::sheetLoaded(Element& element)175 bool InlineStyleSheetOwner::sheetLoaded(Element&) 181 176 { 182 177 if (isLoading()) 183 178 return false; 184 179 185 authorStyleSheetsForElement(element).removePendingSheet(); 180 if (m_styleSheetScope) 181 m_styleSheetScope->removePendingSheet(); 182 186 183 return true; 187 184 } 188 185 189 void InlineStyleSheetOwner::startLoadingDynamicSheet(Element& element)186 void InlineStyleSheetOwner::startLoadingDynamicSheet(Element&) 190 187 { 191 authorStyleSheetsForElement(element).addPendingSheet(); 188 if (m_styleSheetScope) 189 m_styleSheetScope->addPendingSheet(); 192 190 } 193 191 -
trunk/Source/WebCore/dom/InlineStyleSheetOwner.h
r190256 r206880 45 45 void startLoadingDynamicSheet(Element&); 46 46 47 void insertedIntoDocument( Document&,Element&);48 void removedFromDocument( Document&,Element&);49 void clearDocumentData( Document&,Element&);47 void insertedIntoDocument(Element&); 48 void removedFromDocument(Element&); 49 void clearDocumentData(Element&); 50 50 void childrenChanged(Element&); 51 51 void finishParsingChildren(Element&); 52 53 AuthorStyleSheets* styleSheetScope() { return m_styleSheetScope; } 52 54 53 55 private: … … 62 64 AtomicString m_media; 63 65 RefPtr<CSSStyleSheet> m_sheet; 66 AuthorStyleSheets* m_styleSheetScope { nullptr }; 64 67 }; 65 68 -
trunk/Source/WebCore/dom/ShadowRoot.cpp
r206361 r206880 95 95 } 96 96 97 StyleResolver* ShadowRoot::styleResolverIfExists() 98 { 99 if (m_type == Mode::UserAgent) 100 return &document().userAgentShadowTreeStyleResolver(); 101 102 return m_styleResolver.get(); 103 } 104 97 105 void ShadowRoot::resetStyleResolver() 98 106 { -
trunk/Source/WebCore/dom/ShadowRoot.h
r204543 r206880 64 64 65 65 StyleResolver& styleResolver(); 66 StyleResolver* styleResolverIfExists(); 66 67 AuthorStyleSheets& authorStyleSheets(); 67 68 68 69 void updateStyle(); 69 70 void resetStyleResolver(); -
trunk/Source/WebCore/html/HTMLLinkElement.cpp
r206867 r206880 329 329 if (styleSheetIsLoading()) 330 330 removePendingSheet(RemovePendingSheetNotifyLater); 331 332 if (document().hasLivingRenderTree())333 document().authorStyleSheets().didChangeCandidatesForActiveSet();334 331 } 335 332 -
trunk/Source/WebCore/html/HTMLStyleElement.cpp
r206603 r206880 59 59 HTMLStyleElement::~HTMLStyleElement() 60 60 { 61 // During tear-down, willRemove isn't called, so m_scopedStyleRegistrationState may still be RegisteredAsScoped or RegisteredInShadowRoot here. 62 // Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered). 63 m_styleSheetOwner.clearDocumentData(document(), *this); 61 m_styleSheetOwner.clearDocumentData(*this); 64 62 65 63 styleLoadEventSender().cancelEvent(*this); … … 79 77 if (sheet()) { 80 78 sheet()->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(value)); 81 if (inDocument() && document().hasLivingRenderTree()) 82 document().authorStyleSheets().didChangeContentsOrInterpretation(); 83 } 79 if (auto* scope = m_styleSheetOwner.styleSheetScope()) 80 scope->didChangeContentsOrInterpretation(); 81 } else 82 m_styleSheetOwner.childrenChanged(*this); 84 83 } else if (name == typeAttr) 85 84 m_styleSheetOwner.setContentType(value); … … 98 97 HTMLElement::insertedInto(insertionPoint); 99 98 if (insertionPoint.inDocument()) 100 m_styleSheetOwner.insertedIntoDocument( document(),*this);99 m_styleSheetOwner.insertedIntoDocument(*this); 101 100 102 101 return InsertionDone; … … 108 107 109 108 if (insertionPoint.inDocument()) 110 m_styleSheetOwner.removedFromDocument( document(),*this);109 m_styleSheetOwner.removedFromDocument(*this); 111 110 } 112 111 -
trunk/Source/WebCore/page/DOMWindow.cpp
r206751 r206880 28 28 #include "DOMWindow.h" 29 29 30 #include "AuthorStyleSheets.h" 30 31 #include "BackForwardController.h" 31 32 #include "BarProp.h" … … 1432 1433 return nullptr; 1433 1434 1435 m_frame->document()->authorStyleSheets().flushPendingUpdate(); 1436 1434 1437 unsigned rulesToInclude = StyleResolver::AuthorCSSRules; 1435 1438 if (!authorOnly) -
trunk/Source/WebCore/svg/SVGStyleElement.cpp
r203324 r206880 42 42 SVGStyleElement::~SVGStyleElement() 43 43 { 44 m_styleSheetOwner.clearDocumentData( document(),*this);44 m_styleSheetOwner.clearDocumentData(*this); 45 45 } 46 46 … … 124 124 SVGElement::insertedInto(rootParent); 125 125 if (rootParent.inDocument()) 126 m_styleSheetOwner.insertedIntoDocument( document(),*this);126 m_styleSheetOwner.insertedIntoDocument(*this); 127 127 return InsertionDone; 128 128 } … … 132 132 SVGElement::removedFrom(rootParent); 133 133 if (rootParent.inDocument()) 134 m_styleSheetOwner.removedFromDocument( document(),*this);134 m_styleSheetOwner.removedFromDocument(*this); 135 135 } 136 136
Note:
See TracChangeset
for help on using the changeset viewer.