IdChangeInvalidation.cpp [plain text]
#include "config.h"
#include "IdChangeInvalidation.h"
#include "DocumentRuleSets.h"
#include "ElementChildIterator.h"
#include "HTMLSlotElement.h"
#include "ShadowRoot.h"
#include "StyleResolver.h"
#include "StyleScope.h"
namespace WebCore {
namespace Style {
static bool mayBeAffectedByHostRules(const Element& element, const AtomicString& changedId, bool& mayAffectShadowTree)
{
auto* shadowRoot = element.shadowRoot();
if (!shadowRoot)
return false;
auto& shadowRuleSets = shadowRoot->styleScope().resolver().ruleSets();
auto& authorStyle = shadowRuleSets.authorStyle();
if (authorStyle.hostPseudoClassRules().isEmpty() && !authorStyle.hasHostPseudoClassRulesMatchingInShadowTree())
return false;
if (!shadowRuleSets.features().idsInRules.contains(changedId))
return false;
if (authorStyle.hasHostPseudoClassRulesMatchingInShadowTree())
mayAffectShadowTree = true;
return true;
}
static bool mayBeAffectedBySlottedRules(const Element& element, const AtomicString& changedId)
{
for (auto* shadowRoot : assignedShadowRootsIfSlotted(element)) {
auto& ruleSets = shadowRoot->styleScope().resolver().ruleSets();
if (ruleSets.authorStyle().slottedPseudoElementRules().isEmpty())
continue;
if (ruleSets.features().idsInRules.contains(changedId))
return true;
}
return false;
}
void IdChangeInvalidation::invalidateStyle(const AtomicString& changedId)
{
if (changedId.isEmpty())
return;
auto& ruleSets = m_element.styleResolver().ruleSets();
bool mayAffectShadowTree = false;
bool mayAffectStyle = ruleSets.features().idsInRules.contains(changedId)
|| mayBeAffectedByHostRules(m_element, changedId, mayAffectShadowTree)
|| mayBeAffectedBySlottedRules(m_element, changedId);
if (!mayAffectStyle)
return;
if (m_element.shadowRoot() && ruleSets.authorStyle().hasShadowPseudoElementRules())
mayAffectShadowTree = true;
if (is<HTMLSlotElement>(m_element) && !ruleSets.authorStyle().slottedPseudoElementRules().isEmpty())
mayAffectShadowTree = true;
if (mayAffectShadowTree) {
m_element.invalidateStyleForSubtree();
return;
}
m_element.invalidateStyle();
bool mayAffectDescendantStyle = ruleSets.features().idsMatchingAncestorsInRules.contains(changedId);
if (mayAffectDescendantStyle)
m_element.invalidateStyleForSubtree();
else
m_element.invalidateStyle();
}
}
}