blob: 444f9d3724bedf4cbdc4a80d9a0a47409e68e8f8 [file] [log] [blame]
// Copyright 2016 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 NGOutOfFlowLayoutPart_h
#define NGOutOfFlowLayoutPart_h
#include "third_party/blink/renderer/core/core_export.h"
#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_offset.h"
#include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h"
#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
class ComputedStyle;
class LayoutBox;
class LayoutObject;
class NGBlockNode;
class NGBoxFragmentBuilder;
class NGConstraintSpace;
class NGLayoutResult;
struct NGOutOfFlowPositionedDescendant;
// Helper class for positioning of out-of-flow blocks.
// It should be used together with NGBoxFragmentBuilder.
// See NGBoxFragmentBuilder::AddOutOfFlowChildCandidate documentation
// for example of using these classes together.
class CORE_EXPORT NGOutOfFlowLayoutPart {
STACK_ALLOCATED();
public:
NGOutOfFlowLayoutPart(const NGBlockNode& container_node,
const NGConstraintSpace& container_space,
const NGBoxStrut& border_scrollbar,
NGBoxFragmentBuilder* container_builder);
// The |container_builder|, |border_scrollbar|, |container_space|, and
// |container_style| parameters are all with respect to the containing block
// of the relevant out-of-flow positioned descendants. If the CSS "containing
// block" of such an out-of-flow positioned descendant isn't a true block
// (e.g. a relatively positioned inline instead), the containing block here is
// the containing block of said non-block.
NGOutOfFlowLayoutPart(
bool contains_absolute,
bool contains_fixed,
const ComputedStyle& container_style,
const NGConstraintSpace& container_space,
const NGBoxStrut& border_scrollbar,
NGBoxFragmentBuilder* container_builder,
base::Optional<LogicalSize> initial_containing_block_fixed_size =
base::nullopt);
// Normally this function lays out and positions all out-of-flow objects from
// the container_builder and additional ones it discovers through laying out
// those objects. However, if only_layout is specified, only that object will
// get laid out; any additional ones will be stored as out-of-flow
// descendants in the builder for use via
// LayoutResult::OutOfFlowPositionedDescendants.
void Run(const LayoutBox* only_layout = nullptr);
private:
// Information needed to position descendant within a containing block.
// Geometry expressed here is complicated:
// There are two types of containing blocks:
// 1) Default containing block (DCB)
// Containing block passed in NGOutOfFlowLayoutPart constructor.
// It is the block element inside which this algorighm runs.
// All OOF descendants not in inline containing block are placed in DCB.
// 2) Inline containing block
// OOF descendants might be positioned wrt inline containing block.
// Inline containing block is positioned wrt default containing block.
struct ContainingBlockInfo {
STACK_ALLOCATED();
public:
// Containing block style.
const ComputedStyle* style;
// Logical in containing block coordinates.
LogicalSize content_size_for_absolute;
// Content size for fixed is different for the ICB.
LogicalSize content_size_for_fixed;
// Offsets (both logical and physical) of the container's padding-box, wrt.
// the default container's border-box.
LogicalOffset container_offset;
PhysicalOffset physical_container_offset;
LogicalSize ContentSize(EPosition position) const {
return position == EPosition::kAbsolute ? content_size_for_absolute
: content_size_for_fixed;
}
};
bool SweepLegacyDescendants(HashSet<const LayoutObject*>* placed_objects);
const ContainingBlockInfo& GetContainingBlockInfo(
const NGOutOfFlowPositionedDescendant&) const;
void ComputeInlineContainingBlocks(
const Vector<NGOutOfFlowPositionedDescendant>&);
void LayoutDescendantCandidates(
Vector<NGOutOfFlowPositionedDescendant>* descendant_candidates,
const LayoutBox* only_layout,
HashSet<const LayoutObject*>* placed_objects);
scoped_refptr<const NGLayoutResult> LayoutDescendant(
const NGOutOfFlowPositionedDescendant&,
const LayoutBox* only_layout);
bool IsContainingBlockForDescendant(
const NGOutOfFlowPositionedDescendant& descendant);
scoped_refptr<const NGLayoutResult> GenerateFragment(
NGBlockNode node,
const LogicalSize& container_content_size_in_child_writing_mode,
const base::Optional<LayoutUnit>& block_estimate,
const NGAbsolutePhysicalPosition& node_position);
NGBoxFragmentBuilder* container_builder_;
ContainingBlockInfo default_containing_block_;
HashMap<const LayoutObject*, ContainingBlockInfo> containing_blocks_map_;
bool contains_absolute_;
bool contains_fixed_;
};
} // namespace blink
#endif