| // 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_ |