2020-01-18 09:38:21 +01:00
|
|
|
/*
|
2024-10-04 13:19:50 +02:00
|
|
|
* Copyright (c) 2018-2022, Andreas Kling <andreas@ladybird.org>
|
2020-01-18 09:38:21 +01:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 09:38:21 +01:00
|
|
|
*/
|
|
|
|
|
2019-10-15 16:48:38 +02:00
|
|
|
#pragma once
|
|
|
|
|
2020-06-15 17:29:35 +02:00
|
|
|
#include <AK/OwnPtr.h>
|
2020-07-25 21:31:47 -07:00
|
|
|
#include <LibGfx/Rect.h>
|
2023-01-28 11:26:03 -05:00
|
|
|
#include <LibJS/Heap/Cell.h>
|
2020-11-22 15:53:01 +01:00
|
|
|
#include <LibWeb/Layout/Node.h>
|
2019-10-15 16:48:38 +02:00
|
|
|
|
2020-11-22 15:53:01 +01:00
|
|
|
namespace Web::Layout {
|
2020-03-07 10:27:02 +01:00
|
|
|
|
2022-02-28 12:41:23 +01:00
|
|
|
struct LineBoxFragmentCoordinate {
|
|
|
|
size_t line_box_index { 0 };
|
|
|
|
size_t fragment_index { 0 };
|
|
|
|
};
|
|
|
|
|
2020-11-22 15:53:01 +01:00
|
|
|
class Box : public NodeWithStyleAndBoxModelMetrics {
|
2024-11-15 04:01:23 +13:00
|
|
|
GC_CELL(Box, NodeWithStyleAndBoxModelMetrics);
|
2022-10-17 14:41:50 +02:00
|
|
|
|
2019-10-15 16:48:38 +02:00
|
|
|
public:
|
2023-04-20 16:00:42 +01:00
|
|
|
Painting::PaintableBox const* paintable_box() const;
|
2023-08-07 00:51:05 +02:00
|
|
|
Painting::PaintableBox* paintable_box();
|
2020-06-10 10:42:29 +02:00
|
|
|
|
2023-06-08 15:56:28 +01:00
|
|
|
// 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; }
|
2023-09-03 17:33:58 -05:00
|
|
|
Optional<CSSPixelFraction> natural_aspect_ratio() const { return m_natural_aspect_ratio; }
|
2021-10-14 18:37:24 +02:00
|
|
|
|
2023-06-08 15:56:28 +01:00
|
|
|
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; }
|
2023-09-03 17:33:58 -05:00
|
|
|
void set_natural_aspect_ratio(Optional<CSSPixelFraction> ratio) { m_natural_aspect_ratio = ratio; }
|
2021-10-14 18:37:24 +02:00
|
|
|
|
2023-06-08 16:47:50 +01:00
|
|
|
// https://www.w3.org/TR/css-sizing-4/#preferred-aspect-ratio
|
2023-09-03 17:33:58 -05:00
|
|
|
Optional<CSSPixelFraction> preferred_aspect_ratio() const;
|
2023-06-08 16:47:50 +01:00
|
|
|
bool has_preferred_aspect_ratio() const { return preferred_aspect_ratio().has_value(); }
|
|
|
|
|
2022-03-09 23:53:41 +01:00
|
|
|
virtual ~Box() override;
|
2021-01-06 14:10:53 +01:00
|
|
|
|
LibWeb: Fix iframes flickering on window resize
After finishing layout, iframe layout boxes (FrameBox) get notified
about their new size by LayoutState::commit(). This information is
forwarded to the nested browsing context, where it can be used for
layout of the nested document.
The problem here was that we notified the FrameBox twice. Once when
assigning the used offset to its paintable, and once when assigning its
size. Because the offset was assigned first, we ended up telling the
FrameBox "btw, your size is 0x0". This caused us to throw away all
the layout information we had for the nested document.
We'd then say "actually, your size is 300x200" (or something) but by
then it was already too late, and we had to do a full relayout.
This caused iframes to flicker as every time their containing document
was laid out, we'd nuke the iframe layout and redo it (on a zero timer).
The fix is pleasantly simple: we didn't need to inform the nested
document of its offset in the containing document's layout anyway. Only
its size is relevant. So we can simply remove the first call, which
removes the bogus 0x0 temporary size.
Note that iframes may still flicker if they change size in the
containing document. That's a separate issue that will require more
finesse to solve. However, this fixes a very noticeable common case.
2023-05-15 12:06:40 +02:00
|
|
|
virtual void did_set_content_size() { }
|
2020-06-05 19:13:27 +02:00
|
|
|
|
2024-11-15 04:01:23 +13:00
|
|
|
virtual GC::Ptr<Painting::Paintable> create_paintable() const override;
|
2022-03-10 14:02:25 +01:00
|
|
|
|
2024-11-15 04:01:23 +13:00
|
|
|
void add_contained_abspos_child(GC::Ref<Node> child) { m_contained_abspos_children.append(child); }
|
2024-09-13 16:35:31 +02:00
|
|
|
void clear_contained_abspos_children() { m_contained_abspos_children.clear(); }
|
2024-11-15 04:01:23 +13:00
|
|
|
Vector<GC::Ref<Node>> const& contained_abspos_children() const { return m_contained_abspos_children; }
|
2024-09-10 19:02:03 +02:00
|
|
|
|
|
|
|
virtual void visit_edges(Cell::Visitor&) override;
|
|
|
|
|
2022-03-09 23:53:41 +01:00
|
|
|
protected:
|
2024-10-26 17:42:27 +02:00
|
|
|
Box(DOM::Document&, DOM::Node*, CSS::StyleProperties);
|
2024-01-27 08:38:27 +01:00
|
|
|
Box(DOM::Document&, DOM::Node*, NonnullOwnPtr<CSS::ComputedValues>);
|
2022-03-09 23:53:41 +01:00
|
|
|
|
2019-10-15 16:48:38 +02:00
|
|
|
private:
|
2021-01-07 17:31:26 +01:00
|
|
|
virtual bool is_box() const final { return true; }
|
2023-01-23 17:04:24 +01:00
|
|
|
|
2023-06-08 15:56:28 +01:00
|
|
|
Optional<CSSPixels> m_natural_width;
|
|
|
|
Optional<CSSPixels> m_natural_height;
|
2023-09-03 17:33:58 -05:00
|
|
|
Optional<CSSPixelFraction> m_natural_aspect_ratio;
|
2024-09-10 19:02:03 +02:00
|
|
|
|
2024-11-15 04:01:23 +13:00
|
|
|
Vector<GC::Ref<Node>> m_contained_abspos_children;
|
2019-10-15 16:48:38 +02:00
|
|
|
};
|
|
|
|
|
2021-01-07 17:31:26 +01:00
|
|
|
template<>
|
2021-01-17 09:34:01 +01:00
|
|
|
inline bool Node::fast_is<Box>() const { return is_box(); }
|
2021-01-07 17:31:26 +01:00
|
|
|
|
|
|
|
}
|