Changeset 196031 in webkit
- Timestamp:
- Feb 2, 2016 2:34:45 PM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r195999 r196031 2640 2640 style/StyleFontSizeFunctions.cpp 2641 2641 style/StyleResolveForDocument.cpp 2642 style/StyleSharingResolver.cpp 2642 2643 style/StyleTreeResolver.cpp 2643 2644 -
trunk/Source/WebCore/ChangeLog
r196028 r196031 1 2016-02-02 Antti Koivisto <antti@apple.com> 2 3 Factor style sharing code out of StyleResolver 4 https://bugs.webkit.org/show_bug.cgi?id=153768 5 6 Reviewed by Darin Adler. 7 8 Move the code to a new class, Style::SharingResolver. 9 10 When resolving document style we query the sharing resolver first before using the regular style resolver. 11 Other paths that call style resolver were mostly already disabling it with DisallowStyleSharing flag. 12 13 * WebCore.xcodeproj/project.pbxproj: 14 * css/ElementRuleCollector.cpp: 15 (WebCore::MatchRequest::MatchRequest): 16 (WebCore::ElementRuleCollector::matchAllRules): 17 (WebCore::ElementRuleCollector::hasAnyMatchingRules): 18 19 More const. 20 21 * css/ElementRuleCollector.h: 22 (WebCore::ElementRuleCollector::setRegionForStyling): 23 (WebCore::ElementRuleCollector::setMedium): 24 * css/MediaQueryMatcher.cpp: 25 (WebCore::MediaQueryMatcher::prepareEvaluator): 26 * css/StyleMedia.cpp: 27 (WebCore::StyleMedia::matchMedium): 28 * css/StyleResolver.cpp: 29 (WebCore::StyleResolver::State::cacheBorderAndBackground): 30 (WebCore::StyleResolver::StyleResolver): 31 (WebCore::StyleResolver::sweepMatchedPropertiesCache): 32 (WebCore::StyleResolver::State::State): 33 (WebCore::StyleResolver::State::setStyle): 34 (WebCore::isAtShadowBoundary): 35 (WebCore::StyleResolver::styleForElement): 36 (WebCore::StyleResolver::classNamesAffectedByRules): Deleted. 37 (WebCore::parentElementPreventsSharing): Deleted. 38 (WebCore::StyleResolver::locateCousinList): Deleted. 39 (WebCore::StyleResolver::styleSharingCandidateMatchesRuleSet): Deleted. 40 (WebCore::StyleResolver::canShareStyleWithControl): Deleted. 41 (WebCore::elementHasDirectionAuto): Deleted. 42 (WebCore::StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes): Deleted. 43 (WebCore::StyleResolver::canShareStyleWithElement): Deleted. 44 (WebCore::StyleResolver::findSiblingForStyleSharing): Deleted. 45 (WebCore::StyleResolver::locateSharedStyle): Deleted. 46 47 Style sharing code moves to SharingResolver. 48 49 * css/StyleResolver.h: 50 (WebCore::StyleResolver::mediaQueryEvaluator): 51 (WebCore::StyleResolver::State::regionForStyling): 52 (WebCore::StyleResolver::State::elementLinkState): 53 (WebCore::StyleResolver::State::setApplyPropertyToRegularStyle): 54 (WebCore::StyleResolver::State::setApplyPropertyToVisitedLinkStyle): 55 (WebCore::StyleResolver::state): 56 (WebCore::StyleResolver::setTextOrientation): 57 (WebCore::StyleResolver::State::setElementAffectedByClassRules): Deleted. 58 (WebCore::StyleResolver::State::elementAffectedByClassRules): Deleted. 59 (WebCore::StyleResolver::styleNotYetAvailable): Deleted. 60 61 Placeholder code moves to TreeResolver. 62 63 * dom/VisitedLinkState.cpp: 64 (WebCore::linkAttribute): 65 (WebCore::VisitedLinkState::invalidateStyleForAllLinks): 66 (WebCore::linkHashForElement): 67 (WebCore::VisitedLinkState::invalidateStyleForLink): 68 (WebCore::VisitedLinkState::determineLinkStateSlowCase): 69 * dom/VisitedLinkState.h: 70 (WebCore::VisitedLinkState::determineLinkState): 71 * html/HTMLFormControlElement.h: 72 * rendering/RenderElement.cpp: 73 (WebCore::RenderElement::getUncachedPseudoStyle): 74 * rendering/RenderNamedFlowFragment.cpp: 75 (WebCore::RenderNamedFlowFragment::computeStyleInRegion): 76 * rendering/style/RenderStyle.cpp: 77 (WebCore::RenderStyle::isStyleAvailable): 78 (WebCore::RenderStyle::hasUniquePseudoStyle): 79 * style/StyleSharingResolver.cpp: Added. 80 (WebCore::Style::SharingResolver::SharingResolver): 81 (WebCore::Style::parentElementPreventsSharing): 82 (WebCore::Style::elementHasDirectionAuto): 83 (WebCore::Style::SharingResolver::searchSimilar): 84 (WebCore::Style::SharingResolver::findSibling): 85 (WebCore::Style::SharingResolver::locateCousinList): 86 (WebCore::Style::canShareStyleWithControl): 87 (WebCore::Style::SharingResolver::canShareStyleWithElement): 88 (WebCore::Style::SharingResolver::styleSharingCandidateMatchesRuleSet): 89 (WebCore::Style::SharingResolver::sharingCandidateHasIdenticalStyleAffectingAttributes): 90 (WebCore::Style::SharingResolver::classNamesAffectedByRules): 91 * style/StyleSharingResolver.h: Added. 92 * style/StyleTreeResolver.cpp: 93 (WebCore::Style::ensurePlaceholderStyle): 94 (WebCore::Style::TreeResolver::TreeResolver): 95 (WebCore::Style::TreeResolver::styleForElement): 96 97 Try to use SharingResolver first. 98 Also move placeholder style handling here, it is only relevant when resolving document style. 99 100 (WebCore::Style::postResolutionCallbacksAreSuspended): 101 (WebCore::Style::isPlaceholderStyle): 102 * style/StyleTreeResolver.h: 103 * svg/SVGElement.cpp: 104 (WebCore::SVGElement::customStyleForRenderer): 105 * svg/SVGElementRareData.h: 106 (WebCore::SVGElementRareData::overrideComputedStyle): 107 1 108 2016-02-02 Tim Horton <timothy_horton@apple.com> 2 109 -
trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
r195948 r196031 19246 19246 <ClCompile Include="..\style\StyleFontSizeFunctions.cpp" /> 19247 19247 <ClCompile Include="..\style\StyleResolveForDocument.cpp" /> 19248 <ClCompile Include="..\style\StyleSharingResolver.cpp" /> 19248 19249 <ClCompile Include="..\style\StyleTreeResolver.cpp" /> 19249 19250 <ClCompile Include="..\bridge\jsc\BridgeJSC.cpp" /> … … 22813 22814 <ClInclude Include="..\style\StyleFontSizeFunctions.h" /> 22814 22815 <ClInclude Include="..\style\StyleResolveForDocument.h" /> 22816 <ClInclude Include="..\style\StyleSharingResolver.h" /> 22815 22817 <ClInclude Include="..\style\StyleTreeResolver.h" /> 22816 22818 <ClInclude Include="..\bridge\Bridge.h" /> -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r195999 r196031 6589 6589 E4778B7F115A581A00B5D372 /* JSCustomEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */; }; 6590 6590 E4778B80115A581A00B5D372 /* JSCustomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = E4778B7E115A581A00B5D372 /* JSCustomEvent.h */; }; 6591 E47A3AC31C5EABBE00CCBFA7 /* StyleSharingResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */; }; 6592 E47A3AC61C5EAC9D00CCBFA7 /* StyleSharingResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E47A3AC41C5EAC7900CCBFA7 /* StyleSharingResolver.h */; }; 6591 6593 E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = E47B4BE60E71241600038854 /* CachedResourceHandle.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6592 6594 E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */; }; … … 14554 14556 E4778B7D115A581A00B5D372 /* JSCustomEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomEvent.cpp; sourceTree = "<group>"; }; 14555 14557 E4778B7E115A581A00B5D372 /* JSCustomEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomEvent.h; sourceTree = "<group>"; }; 14558 E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSharingResolver.cpp; sourceTree = "<group>"; }; 14559 E47A3AC41C5EAC7900CCBFA7 /* StyleSharingResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSharingResolver.h; sourceTree = "<group>"; }; 14556 14560 E47A97CE163059FC005DCD99 /* StyleInvalidationAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleInvalidationAnalysis.cpp; sourceTree = "<group>"; }; 14557 14561 E47A97CF163059FC005DCD99 /* StyleInvalidationAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleInvalidationAnalysis.h; sourceTree = "<group>"; }; … … 23343 23347 E4DEAA1517A93DC3000E0430 /* StyleTreeResolver.cpp */, 23344 23348 E4DEAA1617A93DC3000E0430 /* StyleTreeResolver.h */, 23349 E47A3AC21C5EABBE00CCBFA7 /* StyleSharingResolver.cpp */, 23350 E47A3AC41C5EAC7900CCBFA7 /* StyleSharingResolver.h */, 23345 23351 ); 23346 23352 path = style; … … 26897 26903 439046E012DA25E17BAF80A2 /* MathMLOperatorDictionary.h in Headers */, 26898 26904 FA654A6C1108ABED002615E0 /* MathMLTextElement.h in Headers */, 26905 E47A3AC61C5EAC9D00CCBFA7 /* StyleSharingResolver.h in Headers */, 26899 26906 49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */, 26900 26907 49E911C70EF86D47009D0CAF /* MatrixTransformOperation.h in Headers */, … … 30092 30099 448A29C00A46D9CB0030759F /* JSHTMLOptionsCollection.cpp in Sources */, 30093 30100 448AD27C0A48137A0023D179 /* JSHTMLOptionsCollectionCustom.cpp in Sources */, 30101 E47A3AC31C5EABBE00CCBFA7 /* StyleSharingResolver.cpp in Sources */, 30094 30102 4AD0173C127E82860015035F /* JSHTMLOutputElement.cpp in Sources */, 30095 30103 1AE2ABA60A1CE90500B42B25 /* JSHTMLParagraphElement.cpp in Sources */, -
trunk/Source/WebCore/css/ElementRuleCollector.cpp
r195311 r196031 69 69 class MatchRequest { 70 70 public: 71 MatchRequest( RuleSet* ruleSet, bool includeEmptyRules = false)71 MatchRequest(const RuleSet* ruleSet, bool includeEmptyRules = false) 72 72 : ruleSet(ruleSet) 73 73 , includeEmptyRules(includeEmptyRules) … … 530 530 } 531 531 532 bool ElementRuleCollector::hasAnyMatchingRules( RuleSet* ruleSet)532 bool ElementRuleCollector::hasAnyMatchingRules(const RuleSet* ruleSet) 533 533 { 534 534 clearMatchedRules(); -
trunk/Source/WebCore/css/ElementRuleCollector.h
r195293 r196031 59 59 void setMedium(const MediaQueryEvaluator* medium) { m_isPrintStyle = medium->mediaTypeMatchSpecific("print"); } 60 60 61 bool hasAnyMatchingRules( RuleSet*);61 bool hasAnyMatchingRules(const RuleSet*); 62 62 63 63 StyleResolver::MatchResult& matchedResult(); -
trunk/Source/WebCore/css/MediaQueryMatcher.cpp
r195465 r196031 86 86 return nullptr; 87 87 88 RefPtr<RenderStyle> rootStyle = m_document->ensureStyleResolver().styleForElement(*documentElement, m_document->renderStyle(), DisallowStyleSharing,MatchOnlyUserAgentRules);88 RefPtr<RenderStyle> rootStyle = m_document->ensureStyleResolver().styleForElement(*documentElement, m_document->renderStyle(), MatchOnlyUserAgentRules); 89 89 90 90 return std::make_unique<MediaQueryEvaluator>(mediaType(), m_document->frame(), rootStyle.get()); -
trunk/Source/WebCore/css/StyleMedia.cpp
r195465 r196031 62 62 return false; 63 63 64 RefPtr<RenderStyle> rootStyle = document->ensureStyleResolver().styleForElement(*documentElement, document->renderStyle(), DisallowStyleSharing,MatchOnlyUserAgentRules);64 RefPtr<RenderStyle> rootStyle = document->ensureStyleResolver().styleForElement(*documentElement, document->renderStyle(), MatchOnlyUserAgentRules); 65 65 66 66 RefPtr<MediaQuerySet> media = MediaQuerySet::create(); -
trunk/Source/WebCore/css/StyleResolver.cpp
r195560 r196031 177 177 static void extractDirectionAndWritingMode(const RenderStyle&, const StyleResolver::MatchResult&, TextDirection&, WritingMode&); 178 178 179 RenderStyle* StyleResolver::s_styleNotYetAvailable;180 181 179 inline void StyleResolver::State::cacheBorderAndBackground() 182 180 { … … 265 263 266 264 if (root) 267 m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), DisallowStyleSharing,MatchOnlyUserAgentRules);265 m_rootDefaultStyle = styleForElement(*root, m_document.renderStyle(), MatchOnlyUserAgentRules); 268 266 269 267 if (m_rootDefaultStyle && view) … … 333 331 } 334 332 335 bool StyleResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const336 {337 for (unsigned i = 0; i < classNames.size(); ++i) {338 if (m_ruleSets.features().classesInRules.contains(classNames[i].impl()))339 return true;340 }341 return false;342 }343 344 333 StyleResolver::State::State(Element& element, RenderStyle* parentStyle, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter) 345 334 : m_element(&element) … … 370 359 updateConversionData(); 371 360 } 372 373 static const unsigned cStyleSearchThreshold = 10;374 static const unsigned cStyleSearchLevelThreshold = 10;375 376 static inline bool parentElementPreventsSharing(const Element* parentElement)377 {378 if (!parentElement)379 return false;380 return parentElement->hasFlagsSetDuringStylingOfChildren();381 }382 383 Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCount) const384 {385 if (visitedNodeCount >= cStyleSearchThreshold * cStyleSearchLevelThreshold)386 return nullptr;387 if (!is<StyledElement>(parent))388 return nullptr;389 StyledElement* styledParent = downcast<StyledElement>(parent);390 if (styledParent->inlineStyle())391 return nullptr;392 if (is<SVGElement>(*styledParent) && downcast<SVGElement>(*styledParent).animatedSMILStyleProperties())393 return nullptr;394 if (styledParent->hasID() && m_ruleSets.features().idsInRules.contains(styledParent->idForStyleResolution().impl()))395 return nullptr;396 397 RenderStyle* parentStyle = styledParent->renderStyle();398 unsigned subcount = 0;399 Node* thisCousin = styledParent;400 Node* currentNode = styledParent->previousSibling();401 402 // Reserve the tries for this level. This effectively makes sure that the algorithm403 // will never go deeper than cStyleSearchLevelThreshold levels into recursion.404 visitedNodeCount += cStyleSearchThreshold;405 while (thisCousin) {406 while (currentNode) {407 ++subcount;408 if (currentNode->renderStyle() == parentStyle && currentNode->lastChild()409 && is<Element>(*currentNode) && !parentElementPreventsSharing(downcast<Element>(currentNode))410 ) {411 // Adjust for unused reserved tries.412 visitedNodeCount -= cStyleSearchThreshold - subcount;413 return currentNode->lastChild();414 }415 if (subcount >= cStyleSearchThreshold)416 return nullptr;417 currentNode = currentNode->previousSibling();418 }419 currentNode = locateCousinList(thisCousin->parentElement(), visitedNodeCount);420 thisCousin = currentNode;421 }422 423 return nullptr;424 }425 426 bool StyleResolver::styleSharingCandidateMatchesRuleSet(RuleSet* ruleSet)427 {428 if (!ruleSet)429 return false;430 431 ElementRuleCollector collector(*m_state.element(), m_state.style(), m_ruleSets, m_state.selectorFilter());432 return collector.hasAnyMatchingRules(ruleSet);433 }434 435 bool StyleResolver::canShareStyleWithControl(StyledElement& element) const436 {437 const State& state = m_state;438 if (!is<HTMLInputElement>(element) || !is<HTMLInputElement>(*state.element()))439 return false;440 441 auto& thisInputElement = downcast<HTMLInputElement>(element);442 auto& otherInputElement = downcast<HTMLInputElement>(*state.element());443 444 if (thisInputElement.isAutoFilled() != otherInputElement.isAutoFilled())445 return false;446 if (thisInputElement.shouldAppearChecked() != otherInputElement.shouldAppearChecked())447 return false;448 if (thisInputElement.shouldAppearIndeterminate() != otherInputElement.shouldAppearIndeterminate())449 return false;450 if (thisInputElement.isRequired() != otherInputElement.isRequired())451 return false;452 453 if (element.isDisabledFormControl() != state.element()->isDisabledFormControl())454 return false;455 456 if (element.isDefaultButtonForForm() != state.element()->isDefaultButtonForForm())457 return false;458 459 if (element.isInRange() != state.element()->isInRange())460 return false;461 462 if (element.isOutOfRange() != state.element()->isOutOfRange())463 return false;464 465 return true;466 }467 468 static inline bool elementHasDirectionAuto(Element& element)469 {470 // FIXME: This line is surprisingly hot, we may wish to inline hasDirectionAuto into StyleResolver.471 return is<HTMLElement>(element) && downcast<HTMLElement>(element).hasDirectionAuto();472 }473 474 bool StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement& sharingCandidate) const475 {476 const State& state = m_state;477 if (state.element()->elementData() == sharingCandidate.elementData())478 return true;479 if (state.element()->fastGetAttribute(XMLNames::langAttr) != sharingCandidate.fastGetAttribute(XMLNames::langAttr))480 return false;481 if (state.element()->fastGetAttribute(langAttr) != sharingCandidate.fastGetAttribute(langAttr))482 return false;483 484 if (!state.elementAffectedByClassRules()) {485 if (sharingCandidate.hasClass() && classNamesAffectedByRules(sharingCandidate.classNames()))486 return false;487 } else if (sharingCandidate.hasClass()) {488 // SVG elements require a (slow!) getAttribute comparision because "class" is an animatable attribute for SVG.489 if (state.element()->isSVGElement()) {490 if (state.element()->getAttribute(classAttr) != sharingCandidate.getAttribute(classAttr))491 return false;492 } else {493 if (state.element()->classNames() != sharingCandidate.classNames())494 return false;495 }496 } else497 return false;498 499 if (downcast<StyledElement>(*state.element()).presentationAttributeStyle() != sharingCandidate.presentationAttributeStyle())500 return false;501 502 if (state.element()->hasTagName(progressTag)) {503 if (state.element()->shouldAppearIndeterminate() != sharingCandidate.shouldAppearIndeterminate())504 return false;505 }506 507 return true;508 }509 510 bool StyleResolver::canShareStyleWithElement(StyledElement& element) const511 {512 auto* style = element.renderStyle();513 const State& state = m_state;514 515 if (!style)516 return false;517 if (style->unique())518 return false;519 if (style->hasUniquePseudoStyle())520 return false;521 if (element.tagQName() != state.element()->tagQName())522 return false;523 if (element.inlineStyle())524 return false;525 if (element.needsStyleRecalc())526 return false;527 if (element.isSVGElement() && downcast<SVGElement>(element).animatedSMILStyleProperties())528 return false;529 if (element.isLink() != state.element()->isLink())530 return false;531 if (element.hovered() != state.element()->hovered())532 return false;533 if (element.active() != state.element()->active())534 return false;535 if (element.focused() != state.element()->focused())536 return false;537 if (element.shadowPseudoId() != state.element()->shadowPseudoId())538 return false;539 if (&element == element.document().cssTarget())540 return false;541 if (!sharingCandidateHasIdenticalStyleAffectingAttributes(element))542 return false;543 if (element.additionalPresentationAttributeStyle() != downcast<StyledElement>(*state.element()).additionalPresentationAttributeStyle())544 return false;545 if (element.affectsNextSiblingElementStyle() || element.styleIsAffectedByPreviousSibling())546 return false;547 548 if (element.hasID() && m_ruleSets.features().idsInRules.contains(element.idForStyleResolution().impl()))549 return false;550 551 bool isControl = is<HTMLFormControlElement>(element);552 553 if (isControl != is<HTMLFormControlElement>(*state.element()))554 return false;555 556 if (isControl && !canShareStyleWithControl(element))557 return false;558 559 if (style->transitions() || style->animations())560 return false;561 562 // Turn off style sharing for elements that can gain layers for reasons outside of the style system.563 // See comments in RenderObject::setStyle().564 if (element.hasTagName(iframeTag) || element.hasTagName(frameTag) || element.hasTagName(embedTag) || element.hasTagName(objectTag) || element.hasTagName(appletTag) || element.hasTagName(canvasTag))565 return false;566 567 if (elementHasDirectionAuto(element))568 return false;569 570 if (element.isLink() && state.elementLinkState() != style->insideLink())571 return false;572 573 if (element.elementData() != state.element()->elementData()) {574 if (element.fastGetAttribute(readonlyAttr) != state.element()->fastGetAttribute(readonlyAttr))575 return false;576 if (element.isSVGElement()) {577 if (element.getAttribute(typeAttr) != state.element()->getAttribute(typeAttr))578 return false;579 } else {580 if (element.fastGetAttribute(typeAttr) != state.element()->fastGetAttribute(typeAttr))581 return false;582 }583 }584 585 if (element.matchesValidPseudoClass() != state.element()->matchesValidPseudoClass())586 return false;587 588 if (element.matchesInvalidPseudoClass() != state.element()->matchesValidPseudoClass())589 return false;590 591 #if ENABLE(VIDEO_TRACK)592 // Deny sharing styles between WebVTT and non-WebVTT nodes.593 if (is<WebVTTElement>(*state.element()))594 return false;595 #endif596 597 #if ENABLE(FULLSCREEN_API)598 if (&element == element.document().webkitCurrentFullScreenElement() || state.element() == state.document().webkitCurrentFullScreenElement())599 return false;600 #endif601 return true;602 }603 604 inline StyledElement* StyleResolver::findSiblingForStyleSharing(Node* node, unsigned& count) const605 {606 for (; node; node = node->previousSibling()) {607 if (!is<StyledElement>(*node))608 continue;609 if (canShareStyleWithElement(downcast<StyledElement>(*node)))610 break;611 if (count++ == cStyleSearchThreshold)612 return nullptr;613 }614 return downcast<StyledElement>(node);615 }616 617 RenderStyle* StyleResolver::locateSharedStyle()618 {619 State& state = m_state;620 if (!is<StyledElement>(state.element()) || !state.parentStyle())621 return nullptr;622 auto& styledElement = downcast<StyledElement>(*state.element());623 624 // If the element has inline style it is probably unique.625 if (styledElement.inlineStyle())626 return nullptr;627 if (styledElement.isSVGElement() && downcast<SVGElement>(styledElement).animatedSMILStyleProperties())628 return nullptr;629 // Ids stop style sharing if they show up in the stylesheets.630 if (styledElement.hasID() && m_ruleSets.features().idsInRules.contains(styledElement.idForStyleResolution().impl()))631 return nullptr;632 if (parentElementPreventsSharing(styledElement.parentElement()))633 return nullptr;634 if (state.element() == state.document().cssTarget())635 return nullptr;636 if (elementHasDirectionAuto(*state.element()))637 return nullptr;638 639 // Cache whether state.element is affected by any known class selectors.640 // FIXME: This shouldn't be a member variable. The style sharing code could be factored out of StyleResolver.641 state.setElementAffectedByClassRules(state.element() && state.element()->hasClass() && classNamesAffectedByRules(state.element()->classNames()));642 643 // Check previous siblings and their cousins.644 unsigned count = 0;645 unsigned visitedNodeCount = 0;646 StyledElement* shareElement = nullptr;647 Node* cousinList = styledElement.previousSibling();648 while (cousinList) {649 shareElement = findSiblingForStyleSharing(cousinList, count);650 if (shareElement)651 break;652 cousinList = locateCousinList(cousinList->parentElement(), visitedNodeCount);653 }654 655 // If we have exhausted all our budget or our cousins.656 if (!shareElement)657 return nullptr;658 659 // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.660 if (styleSharingCandidateMatchesRuleSet(m_ruleSets.sibling()))661 return nullptr;662 // Can't share if attribute rules apply.663 if (styleSharingCandidateMatchesRuleSet(m_ruleSets.uncommonAttribute()))664 return nullptr;665 // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.666 if (parentElementPreventsSharing(styledElement.parentElement()))667 return nullptr;668 return shareElement->renderStyle();669 }670 671 361 static inline bool isAtShadowBoundary(const Element* element) 672 362 { … … 677 367 } 678 368 679 Ref<RenderStyle> StyleResolver::styleForElement(Element& element, RenderStyle* parentStyle, 680 StyleSharingBehavior sharingBehavior, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter) 369 Ref<RenderStyle> StyleResolver::styleForElement(Element& element, RenderStyle* parentStyle, RuleMatchingBehavior matchingBehavior, const RenderRegion* regionForStyling, const SelectorFilter* selectorFilter) 681 370 { 682 371 RELEASE_ASSERT(!m_inLoadPendingImages); 683 684 // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer685 // will vanish if a style recalc happens during loading.686 if (sharingBehavior == AllowStyleSharing && !m_document.haveStylesheetsLoaded() && !element.renderer()) {687 if (!s_styleNotYetAvailable) {688 s_styleNotYetAvailable = &RenderStyle::create().leakRef();689 s_styleNotYetAvailable->setDisplay(NONE);690 s_styleNotYetAvailable->fontCascade().update(&m_document.fontSelector());691 }692 m_document.setHasNodesWithPlaceholderStyle();693 return *s_styleNotYetAvailable;694 }695 372 696 373 m_state = State(element, parentStyle, regionForStyling, selectorFilter); 697 374 State& state = m_state; 698 699 if (sharingBehavior == AllowStyleSharing) {700 if (RenderStyle* sharedStyle = locateSharedStyle()) {701 state.clear();702 return *sharedStyle;703 }704 }705 375 706 376 if (state.parentStyle()) { -
trunk/Source/WebCore/css/StyleResolver.h
r195465 r196031 94 94 struct ResourceLoaderOptions; 95 95 96 enum StyleSharingBehavior {97 AllowStyleSharing,98 DisallowStyleSharing,99 };100 101 96 // MatchOnlyUserAgentRules is used in media queries, where relative units 102 97 // are interpreted according to the document root element style, and styled only … … 136 131 ~StyleResolver(); 137 132 138 Ref<RenderStyle> styleForElement(Element&, RenderStyle* parentStyle, StyleSharingBehavior = AllowStyleSharing, 139 RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr); 133 Ref<RenderStyle> styleForElement(Element&, RenderStyle* parentStyle, RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr, const SelectorFilter* = nullptr); 140 134 141 135 void keyframeStylesForAnimation(Element&, const RenderStyle*, KeyframeList&); … … 161 155 162 156 private: 163 RenderStyle* locateSharedStyle();164 bool styleSharingCandidateMatchesRuleSet(RuleSet*);165 Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;166 StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;167 bool canShareStyleWithElement(StyledElement&) const;168 169 157 Ref<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&); 170 158 … … 379 367 const RenderRegion* regionForStyling() const { return m_regionForStyling; } 380 368 EInsideLink elementLinkState() const { return m_elementLinkState; } 381 void setElementAffectedByClassRules(bool isAffected) { m_elementAffectedByClassRules = isAffected; }382 bool elementAffectedByClassRules() const { return m_elementAffectedByClassRules; }383 369 384 370 void setApplyPropertyToRegularStyle(bool isApply) { m_applyPropertyToRegularStyle = isApply; } … … 436 422 EInsideLink m_elementLinkState { NotInsideLink }; 437 423 438 bool m_elementAffectedByClassRules { false };439 424 bool m_applyPropertyToRegularStyle { true }; 440 425 bool m_applyPropertyToVisitedLinkStyle { false }; … … 459 444 460 445 State& state() { return m_state; } 461 462 static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }463 446 464 447 PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue&); … … 489 472 490 473 private: 491 static RenderStyle* s_styleNotYetAvailable;492 493 474 void cacheBorderAndBackground(); 494 495 bool canShareStyleWithControl(StyledElement&) const;496 475 497 476 void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr); … … 520 499 // the last reference to a style declaration are garbage collected. 521 500 void sweepMatchedPropertiesCache(); 522 523 bool classNamesAffectedByRules(const SpaceSplitString&) const;524 bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement&) const;525 501 526 502 unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep; -
trunk/Source/WebCore/dom/VisitedLinkState.cpp
r173980 r196031 42 42 using namespace HTMLNames; 43 43 44 inline static const AtomicString* linkAttribute( Element& element)44 inline static const AtomicString* linkAttribute(const Element& element) 45 45 { 46 46 if (!element.isLink()) … … 68 68 } 69 69 70 inline static LinkHash linkHashForElement(Document& document, Element& element)70 inline static LinkHash linkHashForElement(Document& document, const Element& element) 71 71 { 72 72 if (is<HTMLAnchorElement>(element)) … … 87 87 } 88 88 89 EInsideLink VisitedLinkState::determineLinkStateSlowCase( Element& element)89 EInsideLink VisitedLinkState::determineLinkStateSlowCase(const Element& element) 90 90 { 91 91 ASSERT(element.isLink()); -
trunk/Source/WebCore/dom/VisitedLinkState.h
r171752 r196031 46 46 void invalidateStyleForAllLinks(); 47 47 void invalidateStyleForLink(LinkHash); 48 EInsideLink determineLinkState( Element&);48 EInsideLink determineLinkState(const Element&); 49 49 50 50 private: 51 EInsideLink determineLinkStateSlowCase( Element&);51 EInsideLink determineLinkStateSlowCase(const Element&); 52 52 53 53 Document& m_document; … … 55 55 }; 56 56 57 inline EInsideLink VisitedLinkState::determineLinkState( Element& element)57 inline EInsideLink VisitedLinkState::determineLinkState(const Element& element) 58 58 { 59 59 if (!element.isLink()) -
trunk/Source/WebCore/html/HTMLFormControlElement.h
r194999 r196031 72 72 73 73 virtual bool isDisabledFormControl() const override; 74 virtual bool isDefaultButtonForForm() const override; 74 75 75 76 virtual bool isFocusable() const override; … … 169 170 170 171 virtual HTMLFormElement* virtualForm() const override; 171 virtual bool isDefaultButtonForForm() const override;172 172 bool isValidFormControlElement() const; 173 173 -
trunk/Source/WebCore/rendering/RenderElement.cpp
r195465 r196031 1591 1591 1592 1592 if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) { 1593 RefPtr<RenderStyle> result = styleResolver.styleForElement(*element(), parentStyle , DisallowStyleSharing);1593 RefPtr<RenderStyle> result = styleResolver.styleForElement(*element(), parentStyle); 1594 1594 result->setStyleType(FIRST_LINE_INHERITED); 1595 1595 return result.release(); -
trunk/Source/WebCore/rendering/RenderNamedFlowFragment.cpp
r195465 r196031 353 353 354 354 // FIXME: Region styling fails for pseudo-elements because the renderers don't have a node. 355 RefPtr<RenderStyle> renderObjectRegionStyle = renderer.element()->styleResolver().styleForElement(*renderer.element(), &parentStyle, DisallowStyleSharing,MatchAllRules, this);355 RefPtr<RenderStyle> renderObjectRegionStyle = renderer.element()->styleResolver().styleForElement(*renderer.element(), &parentStyle, MatchAllRules, this); 356 356 357 357 return renderObjectRegionStyle.release(); -
trunk/Source/WebCore/rendering/style/RenderStyle.cpp
r195928 r196031 43 43 #include "StyleScrollSnapPoints.h" 44 44 #include "StyleSelfAlignmentData.h" 45 #include "StyleTreeResolver.h" 45 46 #include "WillChangeData.h" 46 47 #include <wtf/MathExtras.h> … … 294 295 bool RenderStyle::isStyleAvailable() const 295 296 { 296 return this != StyleResolver::styleNotYetAvailable();297 return !Style::isPlaceholderStyle(*this); 297 298 } 298 299 -
trunk/Source/WebCore/style/StyleTreeResolver.cpp
r195465 r196031 97 97 }; 98 98 99 100 static RenderStyle* placeholderStyle; 101 102 static void ensurePlaceholderStyle(Document& document) 103 { 104 if (placeholderStyle) 105 return; 106 placeholderStyle = &RenderStyle::create().leakRef(); 107 placeholderStyle->setDisplay(NONE); 108 placeholderStyle->fontCascade().update(&document.fontSelector()); 109 } 110 99 111 TreeResolver::TreeResolver(Document& document) 100 112 : m_document(document) 101 113 , m_styleResolver(document.ensureStyleResolver()) 102 { 114 , m_sharingResolver(document, m_styleResolver.ruleSets(), m_selectorFilter) 115 { 116 ensurePlaceholderStyle(document); 103 117 } 104 118 … … 108 122 , m_shadowRoot(&shadowRoot) 109 123 , m_shadowHostTreeResolver(&shadowHostTreeResolver) 124 , m_sharingResolver(m_document, m_styleResolver.ruleSets(), m_selectorFilter) 110 125 { 111 126 } … … 124 139 Ref<RenderStyle> TreeResolver::styleForElement(Element& element, RenderStyle& inheritedStyle) 125 140 { 141 if (!m_document.haveStylesheetsLoaded() && !element.renderer()) { 142 m_document.setHasNodesWithPlaceholderStyle(); 143 return *placeholderStyle; 144 } 145 126 146 if (element.hasCustomStyleResolveCallbacks()) { 127 147 if (RefPtr<RenderStyle> style = element.customStyleForRenderer(inheritedStyle)) 128 148 return style.releaseNonNull(); 129 149 } 130 return m_styleResolver.styleForElement(element, &inheritedStyle, AllowStyleSharing, MatchAllRules, nullptr, &m_selectorFilter); 150 151 if (auto* sharingElement = m_sharingResolver.resolve(element)) 152 return *sharingElement->renderStyle(); 153 154 return m_styleResolver.styleForElement(element, &inheritedStyle, MatchAllRules, nullptr, &m_selectorFilter); 131 155 } 132 156 … … 949 973 } 950 974 951 } 952 } 975 bool isPlaceholderStyle(const RenderStyle& style) 976 { 977 return &style == placeholderStyle; 978 } 979 980 } 981 } -
trunk/Source/WebCore/style/StyleTreeResolver.h
r194762 r196031 30 30 #include "SelectorFilter.h" 31 31 #include "StyleChange.h" 32 #include "StyleSharingResolver.h" 32 33 #include <functional> 33 34 #include <wtf/RefPtr.h> … … 86 87 87 88 SelectorFilter m_selectorFilter; 89 SharingResolver m_sharingResolver; 88 90 }; 89 91 … … 95 97 void queuePostResolutionCallback(std::function<void ()>); 96 98 bool postResolutionCallbacksAreSuspended(); 99 100 bool isPlaceholderStyle(const RenderStyle&); 97 101 98 102 class PostResolutionCallbackDisabler { -
trunk/Source/WebCore/svg/SVGElement.cpp
r195465 r196031 794 794 // If the element is in a <use> tree we get the style from the definition tree. 795 795 if (auto* styleElement = this->correspondingElement()) 796 return styleElement->styleResolver().styleForElement(*styleElement, &parentStyle , DisallowStyleSharing);796 return styleElement->styleResolver().styleForElement(*styleElement, &parentStyle); 797 797 798 798 return resolveStyle(&parentStyle); -
trunk/Source/WebCore/svg/SVGElementRareData.h
r195465 r196031 72 72 if (!m_overrideComputedStyle || m_needsOverrideComputedStyleUpdate) { 73 73 // The style computed here contains no CSS Animations/Transitions or SMIL induced rules - this is needed to compute the "base value" for the SMIL animation sandwhich model. 74 m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, DisallowStyleSharing,MatchAllRulesExcludingSMIL);74 m_overrideComputedStyle = element.styleResolver().styleForElement(element, parentStyle, MatchAllRulesExcludingSMIL); 75 75 m_needsOverrideComputedStyleUpdate = false; 76 76 }
Note: See TracChangeset
for help on using the changeset viewer.