haikuwebkit/Source/WebCore/style/ClassChangeInvalidation.h

73 lines
2.4 KiB
C
Raw Permalink Normal View History

/*
* Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "Element.h"
#include "StyleInvalidator.h"
#include <wtf/Vector.h>
namespace WebCore {
class SpaceSplitString;
namespace Style {
class ClassChangeInvalidation {
public:
ClassChangeInvalidation(Element&, const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses);
~ClassChangeInvalidation();
private:
Invalidate current element style on class change accurately https://bugs.webkit.org/show_bug.cgi?id=181210 Reviewed by Zalan Bujtas. Source/WebCore: * css/DocumentRuleSets.cpp: (WebCore::DocumentRuleSets::collectFeatures const): (WebCore::DocumentRuleSets::subjectClassRules const): New rule set containing class rules affecting the subject element. (WebCore::DocumentRuleSets::ancestorClassRules const): * css/DocumentRuleSets.h: * css/RuleFeature.cpp: (WebCore::RuleFeatureSet::recursivelyCollectFeaturesFromSelector): Classify selector components into various buckets based on the elements they match relative to the subject element. There are more categories than this patch strictly needs, for future use. (WebCore::RuleFeatureSet::collectFeatures): (WebCore::RuleFeatureSet::add): (WebCore::RuleFeatureSet::clear): (WebCore::RuleFeatureSet::shrinkToFit): * css/RuleFeature.h: * css/StyleResolver.h: (WebCore::StyleResolver::hasSelectorForClass const): Deleted. * style/ClassChangeInvalidation.cpp: (WebCore::Style::elementNeedsInvalidation): (WebCore::Style::ClassChangeInvalidation::computeInvalidation): Don't invalidate current element unconditionally on class change. Instead find the subject rulesets that might affect it use them to perform invalidation. (WebCore::Style::ClassChangeInvalidation::invalidateStyleWithRuleSets): (WebCore::Style::ClassChangeInvalidation::invalidateStyle): Deleted. (WebCore::Style::ClassChangeInvalidation::invalidateDescendantStyle): Deleted. * style/ClassChangeInvalidation.h: (WebCore::Style::ClassChangeInvalidation::ClassChangeInvalidation): (WebCore::Style::ClassChangeInvalidation::~ClassChangeInvalidation): * style/StyleSharingResolver.cpp: (WebCore::Style::SharingResolver::classNamesAffectedByRules const): LayoutTests: * fast/css/set-inline-style-recalc-expected.txt: * fast/css/set-inline-style-recalc.html: Canonical link: https://commits.webkit.org/197330@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226703 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-01-10 09:01:53 +00:00
void computeInvalidation(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses);
void invalidateStyleWithRuleSets();
const bool m_isEnabled;
Element& m_element;
Invalidator::MatchElementRuleSets m_matchElementRuleSets;
};
inline ClassChangeInvalidation::ClassChangeInvalidation(Element& element, const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
Optimize style invalidations for attribute selectors https://bugs.webkit.org/show_bug.cgi?id=154242 Reviewed by Andreas Kling. Source/WebCore: Currently we invalidate the whole element subtree if there are any attribute selectors for the changed attribute. This is slow as generally few if any elements are really affected. Using attribute selectors for dynamic styling should be performant. This patch implements optimization strategy for attributes similar to what we already have for classes: - Collect a map of all rules that contains descendant-affecting attribute selectors for a given attribute. - When an attribute value changes check if there are any such rules for it. - Check if the value change affects the results of any of the attribute selectors. - Only if it does invalidate the exact descendant elements affected by the rules. Test: fast/css/style-invalidation-attribute-change-descendants.html * WebCore.xcodeproj/project.pbxproj: * css/DocumentRuleSets.cpp: (WebCore::DocumentRuleSets::ancestorClassRules): (WebCore::DocumentRuleSets::ancestorAttributeRulesForHTML): Create optimization RuleSets when needed. * css/DocumentRuleSets.h: (WebCore::DocumentRuleSets::uncommonAttribute): (WebCore::DocumentRuleSets::features): * css/RuleFeature.cpp: (WebCore::RuleFeatureSet::recursivelyCollectFeaturesFromSelector): (WebCore::makeAttributeSelectorKey): (WebCore::RuleFeatureSet::collectFeatures): Collect rules with descendant affecting attribute selectors. (WebCore::RuleFeatureSet::add): (WebCore::RuleFeatureSet::clear): (WebCore::RuleFeatureSet::shrinkToFit): * css/RuleFeature.h: * css/SelectorChecker.cpp: (WebCore::anyAttributeMatches): (WebCore::SelectorChecker::attributeSelectorMatches): Expose function for matching single attribute selectors. (WebCore::canMatchHoverOrActiveInQuirksMode): * css/SelectorChecker.h: * dom/Attr.cpp: (WebCore::Attr::setValue): (WebCore::Attr::childrenChanged): * dom/Element.cpp: (WebCore::Element::setAttributeInternal): (WebCore::makeIdForStyleResolution): (WebCore::Element::attributeChanged): (WebCore::Element::removeAttributeInternal): (WebCore::Element::addAttributeInternal): (WebCore::Element::removeAttribute): Add AttributeChangeInvalidation where needed. (WebCore::Element::needsStyleInvalidation): Move to Element from ClassChangeInvalidation. (WebCore::Element::willModifyAttribute): No more full style invalidation on attribute change. * style/AttributeChangeInvalidation.cpp: Added. (WebCore::Style::AttributeChangeInvalidation::invalidateStyle): Invalidate local style. Check if we need to invalidate descendants by looking into ancestorAttributeRules. (WebCore::Style::AttributeChangeInvalidation::invalidateDescendants): Use StyleInvalidationAnalysis to invalidate the subtree for the relevant rules. * style/AttributeChangeInvalidation.h: Added. (WebCore::Style::AttributeChangeInvalidation::needsInvalidation): (WebCore::Style::AttributeChangeInvalidation::AttributeChangeInvalidation): (WebCore::Style::AttributeChangeInvalidation::~AttributeChangeInvalidation): If needed, invalidate descendants before and after attribute change to catch rules that start and stop applying. LayoutTests: * fast/css/style-invalidation-attribute-change-descendants-expected.txt: Added. * fast/css/style-invalidation-attribute-change-descendants.html: Added. Canonical link: https://commits.webkit.org/172393@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196629 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-02-16 08:20:58 +00:00
: m_isEnabled(element.needsStyleInvalidation())
, m_element(element)
{
if (!m_isEnabled)
return;
Invalidate current element style on class change accurately https://bugs.webkit.org/show_bug.cgi?id=181210 Reviewed by Zalan Bujtas. Source/WebCore: * css/DocumentRuleSets.cpp: (WebCore::DocumentRuleSets::collectFeatures const): (WebCore::DocumentRuleSets::subjectClassRules const): New rule set containing class rules affecting the subject element. (WebCore::DocumentRuleSets::ancestorClassRules const): * css/DocumentRuleSets.h: * css/RuleFeature.cpp: (WebCore::RuleFeatureSet::recursivelyCollectFeaturesFromSelector): Classify selector components into various buckets based on the elements they match relative to the subject element. There are more categories than this patch strictly needs, for future use. (WebCore::RuleFeatureSet::collectFeatures): (WebCore::RuleFeatureSet::add): (WebCore::RuleFeatureSet::clear): (WebCore::RuleFeatureSet::shrinkToFit): * css/RuleFeature.h: * css/StyleResolver.h: (WebCore::StyleResolver::hasSelectorForClass const): Deleted. * style/ClassChangeInvalidation.cpp: (WebCore::Style::elementNeedsInvalidation): (WebCore::Style::ClassChangeInvalidation::computeInvalidation): Don't invalidate current element unconditionally on class change. Instead find the subject rulesets that might affect it use them to perform invalidation. (WebCore::Style::ClassChangeInvalidation::invalidateStyleWithRuleSets): (WebCore::Style::ClassChangeInvalidation::invalidateStyle): Deleted. (WebCore::Style::ClassChangeInvalidation::invalidateDescendantStyle): Deleted. * style/ClassChangeInvalidation.h: (WebCore::Style::ClassChangeInvalidation::ClassChangeInvalidation): (WebCore::Style::ClassChangeInvalidation::~ClassChangeInvalidation): * style/StyleSharingResolver.cpp: (WebCore::Style::SharingResolver::classNamesAffectedByRules const): LayoutTests: * fast/css/set-inline-style-recalc-expected.txt: * fast/css/set-inline-style-recalc.html: Canonical link: https://commits.webkit.org/197330@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226703 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-01-10 09:01:53 +00:00
computeInvalidation(oldClasses, newClasses);
invalidateStyleWithRuleSets();
}
inline ClassChangeInvalidation::~ClassChangeInvalidation()
{
if (!m_isEnabled)
return;
Invalidate current element style on class change accurately https://bugs.webkit.org/show_bug.cgi?id=181210 Reviewed by Zalan Bujtas. Source/WebCore: * css/DocumentRuleSets.cpp: (WebCore::DocumentRuleSets::collectFeatures const): (WebCore::DocumentRuleSets::subjectClassRules const): New rule set containing class rules affecting the subject element. (WebCore::DocumentRuleSets::ancestorClassRules const): * css/DocumentRuleSets.h: * css/RuleFeature.cpp: (WebCore::RuleFeatureSet::recursivelyCollectFeaturesFromSelector): Classify selector components into various buckets based on the elements they match relative to the subject element. There are more categories than this patch strictly needs, for future use. (WebCore::RuleFeatureSet::collectFeatures): (WebCore::RuleFeatureSet::add): (WebCore::RuleFeatureSet::clear): (WebCore::RuleFeatureSet::shrinkToFit): * css/RuleFeature.h: * css/StyleResolver.h: (WebCore::StyleResolver::hasSelectorForClass const): Deleted. * style/ClassChangeInvalidation.cpp: (WebCore::Style::elementNeedsInvalidation): (WebCore::Style::ClassChangeInvalidation::computeInvalidation): Don't invalidate current element unconditionally on class change. Instead find the subject rulesets that might affect it use them to perform invalidation. (WebCore::Style::ClassChangeInvalidation::invalidateStyleWithRuleSets): (WebCore::Style::ClassChangeInvalidation::invalidateStyle): Deleted. (WebCore::Style::ClassChangeInvalidation::invalidateDescendantStyle): Deleted. * style/ClassChangeInvalidation.h: (WebCore::Style::ClassChangeInvalidation::ClassChangeInvalidation): (WebCore::Style::ClassChangeInvalidation::~ClassChangeInvalidation): * style/StyleSharingResolver.cpp: (WebCore::Style::SharingResolver::classNamesAffectedByRules const): LayoutTests: * fast/css/set-inline-style-recalc-expected.txt: * fast/css/set-inline-style-recalc.html: Canonical link: https://commits.webkit.org/197330@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226703 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-01-10 09:01:53 +00:00
invalidateStyleWithRuleSets();
}
Updating class name doesn't update the slotted content's style https://bugs.webkit.org/show_bug.cgi?id=164577 <rdar://problem/29205873> Reviewed by Ryosuke Niwa. Source/WebCore: Test: fast/shadow-dom/css-scoping-slotted-invalidation.html Teach style invalidation code for attribute/class/id mutations about slotted rules. * dom/ShadowRoot.cpp: (WebCore::assignedShadowRootsIfSlotted): Helper to find all assigned shadow roots (there may be more than one if slots are assigned to slots). * dom/ShadowRoot.h: * style/AttributeChangeInvalidation.cpp: (WebCore::Style::mayBeAffectedByAttributeChange): (WebCore::Style::mayBeAffectedByHostRules): (WebCore::Style::mayBeAffectedBySlottedRules): (WebCore::Style::AttributeChangeInvalidation::invalidateStyle): (WebCore::Style::mayBeAffectedByHostStyle): Deleted. * style/ClassChangeInvalidation.cpp: (WebCore::Style::mayBeAffectedByHostRules): (WebCore::Style::mayBeAffectedBySlottedRules): (WebCore::Style::ClassChangeInvalidation::invalidateStyle): (WebCore::Style::mayBeAffectedByHostStyle): Deleted. * style/ClassChangeInvalidation.h: * style/IdChangeInvalidation.cpp: (WebCore::Style::mayBeAffectedByHostRules): (WebCore::Style::mayBeAffectedBySlottedRules): (WebCore::Style::IdChangeInvalidation::invalidateStyle): (WebCore::Style::mayBeAffectedByHostStyle): Deleted. * style/StyleSharingResolver.cpp: (WebCore::Style::SharingResolver::canShareStyleWithElement): Fix a bug in style sharing where we were checking wrong element for host rules. Tested by the included test too (the last empty div). LayoutTests: * fast/shadow-dom/css-scoping-slotted-invalidation-expected.html: Added. * fast/shadow-dom/css-scoping-slotted-invalidation.html: Added. Canonical link: https://commits.webkit.org/182339@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208616 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-11 23:08:34 +00:00
}
}