#include "third_party/blink/renderer/core/layout/out_of_flow_layout_part.h"
#include <math.h>
#include <algorithm>
#include "base/memory/values_equivalent.h"
#include "base/not_fatal_until.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/out_of_flow_data.h"
#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_document_state.h"
#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/absolute_utils.h"
#include "third_party/blink/renderer/core/layout/anchor_position_scroll_data.h"
#include "third_party/blink/renderer/core/layout/anchor_position_visibility_observer.h"
#include "third_party/blink/renderer/core/layout/anchor_query_map.h"
#include "third_party/blink/renderer/core/layout/column_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/disable_layout_side_effects_scope.h"
#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/grid/grid_placement.h"
#include "third_party/blink/renderer/core/layout/inline/physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_box_utils.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_result.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/legacy_layout_tree_walking.h"
#include "third_party/blink/renderer/core/layout/logical_fragment.h"
#include "third_party/blink/renderer/core/layout/oof_positioned_node.h"
#include "third_party/blink/renderer/core/layout/paginated_root_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/pagination_utils.h"
#include "third_party/blink/renderer/core/layout/physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/physical_fragment.h"
#include "third_party/blink/renderer/core/layout/simplified_layout_algorithm.h"
#include "third_party/blink/renderer/core/layout/simplified_oof_layout_algorithm.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/view_transition/view_transition.h"
#include "third_party/blink/renderer/core/view_transition/view_transition_utils.h"
#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
namespace blink {
namespace {
bool CalculateNonOverflowingRangeInOneAxis(
LayoutUnit margin_box_start,
LayoutUnit margin_box_end,
LayoutUnit imcb_inset_start,
LayoutUnit imcb_inset_end,
LayoutUnit position_area_start,
LayoutUnit position_area_end,
bool has_non_auto_inset_start,
bool has_non_auto_inset_end,
std::optional<LayoutUnit>* out_scroll_min,
std::optional<LayoutUnit>* out_scroll_max) { … }
class OOFCandidateStyleIterator { … };
const Element* GetPositionAnchorElement(
const BlockNode& node,
const ComputedStyle& style,
const LogicalAnchorQuery* anchor_query) { … }
const LayoutObject* GetPositionAnchorObject(
const BlockNode& node,
const ComputedStyle& style,
const LogicalAnchorQuery* anchor_query) { … }
gfx::Vector2dF GetAnchorOffset(const BlockNode& node,
const ComputedStyle& style,
const LogicalAnchorQuery* anchor_query) { … }
void UpdatePositionVisibilityAfterLayout(
const OutOfFlowLayoutPart::OffsetInfo& offset_info,
const BlockNode& node,
const LogicalAnchorQuery* anchor_query) { … }
}
std::optional<LogicalSize> OutOfFlowLayoutPart::InitialContainingBlockFixedSize(
BlockNode container) { … }
OutOfFlowLayoutPart::OutOfFlowLayoutPart(BoxFragmentBuilder* container_builder)
: … { … }
void OutOfFlowLayoutPart::Run() { … }
void OutOfFlowLayoutPart::PropagateOOFsFromPageAreas() { … }
void OutOfFlowLayoutPart::HandleFragmentation() { … }
OutOfFlowLayoutPart::ContainingBlockInfo
OutOfFlowLayoutPart::ApplyPositionAreaOffsets(
const PositionAreaOffsets& offsets,
const OutOfFlowLayoutPart::ContainingBlockInfo& container_info) const { … }
const OutOfFlowLayoutPart::ContainingBlockInfo
OutOfFlowLayoutPart::GetContainingBlockInfo(
const LogicalOofPositionedNode& candidate) { … }
void OutOfFlowLayoutPart::ComputeInlineContainingBlocks(
const HeapVector<LogicalOofPositionedNode>& candidates) { … }
void OutOfFlowLayoutPart::ComputeInlineContainingBlocksForFragmentainer(
const HeapVector<LogicalOofNodeForFragmentation>& descendants) { … }
void OutOfFlowLayoutPart::AddInlineContainingBlockInfo(
const InlineContainingBlockUtils::InlineContainingBlockMap&
inline_container_fragments,
const WritingDirectionMode container_writing_direction,
PhysicalSize container_builder_size,
LogicalOffset containing_block_relative_offset,
LogicalOffset containing_block_offset,
bool adjust_for_fragmentation) { … }
void OutOfFlowLayoutPart::LayoutCandidates(
HeapVector<LogicalOofPositionedNode>* candidates) { … }
void OutOfFlowLayoutPart::HandleMulticolsWithPendingOOFs(
BoxFragmentBuilder* container_builder) { … }
void OutOfFlowLayoutPart::LayoutOOFsInMulticol(
const BlockNode& multicol,
const MulticolWithPendingOofs<LogicalOffset>* multicol_info) { … }
void OutOfFlowLayoutPart::LayoutFragmentainerDescendants(
HeapVector<LogicalOofNodeForFragmentation>* descendants,
LogicalOffset fragmentainer_progression,
bool outer_context_has_fixedpos_container,
HeapVector<MulticolChildInfo>* multicol_children) { … }
AnchorEvaluatorImpl OutOfFlowLayoutPart::CreateAnchorEvaluator(
const ContainingBlockInfo& container_info,
const BlockNode& candidate,
const LogicalAnchorQueryMap* anchor_queries) const { … }
OutOfFlowLayoutPart::NodeInfo OutOfFlowLayoutPart::SetupNodeInfo(
const LogicalOofPositionedNode& oof_node) { … }
const LayoutResult* OutOfFlowLayoutPart::LayoutOOFNode(
NodeToLayout& oof_node_to_layout,
const ConstraintSpace* fragmentainer_constraint_space,
bool is_last_fragmentainer_so_far) { … }
namespace {
constexpr unsigned kMaxTryAttempts = …;
struct NonOverflowingCandidate { … };
EPositionTryOrder ToLogicalPositionTryOrder(
EPositionTryOrder position_try_order,
WritingDirectionMode writing_direction) { … }
void SortNonOverflowingCandidates(
EPositionTryOrder position_try_order,
WritingDirectionMode writing_direction,
HeapVector<NonOverflowingCandidate, kMaxTryAttempts>& candidates) { … }
}
OutOfFlowLayoutPart::OffsetInfo OutOfFlowLayoutPart::CalculateOffset(
const NodeInfo& node_info,
const LogicalAnchorQueryMap* anchor_queries) { … }
std::optional<OutOfFlowLayoutPart::OffsetInfo>
OutOfFlowLayoutPart::TryCalculateOffset(
const NodeInfo& node_info,
const ComputedStyle& candidate_style,
AnchorEvaluatorImpl& anchor_evaluator,
bool try_fit_available_space,
NonOverflowingScrollRange* out_non_overflowing_range) { … }
const LayoutResult* OutOfFlowLayoutPart::Layout(
const NodeToLayout& oof_node_to_layout,
const ConstraintSpace* fragmentainer_constraint_space,
bool is_last_fragmentainer_so_far) { … }
bool OutOfFlowLayoutPart::IsContainingBlockForCandidate(
const LogicalOofPositionedNode& candidate) { … }
const LayoutResult* OutOfFlowLayoutPart::GenerateFragment(
const NodeToLayout& oof_node_to_layout,
const ConstraintSpace* fragmentainer_constraint_space,
bool is_last_fragmentainer_so_far) { … }
void OutOfFlowLayoutPart::LayoutOOFsInFragmentainer(
HeapVector<NodeToLayout>& pending_descendants,
wtf_size_t index,
LogicalOffset fragmentainer_progression,
bool has_oofs_in_later_fragmentainer,
LayoutUnit* monolithic_overflow,
bool* has_actual_break_inside,
HeapVector<NodeToLayout>* fragmented_descendants) { … }
void OutOfFlowLayoutPart::AddOOFToFragmentainer(
NodeToLayout& descendant,
const ConstraintSpace* fragmentainer_space,
LogicalOffset fragmentainer_offset,
wtf_size_t index,
bool is_last_fragmentainer_so_far,
bool* has_actual_break_inside,
SimplifiedOofLayoutAlgorithm* algorithm,
HeapVector<NodeToLayout>* fragmented_descendants) { … }
ConstraintSpace OutOfFlowLayoutPart::GetFragmentainerConstraintSpace(
wtf_size_t index) { … }
void OutOfFlowLayoutPart::ComputeStartFragmentIndexAndRelativeOffset(
WritingMode default_writing_mode,
LayoutUnit block_estimate,
std::optional<LayoutUnit> clipped_container_block_offset,
wtf_size_t* start_index,
LogicalOffset* offset) const { … }
void OutOfFlowLayoutPart::SaveStaticPositionOnPaintLayer(
LayoutBox* layout_box,
const LogicalStaticPosition& position) const { … }
LogicalStaticPosition OutOfFlowLayoutPart::ToStaticPositionForLegacy(
LogicalStaticPosition position) const { … }
const PhysicalBoxFragment& OutOfFlowLayoutPart::GetChildFragment(
wtf_size_t index) const { … }
const BlockBreakToken* OutOfFlowLayoutPart::PreviousFragmentainerBreakToken(
wtf_size_t index) const { … }
void OutOfFlowLayoutPart::ColumnBalancingInfo::PropagateSpaceShortage(
LayoutUnit space_shortage) { … }
void OutOfFlowLayoutPart::MulticolChildInfo::Trace(Visitor* visitor) const { … }
void OutOfFlowLayoutPart::NodeInfo::Trace(Visitor* visitor) const { … }
void OutOfFlowLayoutPart::OffsetInfo::Trace(Visitor* visitor) const { … }
void OutOfFlowLayoutPart::NodeToLayout::Trace(Visitor* visitor) const { … }
}
WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(…)