blob: 6c958c9c8297dcf72cf7ffb7eb38c55723f1a22c [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RECALC_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RECALC_H_
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
namespace blink {
class ContainerQueryEvaluator;
class Element;
class Node;
class PseudoElement;
// Class for keeping track of the need for traversing down flat tree children,
// recompute their computed styles, and marking nodes for layout tree re-
// attachment during the style recalc phase.
class StyleRecalcChange {
public:
enum Propagate {
// No need to update style of any children.
kNo,
// Need to traverse children in display:none or non-slotted/distributed
// children of shadow hosts to clear ensured computed styles.
kClearEnsured,
// Need to traverse descendants to invalidate style for container queries.
// This value is passed in for the container itself, it will translate into
// recalc_container_query_dependent_=true for descendants. We should not
// recalc style for the container itself.
kRecalcContainerQueryDependent,
// Need to update existence and style for pseudo elements.
kUpdatePseudoElements,
// Need to recalculate style for children for inheritance. All changed
// inherited properties can be propagated (PropagateInheritedProperties)
// instead of a full rule matching.
kIndependentInherit,
// Need to recalculate style for children, typically for inheritance.
kRecalcChildren,
// Need to recalculate style for all descendants.
kRecalcDescendants,
};
StyleRecalcChange() = default;
StyleRecalcChange(const StyleRecalcChange&) = default;
StyleRecalcChange(Propagate propagate) : propagate_(propagate) {}
StyleRecalcChange ForChildren(const Element& element) const {
return {RecalcDescendants() ? kRecalcDescendants : kNo, reattach_,
RecalcContainerQueryDependentChildren(element)};
}
StyleRecalcChange ForPseudoElement() const {
if (propagate_ == kUpdatePseudoElements)
return {kRecalcChildren, reattach_, recalc_container_query_dependent_};
return *this;
}
StyleRecalcChange EnsureAtLeast(Propagate propagate) const {
if (propagate > propagate_)
return {propagate, reattach_, recalc_container_query_dependent_};
return {propagate_, reattach_, recalc_container_query_dependent_};
}
StyleRecalcChange ForceRecalcDescendants() const {
return {kRecalcDescendants, reattach_, recalc_container_query_dependent_};
}
StyleRecalcChange ForceReattachLayoutTree() const {
return {propagate_, true, recalc_container_query_dependent_};
}
bool ReattachLayoutTree() const { return reattach_; }
bool RecalcChildren() const { return propagate_ > kUpdatePseudoElements; }
bool RecalcDescendants() const { return propagate_ == kRecalcDescendants; }
bool UpdatePseudoElements() const { return propagate_ != kNo; }
bool IndependentInherit() const { return propagate_ == kIndependentInherit; }
bool TraverseChildren(const Element&) const;
bool TraverseChild(const Node&) const;
bool TraversePseudoElements(const Element&) const;
bool ShouldRecalcStyleFor(const Node&) const;
bool ShouldUpdatePseudoElement(const PseudoElement&) const;
private:
StyleRecalcChange(Propagate propagate,
bool reattach,
bool recalc_container_query_dependent)
: propagate_(propagate),
reattach_(reattach),
recalc_container_query_dependent_(recalc_container_query_dependent) {}
bool RecalcContainerQueryDependent() const {
return recalc_container_query_dependent_;
}
bool RecalcContainerQueryDependentChildren(const Element&) const;
// To what extent do we need to update style for children.
Propagate propagate_ = kNo;
// Need to reattach layout tree if true.
bool reattach_ = false;
// Force recalc of elements depending on container queries.
bool recalc_container_query_dependent_ = false;
};
// StyleRecalcContext is an object that is passed on the stack during
// the style recalc process.
//
// Its purpose is to hold context related to the style recalc process as
// a whole, i.e. information not directly associated to the specific element
// style is being calculated for.
class StyleRecalcContext {
STACK_ALLOCATED();
public:
// Using the ancestor chain, build a StyleRecalcContext suitable for
// resolving the style of the given Element.
static StyleRecalcContext FromAncestors(Element&);
// If style is being calculated for an element inside a container,
// this ContainerQueryEvaluator may be used to evaluate @container
// rules against that container.
ContainerQueryEvaluator* cq_evaluator = nullptr;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RECALC_H_