| 
									
										
										
										
											2021-01-18 17:33:46 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2021-01-18 17:33:46 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 15:56:29 +02:00
										 |  |  | #include <LibWeb/Layout/Box.h>
 | 
					
						
							| 
									
										
										
										
											2021-01-18 17:33:46 +01:00
										 |  |  | #include <LibWeb/Layout/FormattingContext.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Web::Layout { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FlexFormattingContext final : public FormattingContext { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     FlexFormattingContext(FormattingState&, Box const& flex_container, FormattingContext* parent); | 
					
						
							| 
									
										
										
										
											2021-01-18 17:33:46 +01:00
										 |  |  |     ~FlexFormattingContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 12:19:42 +01:00
										 |  |  |     virtual bool inhibits_floating() const override { return true; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     virtual void run(Box const&, LayoutMode) override; | 
					
						
							| 
									
										
										
										
											2021-10-13 19:57:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     Box const& flex_container() const { return context_box(); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 19:57:26 +02:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2021-10-13 22:44:54 +02:00
										 |  |  |     struct DirectionAgnosticMargins { | 
					
						
							|  |  |  |         float main_before { 0 }; | 
					
						
							|  |  |  |         float main_after { 0 }; | 
					
						
							|  |  |  |         float cross_before { 0 }; | 
					
						
							|  |  |  |         float cross_after { 0 }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct FlexItem { | 
					
						
							|  |  |  |         Box& box; | 
					
						
							|  |  |  |         float flex_base_size { 0 }; | 
					
						
							|  |  |  |         float hypothetical_main_size { 0 }; | 
					
						
							|  |  |  |         float hypothetical_cross_size { 0 }; | 
					
						
							|  |  |  |         float hypothetical_cross_size_with_margins() { return hypothetical_cross_size + margins.cross_before + margins.cross_after; } | 
					
						
							|  |  |  |         float target_main_size { 0 }; | 
					
						
							|  |  |  |         bool frozen { false }; | 
					
						
							|  |  |  |         Optional<float> flex_factor {}; | 
					
						
							|  |  |  |         float scaled_flex_shrink_factor { 0 }; | 
					
						
							|  |  |  |         float max_content_flex_fraction { 0 }; | 
					
						
							|  |  |  |         float main_size { 0 }; | 
					
						
							|  |  |  |         float cross_size { 0 }; | 
					
						
							|  |  |  |         float main_offset { 0 }; | 
					
						
							|  |  |  |         float cross_offset { 0 }; | 
					
						
							|  |  |  |         DirectionAgnosticMargins margins {}; | 
					
						
							|  |  |  |         bool is_min_violation { false }; | 
					
						
							|  |  |  |         bool is_max_violation { false }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct FlexLine { | 
					
						
							|  |  |  |         Vector<FlexItem*> items; | 
					
						
							|  |  |  |         float cross_size { 0 }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 21:24:00 +02:00
										 |  |  |     bool has_definite_main_size(Box const&) const; | 
					
						
							|  |  |  |     bool has_definite_cross_size(Box const&) const; | 
					
						
							|  |  |  |     float specified_main_size(Box const&) const; | 
					
						
							|  |  |  |     float specified_cross_size(Box const&) const; | 
					
						
							|  |  |  |     bool has_main_min_size(Box const&) const; | 
					
						
							|  |  |  |     bool has_cross_min_size(Box const&) const; | 
					
						
							|  |  |  |     bool cross_size_is_absolute_or_resolved_nicely(NodeWithStyle const&) const; | 
					
						
							|  |  |  |     float specified_main_max_size(Box const&) const; | 
					
						
							|  |  |  |     float specified_cross_max_size(Box const&) const; | 
					
						
							|  |  |  |     float calculated_main_size(Box const&) const; | 
					
						
							|  |  |  |     bool is_cross_auto(Box const&) const; | 
					
						
							|  |  |  |     bool is_main_axis_margin_first_auto(Box const&) const; | 
					
						
							|  |  |  |     bool is_main_axis_margin_second_auto(Box const&) const; | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     float specified_main_size_of_child_box(Box const& child_box) const; | 
					
						
							| 
									
										
										
										
											2021-10-13 21:24:00 +02:00
										 |  |  |     float specified_main_min_size(Box const&) const; | 
					
						
							|  |  |  |     float specified_cross_min_size(Box const&) const; | 
					
						
							|  |  |  |     bool has_main_max_size(Box const&) const; | 
					
						
							|  |  |  |     bool has_cross_max_size(Box const&) const; | 
					
						
							|  |  |  |     float sum_of_margin_padding_border_in_main_axis(Box const&) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     void set_main_size(Box const&, float size); | 
					
						
							|  |  |  |     void set_cross_size(Box const&, float size); | 
					
						
							|  |  |  |     void set_offset(Box const&, float main_offset, float cross_offset); | 
					
						
							|  |  |  |     void set_main_axis_first_margin(Box const&, float margin); | 
					
						
							|  |  |  |     void set_main_axis_second_margin(Box const&, float margin); | 
					
						
							| 
									
										
										
										
											2021-10-13 21:24:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-27 09:50:09 +01:00
										 |  |  |     void setup_initial_width_and_height(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void generate_anonymous_flex_items(); | 
					
						
							| 
									
										
										
										
											2021-10-13 19:57:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 21:41:35 +02:00
										 |  |  |     struct AvailableSpace { | 
					
						
							|  |  |  |         float main { 0 }; | 
					
						
							|  |  |  |         float cross { 0 }; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     AvailableSpace determine_available_main_and_cross_space(bool& main_size_is_infinite, bool& main_is_constrained, bool& cross_is_constrained, float& main_min_size, float& main_max_size, float& cross_min_size, float& cross_max_size) const; | 
					
						
							| 
									
										
										
										
											2021-10-13 21:41:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     float layout_for_maximum_main_size(Box const&); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void determine_flex_base_size_and_hypothetical_main_size(FlexItem&); | 
					
						
							| 
									
										
										
										
											2021-10-13 21:49:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void determine_main_size_of_flex_container(bool main_is_constrained, bool main_size_is_infinite, float& main_available_size, float main_min_size, float main_max_size); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:03:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void collect_flex_items_into_flex_lines(float main_available_size); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:07:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:44:54 +02:00
										 |  |  |     void resolve_flexible_lengths(float main_available_size); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:11:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     float determine_hypothetical_cross_size_of_item(Box const&); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:15:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void calculate_cross_size_of_each_flex_line(float cross_min_size, float cross_max_size); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:17:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void determine_used_cross_size_of_each_flex_item(); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:19:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void distribute_any_remaining_free_space(float main_available_size); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:20:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void align_all_flex_items_along_the_cross_axis(); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:22:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:52:50 +02:00
										 |  |  |     void determine_flex_container_used_cross_size(float cross_min_size, float cross_max_size); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:24:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:44:54 +02:00
										 |  |  |     void align_all_flex_lines(); | 
					
						
							| 
									
										
										
										
											2021-10-13 22:25:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 19:57:26 +02:00
										 |  |  |     bool is_row_layout() const { return m_flex_direction == CSS::FlexDirection::Row || m_flex_direction == CSS::FlexDirection::RowReverse; } | 
					
						
							| 
									
										
										
										
											2021-10-13 23:38:04 +02:00
										 |  |  |     bool is_single_line() const { return flex_container().computed_values().flex_wrap() == CSS::FlexWrap::Nowrap; } | 
					
						
							| 
									
										
										
										
											2021-10-13 19:57:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:44:54 +02:00
										 |  |  |     void populate_specified_margins(FlexItem&, CSS::FlexDirection) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:51:24 +01:00
										 |  |  |     FormattingState::NodeState& m_flex_container_state; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 22:44:54 +02:00
										 |  |  |     Vector<FlexLine> m_flex_lines; | 
					
						
							|  |  |  |     Vector<FlexItem> m_flex_items; | 
					
						
							| 
									
										
										
										
											2021-10-13 19:57:26 +02:00
										 |  |  |     CSS::FlexDirection m_flex_direction {}; | 
					
						
							| 
									
										
										
										
											2021-01-18 17:33:46 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |