mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-10 18:19:41 +00:00
Before this change, a formatting context was responsible for layout of absolutely positioned boxes whose FC root box was their parent (either directly or indirectly). This only worked correctly when the containing block of the absolutely positioned child did not escape the FC root. This is because the width and height of an absolutely positioned box are resolved based on the size of its containing block, so we needed to ensure that the containing block's layout was completed before laying out an absolutely positioned box. With this change, the layout of absolutely positioned boxes is delayed until the FC responsible for the containing block's layout is complete. This has affected the way we calculate the static position. It is no longer possible to ask the FC for a box's static position, as this FC's state might be gone by the time the layout for absolutely positioned elements occurs. Instead, the "static position rectangle" (a concept from the spec) is saved in the layout state, along with information on how to align the box within this rectangle when its width and height are resolved.
79 lines
2.6 KiB
C++
79 lines
2.6 KiB
C++
/*
|
|
* Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/OwnPtr.h>
|
|
#include <LibGfx/Rect.h>
|
|
#include <LibJS/Heap/Cell.h>
|
|
#include <LibWeb/Layout/Node.h>
|
|
|
|
namespace Web::Layout {
|
|
|
|
struct LineBoxFragmentCoordinate {
|
|
size_t line_box_index { 0 };
|
|
size_t fragment_index { 0 };
|
|
};
|
|
|
|
class Box : public NodeWithStyleAndBoxModelMetrics {
|
|
JS_CELL(Box, NodeWithStyleAndBoxModelMetrics);
|
|
|
|
public:
|
|
Painting::PaintableBox const* paintable_box() const;
|
|
Painting::PaintableBox* paintable_box();
|
|
|
|
bool is_body() const;
|
|
|
|
// https://www.w3.org/TR/css-images-3/#natural-dimensions
|
|
Optional<CSSPixels> natural_width() const { return m_natural_width; }
|
|
Optional<CSSPixels> natural_height() const { return m_natural_height; }
|
|
Optional<CSSPixelFraction> natural_aspect_ratio() const { return m_natural_aspect_ratio; }
|
|
|
|
bool has_natural_width() const { return natural_width().has_value(); }
|
|
bool has_natural_height() const { return natural_height().has_value(); }
|
|
bool has_natural_aspect_ratio() const { return natural_aspect_ratio().has_value(); }
|
|
|
|
void set_natural_width(Optional<CSSPixels> width) { m_natural_width = width; }
|
|
void set_natural_height(Optional<CSSPixels> height) { m_natural_height = height; }
|
|
void set_natural_aspect_ratio(Optional<CSSPixelFraction> ratio) { m_natural_aspect_ratio = ratio; }
|
|
|
|
// https://www.w3.org/TR/css-sizing-4/#preferred-aspect-ratio
|
|
Optional<CSSPixelFraction> preferred_aspect_ratio() const;
|
|
bool has_preferred_aspect_ratio() const { return preferred_aspect_ratio().has_value(); }
|
|
|
|
virtual ~Box() override;
|
|
|
|
virtual void did_set_content_size() { }
|
|
|
|
virtual JS::GCPtr<Painting::Paintable> create_paintable() const override;
|
|
|
|
bool is_scroll_container() const;
|
|
|
|
bool is_user_scrollable() const;
|
|
|
|
void add_contained_abspos_child(JS::NonnullGCPtr<Node> child) { m_contained_abspos_children.append(child); }
|
|
Vector<JS::NonnullGCPtr<Node>> const& contained_abspos_children() const { return m_contained_abspos_children; }
|
|
|
|
virtual void visit_edges(Cell::Visitor&) override;
|
|
|
|
protected:
|
|
Box(DOM::Document&, DOM::Node*, NonnullRefPtr<CSS::StyleProperties>);
|
|
Box(DOM::Document&, DOM::Node*, NonnullOwnPtr<CSS::ComputedValues>);
|
|
|
|
private:
|
|
virtual bool is_box() const final { return true; }
|
|
|
|
Optional<CSSPixels> m_natural_width;
|
|
Optional<CSSPixels> m_natural_height;
|
|
Optional<CSSPixelFraction> m_natural_aspect_ratio;
|
|
|
|
Vector<JS::NonnullGCPtr<Node>> m_contained_abspos_children;
|
|
};
|
|
|
|
template<>
|
|
inline bool Node::fast_is<Box>() const { return is_box(); }
|
|
|
|
}
|