chromium/third_party/blink/renderer/core/layout/oof_positioned_node.h

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_OOF_POSITIONED_NODE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_OOF_POSITIONED_NODE_H_

#include <optional>

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/block_node.h"
#include "third_party/blink/renderer/core/layout/geometry/static_position.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/physical_fragment.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"

namespace blink {

// If an out-of-flow positioned element is inside a fragmentation context, it
// will be laid out once it reaches the fragmentation context root rather than
// once it reaches its containing block. A containing block holds the
// containing block information needed to place these OOF positioned nodes once
// they reach the fragmentation context root. See
// PhysicalOofNodeForFragmentation/LogicalOofNodeForFragmentation for more
// details.
template <typename OffsetType>
class OofContainingBlock {};

// This holds the containing block for an out-of-flow positioned element
// if the containing block is a non-atomic inline. It is the continuation
// root (i.e. the first LayoutInline in the continuation chain for the same
// node) if continuations are involved.
template <typename OffsetType>
struct OofInlineContainer {};

// If an out-of-flow positioned element is inside a nested fragmentation
// context, it will be laid out once it reaches the outermost fragmentation
// context root. A multicol with pending OOFs is the inner multicol information
// needed to perform layout on the OOF descendants once they make their way to
// the outermost context.
template <typename OffsetType>
struct MulticolWithPendingOofs
    : public GarbageCollected<MulticolWithPendingOofs<OffsetType>> {};

// A physical out-of-flow positioned-node is an element with the style
// "postion: absolute" or "position: fixed" which hasn't been bubbled up to its
// containing block yet, (e.g. an element with "position: relative"). As soon
// as a positioned-node reaches its containing block, it gets placed, and
// doesn't bubble further up the tree.
//
// This needs its static position [1] to be placed correctly in its containing
// block.
//
// This is struct is allowed to be stored/persisted.
//
// [1] https://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width
struct CORE_EXPORT PhysicalOofPositionedNode {};

// The logical version of above. It is used within a an algorithm pass (within
// an |FragmentBuilder|), and its logical coordinate system is wrt.
// the container builder's writing-mode.
//
// It is *only* used within an algorithm pass, (it is temporary, and should not
// be stored/persisted).
struct CORE_EXPORT LogicalOofPositionedNode {};

// When fragmentation comes into play, we no longer place a positioned-node as
// soon as it reaches its containing block. Instead, we continue to bubble the
// positioned node up until it reaches the fragmentation context root. There, it
// will get placed and properly fragmented.
//
// In addition to the static position, we also needs the containing block
// fragment to be placed correctly within the fragmentation context root. In
// addition, the containing block offset is needed to compute the start offset
// and the initial fragmentainer of an out-of-flow positioned-node.
//
// If an OOF node in a fragmentation context has fixedpos descendants, those
// descendants will not find their containing block if the containing block
// lives inside the fragmentation context root. Thus, we also need to store
// information on the containing block and inline container for any fixedpos
// descendants, if one exists.
//
// This is struct is allowed to be stored/persisted.
struct CORE_EXPORT PhysicalOofNodeForFragmentation final
    : public PhysicalOofPositionedNode {};

// The logical version of the above. It is used within a an algorithm pass
// (within an |FragmentBuilder|), and its logical coordinate system
// is wrt. the container builder's writing-mode.
//
// It is *only* used within an algorithm pass, (it is temporary, and should not
// be stored/persisted).
struct CORE_EXPORT LogicalOofNodeForFragmentation final
    : public LogicalOofPositionedNode {};

template <>
struct DowncastTraits<LogicalOofNodeForFragmentation> {};

// This is a sub class of |PhysicalFragment::OofData| that can store OOF
// propagation data under the NG block fragmentation context.
//
// This class is defined here instead of |PhysicalFragment| because types
// needed for this class requires full definition of |PhysicalFragment|, and
// |PhysicalFragment| requires full definition of this class if this is put
// into |PhysicalFragment|.
struct FragmentedOofData final : PhysicalFragment::OofData {};

inline PhysicalOffset RelativeInsetToPhysical(
    LogicalOffset relative_inset,
    WritingDirectionMode writing_direction) {}

inline LogicalOffset RelativeInsetToLogical(
    PhysicalOffset relative_inset,
    WritingDirectionMode writing_direction) {}

}  // namespace blink

WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS()
WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS()
WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS()
WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS()

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_OOF_POSITIONED_NODE_H_