/src/serenity/Userland/Libraries/LibWeb/Layout/Box.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> |
3 | | * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> |
4 | | * |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #include <LibWeb/DOM/Document.h> |
9 | | #include <LibWeb/HTML/HTMLHtmlElement.h> |
10 | | #include <LibWeb/Layout/BlockContainer.h> |
11 | | #include <LibWeb/Layout/Box.h> |
12 | | #include <LibWeb/Layout/FormattingContext.h> |
13 | | #include <LibWeb/Painting/PaintableBox.h> |
14 | | |
15 | | namespace Web::Layout { |
16 | | |
17 | | Box::Box(DOM::Document& document, DOM::Node* node, NonnullRefPtr<CSS::StyleProperties> style) |
18 | 0 | : NodeWithStyleAndBoxModelMetrics(document, node, move(style)) |
19 | 0 | { |
20 | 0 | } |
21 | | |
22 | | Box::Box(DOM::Document& document, DOM::Node* node, NonnullOwnPtr<CSS::ComputedValues> computed_values) |
23 | 0 | : NodeWithStyleAndBoxModelMetrics(document, node, move(computed_values)) |
24 | 0 | { |
25 | 0 | } |
26 | | |
27 | | Box::~Box() |
28 | 0 | { |
29 | 0 | } |
30 | | |
31 | | // https://www.w3.org/TR/css-overflow-3/#overflow-control |
32 | | static bool overflow_value_makes_box_a_scroll_container(CSS::Overflow overflow) |
33 | 0 | { |
34 | 0 | switch (overflow) { |
35 | 0 | case CSS::Overflow::Clip: |
36 | 0 | case CSS::Overflow::Visible: |
37 | 0 | return false; |
38 | 0 | case CSS::Overflow::Auto: |
39 | 0 | case CSS::Overflow::Hidden: |
40 | 0 | case CSS::Overflow::Scroll: |
41 | 0 | return true; |
42 | 0 | } |
43 | 0 | VERIFY_NOT_REACHED(); |
44 | 0 | } |
45 | | |
46 | | // https://www.w3.org/TR/css-overflow-3/#scroll-container |
47 | | bool Box::is_scroll_container() const |
48 | 0 | { |
49 | | // NOTE: This isn't in the spec, but we want the viewport to behave like a scroll container. |
50 | 0 | if (is_viewport()) |
51 | 0 | return true; |
52 | | |
53 | 0 | return overflow_value_makes_box_a_scroll_container(computed_values().overflow_x()) |
54 | 0 | || overflow_value_makes_box_a_scroll_container(computed_values().overflow_y()); |
55 | 0 | } |
56 | | |
57 | | bool Box::is_user_scrollable() const |
58 | 0 | { |
59 | | // FIXME: Support horizontal scroll as well (overflow-x) |
60 | 0 | return computed_values().overflow_y() == CSS::Overflow::Scroll || computed_values().overflow_y() == CSS::Overflow::Auto; |
61 | 0 | } |
62 | | |
63 | | bool Box::is_body() const |
64 | 0 | { |
65 | 0 | return dom_node() && dom_node() == document().body(); |
66 | 0 | } |
67 | | |
68 | | JS::GCPtr<Painting::Paintable> Box::create_paintable() const |
69 | 0 | { |
70 | 0 | return Painting::PaintableBox::create(*this); |
71 | 0 | } |
72 | | |
73 | | Painting::PaintableBox* Box::paintable_box() |
74 | 0 | { |
75 | 0 | return static_cast<Painting::PaintableBox*>(Node::paintable()); |
76 | 0 | } |
77 | | |
78 | | Painting::PaintableBox const* Box::paintable_box() const |
79 | 0 | { |
80 | 0 | return static_cast<Painting::PaintableBox const*>(Node::paintable()); |
81 | 0 | } |
82 | | |
83 | | Optional<CSSPixelFraction> Box::preferred_aspect_ratio() const |
84 | 0 | { |
85 | 0 | auto computed_aspect_ratio = computed_values().aspect_ratio(); |
86 | 0 | if (computed_aspect_ratio.use_natural_aspect_ratio_if_available && natural_aspect_ratio().has_value()) |
87 | 0 | return natural_aspect_ratio(); |
88 | | |
89 | 0 | if (!computed_aspect_ratio.preferred_ratio.has_value()) |
90 | 0 | return {}; |
91 | | |
92 | 0 | auto ratio = computed_aspect_ratio.preferred_ratio.release_value(); |
93 | 0 | if (ratio.is_degenerate()) |
94 | 0 | return {}; |
95 | | |
96 | 0 | return CSSPixelFraction(ratio.numerator(), ratio.denominator()); |
97 | 0 | } |
98 | | |
99 | | } |