| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-02-20 18:56:08 +01:00
										 |  |  |  |  * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2023-03-23 17:26:13 +00:00
										 |  |  |  |  * Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.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
										 |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-30 20:22:25 +02:00
										 |  |  |  | #include <AK/TypeCasts.h>
 | 
					
						
							| 
									
										
										
										
											2020-02-06 15:04:03 +01:00
										 |  |  |  | #include <LibCore/DirIterator.h>
 | 
					
						
							| 
									
										
										
										
											2022-07-31 18:47:09 +02:00
										 |  |  |  | #include <LibWeb/CSS/Clip.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:32:51 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleProperties.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-23 17:26:13 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/AngleStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-23 21:17:43 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/ContentStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-04-26 21:05:38 +02:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/DisplayStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-17 20:25:18 +02:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/GridAutoFlowStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-24 14:25:00 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-24 14:53:08 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/GridTrackPlacementStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-04-29 17:59:07 +02:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-07-28 22:24:36 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/IdentifierStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-06-01 17:01:09 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-09-07 15:29:54 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/MathDepthStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-24 17:28:43 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-10-16 13:52:51 +02:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-25 00:02:50 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/RectStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2024-06-26 23:19:38 +01:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/ScrollbarGutterStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-24 17:45:25 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-24 17:48:42 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/StringStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-25 00:12:21 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/StyleValueList.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-24 17:59:33 +00:00
										 |  |  |  | #include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
 | 
					
						
							| 
									
										
										
										
											2021-10-06 20:02:41 +02:00
										 |  |  |  | #include <LibWeb/Layout/BlockContainer.h>
 | 
					
						
							| 
									
										
										
										
											2021-08-12 16:41:09 +01:00
										 |  |  |  | #include <LibWeb/Layout/Node.h>
 | 
					
						
							| 
									
										
										
										
											2022-09-17 21:25:50 +02:00
										 |  |  |  | #include <LibWeb/Platform/FontPlugin.h>
 | 
					
						
							| 
									
										
										
										
											2019-09-21 15:32:17 +03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 20:01:35 +02:00
										 |  |  |  | namespace Web::CSS { | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-16 07:44:48 +01:00
										 |  |  |  | bool StyleProperties::is_property_important(CSS::PropertyID property_id) const | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |     return m_property_values[to_underlying(property_id)].style && m_property_values[to_underlying(property_id)].important == Important::Yes; | 
					
						
							| 
									
										
										
										
											2024-03-16 07:44:48 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | bool StyleProperties::is_property_inherited(CSS::PropertyID property_id) const | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |     return m_property_values[to_underlying(property_id)].style && m_property_values[to_underlying(property_id)].inherited == Inherited::Yes; | 
					
						
							| 
									
										
										
										
											2024-03-16 07:44:48 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue const> value, CSS::CSSStyleDeclaration const* source_declaration, Inherited inherited, Important important) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     m_property_values[to_underlying(id)] = StyleAndSourceDeclaration { move(value), source_declaration, important, inherited }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void StyleProperties::set_animated_property(CSS::PropertyID id, NonnullRefPtr<StyleValue const> value) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 11:21:57 +01:00
										 |  |  |  |     m_animated_property_values.set(id, move(value)); | 
					
						
							| 
									
										
										
										
											2024-03-16 07:44:48 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | void StyleProperties::reset_animated_properties() | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 11:21:57 +01:00
										 |  |  |  |     m_animated_property_values.clear(); | 
					
						
							| 
									
										
										
										
											2019-09-21 15:32:17 +03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-20 18:56:08 +01:00
										 |  |  |  | NonnullRefPtr<StyleValue const> StyleProperties::property(CSS::PropertyID property_id) const | 
					
						
							| 
									
										
										
										
											2019-09-21 15:32:17 +03:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 11:21:57 +01:00
										 |  |  |  |     if (auto animated_value = m_animated_property_values.get(property_id).value_or(nullptr)) | 
					
						
							| 
									
										
										
										
											2024-03-16 07:44:48 +01:00
										 |  |  |  |         return *animated_value; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     // By the time we call this method, all properties have values assigned.
 | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |     return *m_property_values[to_underlying(property_id)].style; | 
					
						
							| 
									
										
										
										
											2019-09-21 15:32:17 +03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-20 18:56:08 +01:00
										 |  |  |  | RefPtr<StyleValue const> StyleProperties::maybe_null_property(CSS::PropertyID property_id) const | 
					
						
							| 
									
										
										
										
											2022-10-28 15:42:18 +01:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 11:21:57 +01:00
										 |  |  |  |     if (auto animated_value = m_animated_property_values.get(property_id).value_or(nullptr)) | 
					
						
							| 
									
										
										
										
											2024-03-16 07:44:48 +01:00
										 |  |  |  |         return *animated_value; | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |     return m_property_values[to_underlying(property_id)].style; | 
					
						
							| 
									
										
										
										
											2023-05-26 23:25:25 +03:30
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | CSS::CSSStyleDeclaration const* StyleProperties::property_source_declaration(CSS::PropertyID property_id) const | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |     return m_property_values[to_underlying(property_id)].declaration; | 
					
						
							| 
									
										
										
										
											2022-10-28 15:42:18 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-25 15:47:40 +02:00
										 |  |  |  | CSS::Size StyleProperties::size_value(CSS::PropertyID id) const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(id); | 
					
						
							|  |  |  |  |     if (value->is_identifier()) { | 
					
						
							|  |  |  |  |         switch (value->to_identifier()) { | 
					
						
							|  |  |  |  |         case ValueID::Auto: | 
					
						
							|  |  |  |  |             return CSS::Size::make_auto(); | 
					
						
							|  |  |  |  |         case ValueID::MinContent: | 
					
						
							|  |  |  |  |             return CSS::Size::make_min_content(); | 
					
						
							|  |  |  |  |         case ValueID::MaxContent: | 
					
						
							|  |  |  |  |             return CSS::Size::make_max_content(); | 
					
						
							| 
									
										
										
										
											2023-05-26 18:58:06 +02:00
										 |  |  |  |         case ValueID::FitContent: | 
					
						
							|  |  |  |  |             return CSS::Size::make_fit_content(); | 
					
						
							| 
									
										
										
										
											2022-09-25 15:47:40 +02:00
										 |  |  |  |         case ValueID::None: | 
					
						
							|  |  |  |  |             return CSS::Size::make_none(); | 
					
						
							|  |  |  |  |         default: | 
					
						
							|  |  |  |  |             VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (value->is_calculated()) | 
					
						
							| 
									
										
										
										
											2023-03-30 10:50:40 +01:00
										 |  |  |  |         return CSS::Size::make_calculated(const_cast<CalculatedStyleValue&>(value->as_calculated())); | 
					
						
							| 
									
										
										
										
											2022-09-25 15:47:40 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (value->is_percentage()) | 
					
						
							|  |  |  |  |         return CSS::Size::make_percentage(value->as_percentage().percentage()); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |     if (value->is_length()) { | 
					
						
							|  |  |  |  |         auto length = value->as_length().length(); | 
					
						
							| 
									
										
										
										
											2022-09-25 15:47:40 +02:00
										 |  |  |  |         if (length.is_auto()) | 
					
						
							|  |  |  |  |             return CSS::Size::make_auto(); | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |         return CSS::Size::make_length(length); | 
					
						
							| 
									
										
										
										
											2022-09-25 15:47:40 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // FIXME: Support `fit-content(<length>)`
 | 
					
						
							| 
									
										
										
										
											2023-01-06 19:02:26 +01:00
										 |  |  |  |     dbgln("FIXME: Unsupported size value: `{}`, treating as `auto`", value->to_string()); | 
					
						
							| 
									
										
										
										
											2022-09-25 15:47:40 +02:00
										 |  |  |  |     return CSS::Size::make_auto(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 16:19:43 +00:00
										 |  |  |  | LengthPercentage StyleProperties::length_percentage_or_fallback(CSS::PropertyID id, LengthPercentage const& fallback) const | 
					
						
							| 
									
										
										
										
											2022-02-18 15:10:11 +00:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     return length_percentage(id).value_or(fallback); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Optional<LengthPercentage> StyleProperties::length_percentage(CSS::PropertyID id) const | 
					
						
							| 
									
										
										
										
											2022-01-19 16:19:43 +00:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     auto value = property(id); | 
					
						
							| 
									
										
										
										
											2022-01-19 16:19:43 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 14:38:59 +00:00
										 |  |  |  |     if (value->is_calculated()) | 
					
						
							| 
									
										
										
										
											2023-02-20 18:56:08 +01:00
										 |  |  |  |         return LengthPercentage { const_cast<CalculatedStyleValue&>(value->as_calculated()) }; | 
					
						
							| 
									
										
										
										
											2022-01-19 16:19:43 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (value->is_percentage()) | 
					
						
							|  |  |  |  |         return value->as_percentage().percentage(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |     if (value->is_length()) | 
					
						
							|  |  |  |  |         return value->as_length().length(); | 
					
						
							| 
									
										
										
										
											2022-01-19 16:19:43 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-19 11:26:49 +01:00
										 |  |  |  |     if (value->has_auto()) | 
					
						
							|  |  |  |  |         return LengthPercentage { Length::make_auto() }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 15:10:11 +00:00
										 |  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2019-09-21 15:32:17 +03:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-09-25 11:55:04 +03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 20:01:00 +01:00
										 |  |  |  | LengthBox StyleProperties::length_box(CSS::PropertyID left_id, CSS::PropertyID top_id, CSS::PropertyID right_id, CSS::PropertyID bottom_id, const CSS::Length& default_value) const | 
					
						
							| 
									
										
										
										
											2020-05-11 23:04:59 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-24 17:45:42 +02:00
										 |  |  |  |     LengthBox box; | 
					
						
							| 
									
										
										
										
											2022-09-13 17:42:39 +02:00
										 |  |  |  |     box.left() = length_percentage_or_fallback(left_id, default_value); | 
					
						
							|  |  |  |  |     box.top() = length_percentage_or_fallback(top_id, default_value); | 
					
						
							|  |  |  |  |     box.right() = length_percentage_or_fallback(right_id, default_value); | 
					
						
							|  |  |  |  |     box.bottom() = length_percentage_or_fallback(bottom_id, default_value); | 
					
						
							| 
									
										
										
										
											2020-06-24 17:45:42 +02:00
										 |  |  |  |     return box; | 
					
						
							| 
									
										
										
										
											2020-05-11 23:04:59 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 19:20:20 +01:00
										 |  |  |  | Color StyleProperties::color_or_fallback(CSS::PropertyID id, Layout::NodeWithStyle const& node, Color fallback) const | 
					
						
							| 
									
										
										
										
											2019-09-28 22:18:19 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-08 15:34:19 +02:00
										 |  |  |  |     auto value = property(id); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     if (!value->has_color()) | 
					
						
							| 
									
										
										
										
											2019-09-28 22:18:19 +02:00
										 |  |  |  |         return fallback; | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value->to_color(node); | 
					
						
							| 
									
										
										
										
											2019-09-28 22:18:19 +02:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-06 11:23:58 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-20 18:56:08 +01:00
										 |  |  |  | NonnullRefPtr<Gfx::Font const> StyleProperties::font_fallback(bool monospace, bool bold) | 
					
						
							| 
									
										
										
										
											2021-04-22 20:47:47 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     if (monospace && bold) | 
					
						
							| 
									
										
										
										
											2022-09-17 21:25:50 +02:00
										 |  |  |  |         return Platform::FontPlugin::the().default_fixed_width_font().bold_variant(); | 
					
						
							| 
									
										
										
										
											2021-04-22 20:47:47 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (monospace) | 
					
						
							| 
									
										
										
										
											2022-09-17 21:25:50 +02:00
										 |  |  |  |         return Platform::FontPlugin::the().default_fixed_width_font(); | 
					
						
							| 
									
										
										
										
											2021-04-22 20:47:47 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (bold) | 
					
						
							| 
									
										
										
										
											2022-09-17 21:25:50 +02:00
										 |  |  |  |         return Platform::FontPlugin::the().default_font().bold_variant(); | 
					
						
							| 
									
										
										
										
											2021-04-22 20:47:47 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-17 21:25:50 +02:00
										 |  |  |  |     return Platform::FontPlugin::the().default_font(); | 
					
						
							| 
									
										
										
										
											2021-04-22 20:47:47 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-12 12:39:40 +01:00
										 |  |  |  | CSSPixels StyleProperties::compute_line_height(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto line_height = property(CSS::PropertyID::LineHeight); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (line_height->is_identifier() && line_height->to_identifier() == ValueID::Normal) | 
					
						
							| 
									
										
										
										
											2023-04-28 16:29:12 +01:00
										 |  |  |  |         return font_metrics.line_height; | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (line_height->is_length()) { | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |         auto line_height_length = line_height->as_length().length(); | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  |         if (!line_height_length.is_auto()) | 
					
						
							| 
									
										
										
										
											2023-04-28 16:29:12 +01:00
										 |  |  |  |             return line_height_length.to_px(viewport_rect, font_metrics, root_font_metrics); | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |     if (line_height->is_number()) | 
					
						
							|  |  |  |  |         return Length(line_height->as_number().number(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics); | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (line_height->is_percentage()) { | 
					
						
							|  |  |  |  |         // Percentages are relative to 1em. https://www.w3.org/TR/css-inline-3/#valdef-line-height-percentage
 | 
					
						
							|  |  |  |  |         auto& percentage = line_height->as_percentage().percentage(); | 
					
						
							| 
									
										
										
										
											2023-04-28 16:29:12 +01:00
										 |  |  |  |         return Length(percentage.as_fraction(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics); | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-18 21:15:51 +01:00
										 |  |  |  |     if (line_height->is_calculated()) { | 
					
						
							| 
									
										
										
										
											2024-01-12 12:39:40 +01:00
										 |  |  |  |         if (line_height->as_calculated().resolves_to_number()) { | 
					
						
							|  |  |  |  |             auto resolved = line_height->as_calculated().resolve_number(); | 
					
						
							|  |  |  |  |             if (!resolved.has_value()) { | 
					
						
							|  |  |  |  |                 dbgln("FIXME: Failed to resolve calc() line-height (number): {}", line_height->as_calculated().to_string()); | 
					
						
							|  |  |  |  |                 return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing()); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             return Length(resolved.value(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         auto resolved = line_height->as_calculated().resolve_length(Length::ResolutionContext { viewport_rect, font_metrics, root_font_metrics }); | 
					
						
							|  |  |  |  |         if (!resolved.has_value()) { | 
					
						
							|  |  |  |  |             dbgln("FIXME: Failed to resolve calc() line-height: {}", line_height->as_calculated().to_string()); | 
					
						
							|  |  |  |  |             return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing()); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return resolved->to_px(viewport_rect, font_metrics, root_font_metrics); | 
					
						
							| 
									
										
										
										
											2023-03-18 21:15:51 +01:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-28 16:29:12 +01:00
										 |  |  |  |     return font_metrics.line_height; | 
					
						
							| 
									
										
										
										
											2023-03-17 23:08:45 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 17:29:35 +02:00
										 |  |  |  | Optional<int> StyleProperties::z_index() const | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     auto value = property(CSS::PropertyID::ZIndex); | 
					
						
							| 
									
										
										
										
											2021-09-23 19:54:19 +01:00
										 |  |  |  |     if (value->has_auto()) | 
					
						
							| 
									
										
										
										
											2022-03-04 15:01:01 +01:00
										 |  |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2023-06-01 17:01:09 +01:00
										 |  |  |  |     if (value->is_integer()) { | 
					
						
							| 
									
										
										
										
											2023-04-26 07:19:07 +02:00
										 |  |  |  |         // Clamp z-index to the range of a signed 32-bit integer for consistency with other engines.
 | 
					
						
							| 
									
										
										
										
											2023-06-01 17:01:09 +01:00
										 |  |  |  |         auto integer = value->as_integer().integer(); | 
					
						
							|  |  |  |  |         if (integer >= NumericLimits<int>::max()) | 
					
						
							| 
									
										
										
										
											2023-04-26 07:19:07 +02:00
										 |  |  |  |             return NumericLimits<int>::max(); | 
					
						
							| 
									
										
										
										
											2023-06-01 17:01:09 +01:00
										 |  |  |  |         if (integer <= NumericLimits<int>::min()) | 
					
						
							| 
									
										
										
										
											2023-04-26 07:19:07 +02:00
										 |  |  |  |             return NumericLimits<int>::min(); | 
					
						
							|  |  |  |  |         return static_cast<int>(integer); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-10 20:37:09 +01:00
										 |  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2020-06-15 17:29:35 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-19 12:02:06 +01:00
										 |  |  |  | float StyleProperties::resolve_opacity_value(CSS::StyleValue const& value) | 
					
						
							| 
									
										
										
										
											2021-07-23 13:18:09 +03:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-27 17:44:22 +00:00
										 |  |  |  |     float unclamped_opacity = 1.0f; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |     if (value.is_number()) { | 
					
						
							|  |  |  |  |         unclamped_opacity = value.as_number().number(); | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  |     } else if (value.is_calculated()) { | 
					
						
							|  |  |  |  |         auto& calculated = value.as_calculated(); | 
					
						
							| 
									
										
										
										
											2023-06-30 16:29:06 +01:00
										 |  |  |  |         if (calculated.resolves_to_percentage()) { | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  |             auto maybe_percentage = value.as_calculated().resolve_percentage(); | 
					
						
							| 
									
										
										
										
											2022-01-27 17:44:22 +00:00
										 |  |  |  |             if (maybe_percentage.has_value()) | 
					
						
							|  |  |  |  |                 unclamped_opacity = maybe_percentage->as_fraction(); | 
					
						
							|  |  |  |  |             else | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  |                 dbgln("Unable to resolve calc() as opacity (percentage): {}", value.to_string()); | 
					
						
							| 
									
										
										
										
											2023-06-30 16:29:06 +01:00
										 |  |  |  |         } else if (calculated.resolves_to_number()) { | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  |             auto maybe_number = const_cast<CalculatedStyleValue&>(value.as_calculated()).resolve_number(); | 
					
						
							| 
									
										
										
										
											2022-01-27 17:44:22 +00:00
										 |  |  |  |             if (maybe_number.has_value()) | 
					
						
							|  |  |  |  |                 unclamped_opacity = maybe_number.value(); | 
					
						
							|  |  |  |  |             else | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  |                 dbgln("Unable to resolve calc() as opacity (number): {}", value.to_string()); | 
					
						
							| 
									
										
										
										
											2022-01-27 17:44:22 +00:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  |     } else if (value.is_percentage()) { | 
					
						
							|  |  |  |  |         unclamped_opacity = value.as_percentage().percentage().as_fraction(); | 
					
						
							| 
									
										
										
										
											2022-01-27 17:44:22 +00:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-23 13:18:09 +03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 17:44:22 +00:00
										 |  |  |  |     return clamp(unclamped_opacity, 0.0f, 1.0f); | 
					
						
							| 
									
										
										
										
											2021-07-23 13:18:09 +03:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 20:35:39 +01:00
										 |  |  |  | float StyleProperties::opacity() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Opacity); | 
					
						
							|  |  |  |  |     return resolve_opacity_value(*value); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | float StyleProperties::fill_opacity() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FillOpacity); | 
					
						
							|  |  |  |  |     return resolve_opacity_value(*value); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | float StyleProperties::stroke_opacity() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::StrokeOpacity); | 
					
						
							|  |  |  |  |     return resolve_opacity_value(*value); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | float StyleProperties::stop_opacity() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::StopOpacity); | 
					
						
							|  |  |  |  |     return resolve_opacity_value(*value); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-11 16:43:46 +01:00
										 |  |  |  | Optional<CSS::FillRule> StyleProperties::fill_rule() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FillRule); | 
					
						
							|  |  |  |  |     return value_id_to_fill_rule(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 20:19:43 +01:00
										 |  |  |  | Optional<CSS::ClipRule> StyleProperties::clip_rule() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ClipRule); | 
					
						
							|  |  |  |  |     return value_id_to_fill_rule(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-18 17:41:57 +01:00
										 |  |  |  | Optional<CSS::FlexDirection> StyleProperties::flex_direction() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FlexDirection); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_flex_direction(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-01-18 17:41:57 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-30 12:11:32 +02:00
										 |  |  |  | Optional<CSS::FlexWrap> StyleProperties::flex_wrap() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FlexWrap); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_flex_wrap(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-05-30 12:11:32 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 19:39:07 +02:00
										 |  |  |  | Optional<CSS::FlexBasis> StyleProperties::flex_basis() const | 
					
						
							| 
									
										
										
										
											2021-05-30 14:23:43 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     auto value = property(CSS::PropertyID::FlexBasis); | 
					
						
							| 
									
										
										
										
											2021-05-30 14:23:43 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 11:52:01 +00:00
										 |  |  |  |     if (value->is_identifier() && value->to_identifier() == CSS::ValueID::Content) | 
					
						
							| 
									
										
										
										
											2023-06-21 19:39:07 +02:00
										 |  |  |  |         return CSS::FlexBasisContent {}; | 
					
						
							| 
									
										
										
										
											2021-05-30 14:23:43 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 19:39:07 +02:00
										 |  |  |  |     return size_value(CSS::PropertyID::FlexBasis); | 
					
						
							| 
									
										
										
										
											2021-05-30 14:23:43 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 15:22:08 +02:00
										 |  |  |  | float StyleProperties::flex_grow() const | 
					
						
							| 
									
										
										
										
											2021-05-30 20:22:25 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FlexGrow); | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |     if (!value->is_number()) | 
					
						
							| 
									
										
										
										
											2021-10-19 15:22:08 +02:00
										 |  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |     return value->as_number().number(); | 
					
						
							| 
									
										
										
										
											2021-05-30 20:22:25 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 15:22:08 +02:00
										 |  |  |  | float StyleProperties::flex_shrink() const | 
					
						
							| 
									
										
										
										
											2021-05-30 20:22:25 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FlexShrink); | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |     if (!value->is_number()) | 
					
						
							| 
									
										
										
										
											2021-10-19 15:22:08 +02:00
										 |  |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |     return value->as_number().number(); | 
					
						
							| 
									
										
										
										
											2021-05-30 20:22:25 +02:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-19 15:22:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 22:11:38 +02:00
										 |  |  |  | int StyleProperties::order() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Order); | 
					
						
							| 
									
										
										
										
											2023-06-01 17:01:09 +01:00
										 |  |  |  |     if (!value->is_integer()) | 
					
						
							| 
									
										
										
										
											2022-03-31 22:11:38 +02:00
										 |  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2023-06-01 17:01:09 +01:00
										 |  |  |  |     return value->as_integer().integer(); | 
					
						
							| 
									
										
										
										
											2022-03-31 22:11:38 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 12:21:27 +01:00
										 |  |  |  | Optional<CSS::ImageRendering> StyleProperties::image_rendering() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ImageRendering); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_image_rendering(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2022-02-18 12:21:27 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-16 02:35:03 +00:00
										 |  |  |  | CSS::Length StyleProperties::border_spacing_horizontal() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::BorderSpacing); | 
					
						
							|  |  |  |  |     if (value->is_length()) | 
					
						
							|  |  |  |  |         return value->as_length().length(); | 
					
						
							|  |  |  |  |     auto const& list = value->as_value_list(); | 
					
						
							|  |  |  |  |     return list.value_at(0, false)->as_length().length(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | CSS::Length StyleProperties::border_spacing_vertical() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::BorderSpacing); | 
					
						
							|  |  |  |  |     if (value->is_length()) | 
					
						
							|  |  |  |  |         return value->as_length().length(); | 
					
						
							|  |  |  |  |     auto const& list = value->as_value_list(); | 
					
						
							|  |  |  |  |     return list.value_at(1, false)->as_length().length(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-07 02:10:55 +00:00
										 |  |  |  | Optional<CSS::CaptionSide> StyleProperties::caption_side() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::CaptionSide); | 
					
						
							|  |  |  |  |     return value_id_to_caption_side(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-31 18:47:09 +02:00
										 |  |  |  | CSS::Clip StyleProperties::clip() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Clip); | 
					
						
							| 
									
										
										
										
											2023-05-26 17:04:10 +01:00
										 |  |  |  |     if (!value->is_rect()) | 
					
						
							| 
									
										
										
										
											2022-07-31 18:47:09 +02:00
										 |  |  |  |         return CSS::Clip::make_auto(); | 
					
						
							|  |  |  |  |     return CSS::Clip(value->as_rect().rect()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-16 18:38:26 +02:00
										 |  |  |  | Optional<CSS::JustifyContent> StyleProperties::justify_content() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::JustifyContent); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_justify_content(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-07-16 18:38:26 +02:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-05-30 20:22:25 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-14 20:49:22 +02:00
										 |  |  |  | Optional<CSS::JustifyItems> StyleProperties::justify_items() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::JustifyItems); | 
					
						
							|  |  |  |  |     return value_id_to_justify_items(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-14 14:41:22 +02:00
										 |  |  |  | Optional<CSS::JustifySelf> StyleProperties::justify_self() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::JustifySelf); | 
					
						
							|  |  |  |  |     return value_id_to_justify_self(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 18:05:21 +01:00
										 |  |  |  | Vector<CSS::Transformation> StyleProperties::transformations_for_style_value(StyleValue const& value) | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-01-06 18:05:21 +01:00
										 |  |  |  |     if (value.is_identifier() && value.to_identifier() == CSS::ValueID::None) | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |         return {}; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 18:05:21 +01:00
										 |  |  |  |     if (!value.is_value_list()) | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |         return {}; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 18:05:21 +01:00
										 |  |  |  |     auto& list = value.as_value_list(); | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     Vector<CSS::Transformation> transformations; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     for (auto& it : list.values()) { | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |         if (!it->is_transformation()) | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |             return {}; | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |         auto& transformation_style_value = it->as_transformation(); | 
					
						
							| 
									
										
										
										
											2023-10-13 17:25:23 +01:00
										 |  |  |  |         auto function = transformation_style_value.transform_function(); | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |         auto function_metadata = transform_function_metadata(function); | 
					
						
							| 
									
										
										
										
											2022-07-14 17:45:23 +01:00
										 |  |  |  |         Vector<TransformValue> values; | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |         size_t argument_index = 0; | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |         for (auto& transformation_value : transformation_style_value.values()) { | 
					
						
							| 
									
										
										
										
											2023-05-27 19:21:42 +02:00
										 |  |  |  |             if (transformation_value->is_calculated()) { | 
					
						
							|  |  |  |  |                 auto& calculated = transformation_value->as_calculated(); | 
					
						
							| 
									
										
										
										
											2024-01-09 12:39:17 +04:00
										 |  |  |  |                 if (calculated.resolves_to_length_percentage()) { | 
					
						
							| 
									
										
										
										
											2023-07-15 10:23:43 +02:00
										 |  |  |  |                     values.append(CSS::LengthPercentage { calculated }); | 
					
						
							| 
									
										
										
										
											2023-05-27 19:21:42 +02:00
										 |  |  |  |                 } else if (calculated.resolves_to_percentage()) { | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |                     // FIXME: Maybe transform this for loop to always check the metadata for the correct types
 | 
					
						
							|  |  |  |  |                     if (function_metadata.parameters[argument_index].type == TransformFunctionParameterType::NumberPercentage) { | 
					
						
							|  |  |  |  |                         values.append(NumberPercentage { calculated.resolve_percentage().value() }); | 
					
						
							|  |  |  |  |                     } else { | 
					
						
							|  |  |  |  |                         values.append(LengthPercentage { calculated.resolve_percentage().value() }); | 
					
						
							|  |  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-05-27 19:21:42 +02:00
										 |  |  |  |                 } else if (calculated.resolves_to_number()) { | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |                     values.append({ Number(Number::Type::Number, calculated.resolve_number().value()) }); | 
					
						
							| 
									
										
										
										
											2023-05-27 19:21:42 +02:00
										 |  |  |  |                 } else if (calculated.resolves_to_angle()) { | 
					
						
							|  |  |  |  |                     values.append({ calculated.resolve_angle().value() }); | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                     dbgln("FIXME: Unsupported calc value in transform! {}", calculated.to_string()); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } else if (transformation_value->is_length()) { | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |                 values.append({ transformation_value->as_length().length() }); | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |             } else if (transformation_value->is_percentage()) { | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |                 if (function_metadata.parameters[argument_index].type == TransformFunctionParameterType::NumberPercentage) { | 
					
						
							|  |  |  |  |                     values.append(NumberPercentage { transformation_value->as_percentage().percentage() }); | 
					
						
							|  |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                     values.append(LengthPercentage { transformation_value->as_percentage().percentage() }); | 
					
						
							|  |  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-06-01 16:16:15 +01:00
										 |  |  |  |             } else if (transformation_value->is_number()) { | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |                 values.append({ Number(Number::Type::Number, transformation_value->as_number().number()) }); | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |             } else if (transformation_value->is_angle()) { | 
					
						
							|  |  |  |  |                 values.append({ transformation_value->as_angle().angle() }); | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2023-05-27 19:21:42 +02:00
										 |  |  |  |                 dbgln("FIXME: Unsupported value in transform! {}", transformation_value->to_string()); | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-01-08 18:51:19 +01:00
										 |  |  |  |             argument_index++; | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-13 17:25:23 +01:00
										 |  |  |  |         transformations.empend(function, move(values)); | 
					
						
							| 
									
										
										
										
											2021-09-18 17:20:00 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     return transformations; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 18:05:21 +01:00
										 |  |  |  | Vector<CSS::Transformation> StyleProperties::transformations() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return transformations_for_style_value(property(CSS::PropertyID::Transform)); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 19:38:00 +01:00
										 |  |  |  | static Optional<LengthPercentage> length_percentage_for_style_value(StyleValue const& value) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     if (value.is_length()) | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |         return value.as_length().length(); | 
					
						
							| 
									
										
										
										
											2022-03-21 19:38:00 +01:00
										 |  |  |  |     if (value.is_percentage()) | 
					
						
							|  |  |  |  |         return value.as_percentage().percentage(); | 
					
						
							|  |  |  |  |     return {}; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-25 17:02:37 +00:00
										 |  |  |  | Optional<CSS::TransformBox> StyleProperties::transform_box() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TransformBox); | 
					
						
							|  |  |  |  |     return value_id_to_transform_box(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 19:38:00 +01:00
										 |  |  |  | CSS::TransformOrigin StyleProperties::transform_origin() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TransformOrigin); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     if (!value->is_value_list() || value->as_value_list().size() != 2) | 
					
						
							| 
									
										
										
										
											2022-03-21 19:38:00 +01:00
										 |  |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     auto const& list = value->as_value_list(); | 
					
						
							| 
									
										
										
										
											2022-03-21 19:38:00 +01:00
										 |  |  |  |     auto x_value = length_percentage_for_style_value(list.values()[0]); | 
					
						
							|  |  |  |  |     auto y_value = length_percentage_for_style_value(list.values()[1]); | 
					
						
							|  |  |  |  |     if (!x_value.has_value() || !y_value.has_value()) { | 
					
						
							|  |  |  |  |         return {}; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return { x_value.value(), y_value.value() }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-18 20:49:00 +01:00
										 |  |  |  | Optional<Color> StyleProperties::accent_color(Layout::NodeWithStyle const& node) const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::AccentColor); | 
					
						
							|  |  |  |  |     if (value->has_color()) | 
					
						
							|  |  |  |  |         return value->to_color(node); | 
					
						
							|  |  |  |  |     return {}; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-14 13:50:06 +02:00
										 |  |  |  | Optional<CSS::AlignContent> StyleProperties::align_content() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::AlignContent); | 
					
						
							|  |  |  |  |     return value_id_to_align_content(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-15 18:27:20 +02:00
										 |  |  |  | Optional<CSS::AlignItems> StyleProperties::align_items() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::AlignItems); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_align_items(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-09-15 18:27:20 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-11 23:52:36 +02:00
										 |  |  |  | Optional<CSS::AlignSelf> StyleProperties::align_self() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::AlignSelf); | 
					
						
							|  |  |  |  |     return value_id_to_align_self(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-22 16:05:11 +01:00
										 |  |  |  | Optional<CSS::Appearance> StyleProperties::appearance() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Appearance); | 
					
						
							|  |  |  |  |     auto appearance = value_id_to_appearance(value->to_identifier()); | 
					
						
							|  |  |  |  |     if (appearance.has_value()) { | 
					
						
							|  |  |  |  |         switch (*appearance) { | 
					
						
							|  |  |  |  |         // Note: All these compatibility values can be treated as 'auto'
 | 
					
						
							|  |  |  |  |         case CSS::Appearance::Textfield: | 
					
						
							|  |  |  |  |         case CSS::Appearance::MenulistButton: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Searchfield: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Textarea: | 
					
						
							|  |  |  |  |         case CSS::Appearance::PushButton: | 
					
						
							|  |  |  |  |         case CSS::Appearance::SliderHorizontal: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Checkbox: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Radio: | 
					
						
							|  |  |  |  |         case CSS::Appearance::SquareButton: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Menulist: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Listbox: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Meter: | 
					
						
							|  |  |  |  |         case CSS::Appearance::ProgressBar: | 
					
						
							|  |  |  |  |         case CSS::Appearance::Button: | 
					
						
							|  |  |  |  |             appearance = CSS::Appearance::Auto; | 
					
						
							|  |  |  |  |             break; | 
					
						
							|  |  |  |  |         default: | 
					
						
							|  |  |  |  |             break; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return appearance; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 08:31:19 +01:00
										 |  |  |  | CSS::BackdropFilter StyleProperties::backdrop_filter() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::BackdropFilter); | 
					
						
							|  |  |  |  |     if (value->is_filter_value_list()) | 
					
						
							|  |  |  |  |         return BackdropFilter(value->as_filter_value_list()); | 
					
						
							|  |  |  |  |     return BackdropFilter::make_none(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 15:17:36 +02:00
										 |  |  |  | Optional<CSS::Positioning> StyleProperties::position() const | 
					
						
							| 
									
										
										
										
											2020-03-23 17:29:15 +01:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-14 18:47:00 +01:00
										 |  |  |  |     auto value = property(CSS::PropertyID::Position); | 
					
						
							| 
									
										
										
										
											2023-10-27 15:17:36 +02:00
										 |  |  |  |     return value_id_to_positioning(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-03-23 17:29:15 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 20:58:27 +03:00
										 |  |  |  | bool StyleProperties::operator==(StyleProperties const& other) const | 
					
						
							| 
									
										
										
										
											2019-10-14 18:32:02 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     if (m_property_values.size() != other.m_property_values.size()) | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 20:21:49 +01:00
										 |  |  |  |     for (size_t i = 0; i < m_property_values.size(); ++i) { | 
					
						
							| 
									
										
										
										
											2023-05-26 23:25:25 +03:30
										 |  |  |  |         auto const& my_style = m_property_values[i]; | 
					
						
							|  |  |  |  |         auto const& other_style = other.m_property_values[i]; | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |         if (!my_style.style) { | 
					
						
							|  |  |  |  |             if (other_style.style) | 
					
						
							| 
									
										
										
										
											2022-02-18 20:21:49 +01:00
										 |  |  |  |                 return false; | 
					
						
							|  |  |  |  |             continue; | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |         if (!other_style.style) | 
					
						
							| 
									
										
										
										
											2019-10-14 18:32:02 +02:00
										 |  |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2024-03-18 12:02:29 +01:00
										 |  |  |  |         auto const& my_value = *my_style.style; | 
					
						
							|  |  |  |  |         auto const& other_value = *other_style.style; | 
					
						
							| 
									
										
										
										
											2019-10-14 18:32:02 +02:00
										 |  |  |  |         if (my_value.type() != other_value.type()) | 
					
						
							|  |  |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2020-12-14 15:56:01 +01:00
										 |  |  |  |         if (my_value != other_value) | 
					
						
							| 
									
										
										
										
											2019-10-14 18:32:02 +02:00
										 |  |  |  |             return false; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return true; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 19:12:00 +01:00
										 |  |  |  | Optional<CSS::TextAnchor> StyleProperties::text_anchor() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TextAnchor); | 
					
						
							|  |  |  |  |     return value_id_to_text_anchor(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-14 18:38:02 +01:00
										 |  |  |  | Optional<CSS::TextAlign> StyleProperties::text_align() const | 
					
						
							| 
									
										
										
										
											2020-06-13 10:54:58 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-14 18:38:02 +01:00
										 |  |  |  |     auto value = property(CSS::PropertyID::TextAlign); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_text_align(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2022-03-12 19:31:32 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Optional<CSS::TextJustify> StyleProperties::text_justify() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TextJustify); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_text_justify(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-06-13 10:54:58 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 19:47:13 +01:00
										 |  |  |  | Optional<CSS::PointerEvents> StyleProperties::pointer_events() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::PointerEvents); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_pointer_events(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-10-05 19:47:13 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-24 16:37:44 +02:00
										 |  |  |  | Optional<CSS::WhiteSpace> StyleProperties::white_space() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::WhiteSpace); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_white_space(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-06-24 16:37:44 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:11:55 +01:00
										 |  |  |  | Optional<CSS::LineStyle> StyleProperties::line_style(CSS::PropertyID property_id) const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(property_id); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_line_style(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2023-08-02 17:24:14 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Optional<CSS::OutlineStyle> StyleProperties::outline_style() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::OutlineStyle); | 
					
						
							|  |  |  |  |     return value_id_to_outline_style(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-12-04 16:11:55 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-26 15:08:42 +02:00
										 |  |  |  | Optional<CSS::Float> StyleProperties::float_() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Float); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_float(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-06-26 15:08:42 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-06 01:45:51 +01:00
										 |  |  |  | Optional<CSS::Clear> StyleProperties::clear() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Clear); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_clear(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-12-06 01:45:51 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  | StyleProperties::ContentDataAndQuoteNestingLevel StyleProperties::content(u32 initial_quote_nesting_level) const | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     auto value = property(CSS::PropertyID::Content); | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |     auto quotes_data = quotes(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |     auto quote_nesting_level = initial_quote_nesting_level; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |     auto get_quote_string = [&](bool open, auto depth) { | 
					
						
							|  |  |  |  |         switch (quotes_data.type) { | 
					
						
							|  |  |  |  |         case QuotesData::Type::None: | 
					
						
							| 
									
										
										
										
											2024-07-17 12:42:12 +01:00
										 |  |  |  |             return FlyString {}; | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |         case QuotesData::Type::Auto: | 
					
						
							|  |  |  |  |             // FIXME: "A typographically appropriate used value for quotes is automatically chosen by the UA
 | 
					
						
							|  |  |  |  |             //        based on the content language of the element and/or its parent."
 | 
					
						
							|  |  |  |  |             if (open) | 
					
						
							| 
									
										
										
										
											2024-07-17 12:42:12 +01:00
										 |  |  |  |                 return depth == 0 ? "“"_fly_string : "‘"_fly_string; | 
					
						
							|  |  |  |  |             return depth == 0 ? "”"_fly_string : "’"_fly_string; | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |         case QuotesData::Type::Specified: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:28:40 +01:00
										 |  |  |  |             // If the depth is greater than the number of pairs, the last pair is repeated.
 | 
					
						
							|  |  |  |  |             auto& level = quotes_data.strings[min(depth, quotes_data.strings.size() - 1)]; | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |             return open ? level[0] : level[1]; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |     if (value->is_content()) { | 
					
						
							|  |  |  |  |         auto& content_style_value = value->as_content(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         CSS::ContentData content_data; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // FIXME: The content is a list of things: strings, identifiers or functions that return strings, and images.
 | 
					
						
							|  |  |  |  |         //        So it can't always be represented as a single String, but may have to be multiple boxes.
 | 
					
						
							|  |  |  |  |         //        For now, we'll just assume strings since that is easiest.
 | 
					
						
							|  |  |  |  |         StringBuilder builder; | 
					
						
							|  |  |  |  |         for (auto const& item : content_style_value.content().values()) { | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |             if (item->is_string()) { | 
					
						
							| 
									
										
										
										
											2023-09-12 11:33:11 +01:00
										 |  |  |  |                 builder.append(item->as_string().string_value()); | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |             } else if (item->is_identifier()) { | 
					
						
							|  |  |  |  |                 switch (item->to_identifier()) { | 
					
						
							|  |  |  |  |                 case ValueID::OpenQuote: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |                     builder.append(get_quote_string(true, quote_nesting_level++)); | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 case ValueID::CloseQuote: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |                     // A 'close-quote' or 'no-close-quote' that would make the depth negative is in error and is ignored
 | 
					
						
							|  |  |  |  |                     // (at rendering time): the depth stays at 0 and no quote mark is rendered (although the rest of the
 | 
					
						
							|  |  |  |  |                     // 'content' property's value is still inserted).
 | 
					
						
							|  |  |  |  |                     // - https://www.w3.org/TR/CSS21/generate.html#quotes-insert
 | 
					
						
							|  |  |  |  |                     // (This is missing from the CONTENT-3 spec.)
 | 
					
						
							|  |  |  |  |                     if (quote_nesting_level > 0) | 
					
						
							|  |  |  |  |                         builder.append(get_quote_string(false, --quote_nesting_level)); | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 case ValueID::NoOpenQuote: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |                     quote_nesting_level++; | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 case ValueID::NoCloseQuote: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |                     // NOTE: See CloseQuote
 | 
					
						
							|  |  |  |  |                     if (quote_nesting_level > 0) | 
					
						
							|  |  |  |  |                         quote_nesting_level--; | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 default: | 
					
						
							|  |  |  |  |                     dbgln("`{}` is not supported in `content` (yet?)", item->to_string()); | 
					
						
							|  |  |  |  |                     break; | 
					
						
							|  |  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |                 // TODO: Implement counters, images, and other things.
 | 
					
						
							|  |  |  |  |                 dbgln("`{}` is not supported in `content` (yet?)", item->to_string()); | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         content_data.type = ContentData::Type::String; | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |         content_data.data = MUST(builder.to_string()); | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (content_style_value.has_alt_text()) { | 
					
						
							|  |  |  |  |             StringBuilder alt_text_builder; | 
					
						
							|  |  |  |  |             for (auto const& item : content_style_value.alt_text()->values()) { | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |                 if (item->is_string()) { | 
					
						
							| 
									
										
										
										
											2023-09-12 11:33:11 +01:00
										 |  |  |  |                     alt_text_builder.append(item->as_string().string_value()); | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |                 } else { | 
					
						
							|  |  |  |  |                     // TODO: Implement counters
 | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-09-12 14:22:46 +01:00
										 |  |  |  |             content_data.alt_text = MUST(alt_text_builder.to_string()); | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |         return { content_data, quote_nesting_level }; | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     switch (value->to_identifier()) { | 
					
						
							|  |  |  |  |     case ValueID::None: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |         return { { ContentData::Type::None }, quote_nesting_level }; | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |     case ValueID::Normal: | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |         return { { ContentData::Type::Normal }, quote_nesting_level }; | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  |     default: | 
					
						
							|  |  |  |  |         break; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-18 15:41:17 +01:00
										 |  |  |  |     return { {}, quote_nesting_level }; | 
					
						
							| 
									
										
										
										
											2022-02-24 16:52:58 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 17:41:00 +00:00
										 |  |  |  | Optional<CSS::Cursor> StyleProperties::cursor() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Cursor); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_cursor(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-02-21 17:41:00 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 15:42:57 +01:00
										 |  |  |  | Optional<CSS::Visibility> StyleProperties::visibility() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Visibility); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     if (!value->is_identifier()) | 
					
						
							| 
									
										
										
										
											2022-03-21 15:42:57 +01:00
										 |  |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_visibility(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2022-03-21 15:42:57 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-26 21:05:38 +02:00
										 |  |  |  | Display StyleProperties::display() const | 
					
						
							| 
									
										
										
										
											2020-06-24 16:22:16 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-04-26 21:05:38 +02:00
										 |  |  |  |     auto value = property(PropertyID::Display); | 
					
						
							|  |  |  |  |     if (value->is_display()) { | 
					
						
							|  |  |  |  |         return value->as_display().display(); | 
					
						
							| 
									
										
										
										
											2020-12-14 22:22:35 +01:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-26 21:05:38 +02:00
										 |  |  |  |     return Display::from_short(Display::Short::Inline); | 
					
						
							| 
									
										
										
										
											2020-06-24 16:22:16 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 16:22:35 +01:00
										 |  |  |  | Vector<CSS::TextDecorationLine> StyleProperties::text_decoration_line() const | 
					
						
							| 
									
										
										
										
											2020-12-15 13:36:27 +01:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TextDecorationLine); | 
					
						
							| 
									
										
										
										
											2022-04-14 16:22:35 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (value->is_value_list()) { | 
					
						
							|  |  |  |  |         Vector<CSS::TextDecorationLine> lines; | 
					
						
							|  |  |  |  |         auto& values = value->as_value_list().values(); | 
					
						
							|  |  |  |  |         for (auto const& item : values) { | 
					
						
							| 
									
										
										
										
											2023-03-06 14:33:11 +01:00
										 |  |  |  |             lines.append(value_id_to_text_decoration_line(item->to_identifier()).value()); | 
					
						
							| 
									
										
										
										
											2022-04-14 16:22:35 +01:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |         return lines; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (value->is_identifier() && value->to_identifier() == ValueID::None) | 
					
						
							|  |  |  |  |         return {}; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-06 19:02:26 +01:00
										 |  |  |  |     dbgln("FIXME: Unsupported value for text-decoration-line: {}", value->to_string()); | 
					
						
							| 
									
										
										
										
											2022-11-02 19:07:17 +01:00
										 |  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2020-12-15 13:36:27 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-20 20:27:55 +01:00
										 |  |  |  | Optional<CSS::TextDecorationStyle> StyleProperties::text_decoration_style() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TextDecorationStyle); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_text_decoration_style(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2022-01-20 20:27:55 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 14:15:49 +01:00
										 |  |  |  | Optional<CSS::TextTransform> StyleProperties::text_transform() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TextTransform); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_text_transform(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-12-15 14:15:49 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-15 16:50:39 +01:00
										 |  |  |  | Optional<CSS::ListStyleType> StyleProperties::list_style_type() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ListStyleType); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_list_style_type(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2020-12-15 16:50:39 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-02 23:05:15 +02:00
										 |  |  |  | Optional<CSS::ListStylePosition> StyleProperties::list_style_position() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ListStylePosition); | 
					
						
							|  |  |  |  |     return value_id_to_list_style_position(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-22 15:20:31 +01:00
										 |  |  |  | Optional<CSS::Overflow> StyleProperties::overflow_x() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return overflow(CSS::PropertyID::OverflowX); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Optional<CSS::Overflow> StyleProperties::overflow_y() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     return overflow(CSS::PropertyID::OverflowY); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Optional<CSS::Overflow> StyleProperties::overflow(CSS::PropertyID property_id) const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(property_id); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_overflow(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-02-22 15:20:31 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  | Vector<ShadowData> StyleProperties::shadow(PropertyID property_id, Layout::Node const& layout_node) const | 
					
						
							| 
									
										
										
										
											2021-07-23 21:22:31 +02:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     auto value = property(property_id); | 
					
						
							| 
									
										
										
										
											2021-07-23 21:22:31 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  |     auto resolve_to_length = [&layout_node](NonnullRefPtr<StyleValue const> const& value) -> Optional<Length> { | 
					
						
							|  |  |  |  |         if (value->is_length()) | 
					
						
							|  |  |  |  |             return value->as_length().length(); | 
					
						
							|  |  |  |  |         if (value->is_calculated()) | 
					
						
							|  |  |  |  |             return value->as_calculated().resolve_length(layout_node); | 
					
						
							|  |  |  |  |         return {}; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto make_shadow_data = [resolve_to_length](ShadowStyleValue const& value) -> Optional<ShadowData> { | 
					
						
							|  |  |  |  |         auto maybe_offset_x = resolve_to_length(value.offset_x()); | 
					
						
							|  |  |  |  |         if (!maybe_offset_x.has_value()) | 
					
						
							|  |  |  |  |             return {}; | 
					
						
							|  |  |  |  |         auto maybe_offset_y = resolve_to_length(value.offset_y()); | 
					
						
							|  |  |  |  |         if (!maybe_offset_y.has_value()) | 
					
						
							|  |  |  |  |             return {}; | 
					
						
							|  |  |  |  |         auto maybe_blur_radius = resolve_to_length(value.blur_radius()); | 
					
						
							|  |  |  |  |         if (!maybe_blur_radius.has_value()) | 
					
						
							|  |  |  |  |             return {}; | 
					
						
							|  |  |  |  |         auto maybe_spread_distance = resolve_to_length(value.spread_distance()); | 
					
						
							|  |  |  |  |         if (!maybe_spread_distance.has_value()) | 
					
						
							|  |  |  |  |             return {}; | 
					
						
							|  |  |  |  |         return ShadowData { | 
					
						
							|  |  |  |  |             value.color(), | 
					
						
							|  |  |  |  |             maybe_offset_x.release_value(), | 
					
						
							|  |  |  |  |             maybe_offset_y.release_value(), | 
					
						
							|  |  |  |  |             maybe_blur_radius.release_value(), | 
					
						
							|  |  |  |  |             maybe_spread_distance.release_value(), | 
					
						
							|  |  |  |  |             value.placement() | 
					
						
							|  |  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2022-02-08 14:48:37 +00:00
										 |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (value->is_value_list()) { | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  |         auto const& value_list = value->as_value_list(); | 
					
						
							| 
									
										
										
										
											2022-02-08 14:48:37 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 21:16:36 +00:00
										 |  |  |  |         Vector<ShadowData> shadow_data; | 
					
						
							|  |  |  |  |         shadow_data.ensure_capacity(value_list.size()); | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  |         for (auto const& layer_value : value_list.values()) { | 
					
						
							|  |  |  |  |             auto maybe_shadow_data = make_shadow_data(layer_value->as_shadow()); | 
					
						
							|  |  |  |  |             if (!maybe_shadow_data.has_value()) | 
					
						
							|  |  |  |  |                 return {}; | 
					
						
							|  |  |  |  |             shadow_data.append(maybe_shadow_data.release_value()); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-08 14:48:37 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 21:16:36 +00:00
										 |  |  |  |         return shadow_data; | 
					
						
							| 
									
										
										
										
											2022-02-08 14:48:37 +00:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 16:55:22 +00:00
										 |  |  |  |     if (value->is_shadow()) { | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  |         auto maybe_shadow_data = make_shadow_data(value->as_shadow()); | 
					
						
							|  |  |  |  |         if (!maybe_shadow_data.has_value()) | 
					
						
							|  |  |  |  |             return {}; | 
					
						
							|  |  |  |  |         return { maybe_shadow_data.release_value() }; | 
					
						
							| 
									
										
										
										
											2022-02-08 14:48:37 +00:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2021-07-23 21:22:31 +02:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-05 16:55:02 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  | Vector<ShadowData> StyleProperties::box_shadow(Layout::Node const& layout_node) const | 
					
						
							| 
									
										
										
										
											2022-03-23 21:16:36 +00:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  |     return shadow(PropertyID::BoxShadow, layout_node); | 
					
						
							| 
									
										
										
										
											2022-03-23 21:16:36 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  | Vector<ShadowData> StyleProperties::text_shadow(Layout::Node const& layout_node) const | 
					
						
							| 
									
										
										
										
											2022-03-23 21:16:36 +00:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-05-31 16:07:06 -04:00
										 |  |  |  |     return shadow(PropertyID::TextShadow, layout_node); | 
					
						
							| 
									
										
										
										
											2022-03-23 21:16:36 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-13 19:33:56 +01:00
										 |  |  |  | Optional<CSS::BoxSizing> StyleProperties::box_sizing() const | 
					
						
							| 
									
										
										
										
											2021-10-05 16:55:02 +01:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::BoxSizing); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_box_sizing(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2021-10-05 16:55:02 +01:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-26 01:34:07 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Variant<CSS::VerticalAlign, CSS::LengthPercentage> StyleProperties::vertical_align() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::VerticalAlign); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     if (value->is_identifier()) | 
					
						
							|  |  |  |  |         return value_id_to_vertical_align(value->to_identifier()).release_value(); | 
					
						
							| 
									
										
										
										
											2022-02-26 01:34:07 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     if (value->is_length()) | 
					
						
							| 
									
										
										
										
											2023-05-27 12:28:25 +01:00
										 |  |  |  |         return CSS::LengthPercentage(value->as_length().length()); | 
					
						
							| 
									
										
										
										
											2022-02-26 01:34:07 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     if (value->is_percentage()) | 
					
						
							|  |  |  |  |         return CSS::LengthPercentage(value->as_percentage().percentage()); | 
					
						
							| 
									
										
										
										
											2022-02-26 01:34:07 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 00:09:41 +02:00
										 |  |  |  |     if (value->is_calculated()) | 
					
						
							|  |  |  |  |         return LengthPercentage { const_cast<CalculatedStyleValue&>(value->as_calculated()) }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-26 01:34:07 +01:00
										 |  |  |  |     VERIFY_NOT_REACHED(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 14:54:21 +01:00
										 |  |  |  | Optional<CSS::FontVariant> StyleProperties::font_variant() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::FontVariant); | 
					
						
							| 
									
										
										
										
											2022-04-14 11:52:35 +01:00
										 |  |  |  |     return value_id_to_font_variant(value->to_identifier()); | 
					
						
							| 
									
										
										
										
											2022-03-23 14:54:21 +01:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 18:08:41 +03:00
										 |  |  |  | CSS::GridTrackSizeList StyleProperties::grid_auto_columns() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridAutoColumns); | 
					
						
							|  |  |  |  |     return value->as_grid_track_size_list().grid_track_size_list(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | CSS::GridTrackSizeList StyleProperties::grid_auto_rows() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridAutoRows); | 
					
						
							|  |  |  |  |     return value->as_grid_track_size_list().grid_track_size_list(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 13:27:57 +01:00
										 |  |  |  | CSS::GridTrackSizeList StyleProperties::grid_template_columns() const | 
					
						
							| 
									
										
										
										
											2022-08-23 19:49:07 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridTemplateColumns); | 
					
						
							| 
									
										
										
										
											2022-10-30 13:27:57 +01:00
										 |  |  |  |     return value->as_grid_track_size_list().grid_track_size_list(); | 
					
						
							| 
									
										
										
										
											2022-08-23 19:49:07 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 13:27:57 +01:00
										 |  |  |  | CSS::GridTrackSizeList StyleProperties::grid_template_rows() const | 
					
						
							| 
									
										
										
										
											2022-08-23 19:49:07 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridTemplateRows); | 
					
						
							| 
									
										
										
										
											2022-10-30 13:27:57 +01:00
										 |  |  |  |     return value->as_grid_track_size_list().grid_track_size_list(); | 
					
						
							| 
									
										
										
										
											2022-08-23 19:49:07 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-17 20:25:18 +02:00
										 |  |  |  | CSS::GridAutoFlow StyleProperties::grid_auto_flow() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridAutoFlow); | 
					
						
							|  |  |  |  |     if (!value->is_grid_auto_flow()) | 
					
						
							|  |  |  |  |         return CSS::GridAutoFlow {}; | 
					
						
							|  |  |  |  |     auto& grid_auto_flow_value = value->as_grid_auto_flow(); | 
					
						
							|  |  |  |  |     return CSS::GridAutoFlow { .row = grid_auto_flow_value.is_row(), .dense = grid_auto_flow_value.is_dense() }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 19:58:00 +02:00
										 |  |  |  | CSS::GridTrackPlacement StyleProperties::grid_column_end() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridColumnEnd); | 
					
						
							|  |  |  |  |     return value->as_grid_track_placement().grid_track_placement(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | CSS::GridTrackPlacement StyleProperties::grid_column_start() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridColumnStart); | 
					
						
							|  |  |  |  |     return value->as_grid_track_placement().grid_track_placement(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | CSS::GridTrackPlacement StyleProperties::grid_row_end() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridRowEnd); | 
					
						
							|  |  |  |  |     return value->as_grid_track_placement().grid_track_placement(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | CSS::GridTrackPlacement StyleProperties::grid_row_start() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridRowStart); | 
					
						
							|  |  |  |  |     return value->as_grid_track_placement().grid_track_placement(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-02 23:01:29 +01:00
										 |  |  |  | Optional<CSS::BorderCollapse> StyleProperties::border_collapse() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::BorderCollapse); | 
					
						
							|  |  |  |  |     return value_id_to_border_collapse(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-16 18:17:05 +01:00
										 |  |  |  | Vector<Vector<String>> StyleProperties::grid_template_areas() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::GridTemplateAreas); | 
					
						
							|  |  |  |  |     return value->as_grid_template_area().grid_template_area(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-01 20:06:50 +02:00
										 |  |  |  | Optional<CSS::ObjectFit> StyleProperties::object_fit() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ObjectFit); | 
					
						
							|  |  |  |  |     return value_id_to_object_fit(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 11:33:54 +01:00
										 |  |  |  | CSS::ObjectPosition StyleProperties::object_position() const | 
					
						
							| 
									
										
										
										
											2023-10-16 13:52:51 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ObjectPosition); | 
					
						
							| 
									
										
										
										
											2024-02-26 11:33:54 +01:00
										 |  |  |  |     auto const& position = value->as_position(); | 
					
						
							|  |  |  |  |     CSS::ObjectPosition object_position; | 
					
						
							|  |  |  |  |     auto const& edge_x = position.edge_x(); | 
					
						
							|  |  |  |  |     auto const& edge_y = position.edge_y(); | 
					
						
							|  |  |  |  |     if (edge_x->is_edge()) { | 
					
						
							|  |  |  |  |         auto const& edge = edge_x->as_edge(); | 
					
						
							|  |  |  |  |         object_position.edge_x = edge.edge(); | 
					
						
							|  |  |  |  |         object_position.offset_x = edge.offset(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     if (edge_y->is_edge()) { | 
					
						
							|  |  |  |  |         auto const& edge = edge_y->as_edge(); | 
					
						
							|  |  |  |  |         object_position.edge_y = edge.edge(); | 
					
						
							|  |  |  |  |         object_position.offset_y = edge.offset(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return object_position; | 
					
						
							| 
									
										
										
										
											2023-10-16 13:52:51 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 01:32:52 +00:00
										 |  |  |  | Optional<CSS::TableLayout> StyleProperties::table_layout() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::TableLayout); | 
					
						
							|  |  |  |  |     return value_id_to_table_layout(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-08 11:06:34 +01:00
										 |  |  |  | Optional<CSS::MaskType> StyleProperties::mask_type() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::MaskType); | 
					
						
							|  |  |  |  |     return value_id_to_mask_type(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-19 18:51:00 +01:00
										 |  |  |  | Color StyleProperties::stop_color() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::StopColor); | 
					
						
							| 
									
										
										
										
											2023-07-28 22:24:36 +01:00
										 |  |  |  |     if (value->is_identifier()) { | 
					
						
							|  |  |  |  |         // Workaround lack of layout node to resolve current color.
 | 
					
						
							|  |  |  |  |         auto& ident = value->as_identifier(); | 
					
						
							|  |  |  |  |         if (ident.id() == CSS::ValueID::Currentcolor) | 
					
						
							|  |  |  |  |             value = property(CSS::PropertyID::Color); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-19 18:51:00 +01:00
										 |  |  |  |     if (value->has_color()) { | 
					
						
							|  |  |  |  |         // FIXME: This is used by the SVGStopElement, which does not participate in layout,
 | 
					
						
							| 
									
										
										
										
											2023-07-28 22:24:36 +01:00
										 |  |  |  |         // so can't pass a layout node (so can't resolve some colors, e.g. palette ones)
 | 
					
						
							| 
									
										
										
										
											2023-04-19 18:51:00 +01:00
										 |  |  |  |         return value->to_color({}); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return Color::Black; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 15:29:54 +01:00
										 |  |  |  | void StyleProperties::set_math_depth(int math_depth) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     m_math_depth = math_depth; | 
					
						
							|  |  |  |  |     // Make our children inherit our computed value, not our specified value.
 | 
					
						
							|  |  |  |  |     set_property(PropertyID::MathDepth, MathDepthStyleValue::create_integer(IntegerStyleValue::create(math_depth))); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 11:34:26 +01:00
										 |  |  |  | QuotesData StyleProperties::quotes() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::Quotes); | 
					
						
							|  |  |  |  |     if (value->is_identifier()) { | 
					
						
							|  |  |  |  |         switch (value->to_identifier()) { | 
					
						
							|  |  |  |  |         case ValueID::Auto: | 
					
						
							|  |  |  |  |             return QuotesData { .type = QuotesData::Type::Auto }; | 
					
						
							|  |  |  |  |         case ValueID::None: | 
					
						
							|  |  |  |  |             return QuotesData { .type = QuotesData::Type::None }; | 
					
						
							|  |  |  |  |         default: | 
					
						
							|  |  |  |  |             break; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     if (value->is_value_list()) { | 
					
						
							|  |  |  |  |         auto& value_list = value->as_value_list(); | 
					
						
							|  |  |  |  |         QuotesData quotes_data { .type = QuotesData::Type::Specified }; | 
					
						
							|  |  |  |  |         VERIFY(value_list.size() % 2 == 0); | 
					
						
							|  |  |  |  |         for (auto i = 0u; i < value_list.size(); i += 2) { | 
					
						
							|  |  |  |  |             quotes_data.strings.empend( | 
					
						
							|  |  |  |  |                 value_list.value_at(i, false)->as_string().string_value(), | 
					
						
							|  |  |  |  |                 value_list.value_at(i + 1, false)->as_string().string_value()); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return quotes_data; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return InitialValues::quotes(); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-27 09:37:18 +01:00
										 |  |  |  | Optional<CSS::ScrollbarWidth> StyleProperties::scrollbar_width() const | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     auto value = property(CSS::PropertyID::ScrollbarWidth); | 
					
						
							|  |  |  |  |     return value_id_to_scrollbar_width(value->to_identifier()); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  |  | } |