2021-09-12 20:05:29 +02:00
/*
2023-02-20 18:56:08 +01:00
* Copyright ( c ) 2021 - 2023 , Andreas Kling < kling @ serenityos . org >
2021-09-13 19:54:54 +02:00
* Copyright ( c ) 2021 , Tobias Christiansen < tobyase @ serenityos . org >
2023-03-23 17:44:13 +00:00
* Copyright ( c ) 2022 - 2023 , Sam Atkins < atkinssj @ serenityos . org >
2021-09-12 20:05:29 +02:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2022-02-06 14:17:42 +01:00
# include <AK/Debug.h>
2022-12-06 03:08:20 -03:00
# include <AK/Format.h>
2021-09-14 00:38:46 +02:00
# include <AK/NonnullRefPtr.h>
2022-04-13 20:05:56 +01:00
# include <LibWeb/CSS/Enums.h>
2021-09-23 12:35:56 +02:00
# include <LibWeb/CSS/ResolvedCSSStyleDeclaration.h>
2021-09-24 13:49:57 +02:00
# include <LibWeb/CSS/StyleComputer.h>
2023-03-23 17:44:13 +00:00
# include <LibWeb/CSS/StyleValues/BackgroundRepeatStyleValue.h>
2023-03-23 17:35:44 +00:00
# include <LibWeb/CSS/StyleValues/BackgroundStyleValue.h>
2023-03-25 00:29:33 +00:00
# include <LibWeb/CSS/StyleValues/BorderRadiusShorthandStyleValue.h>
2023-03-25 00:33:20 +00:00
# include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h>
2023-03-23 20:56:30 +00:00
# include <LibWeb/CSS/StyleValues/BorderStyleValue.h>
2023-03-30 17:34:14 +01:00
# include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
2023-03-23 21:12:15 +00:00
# include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
2023-04-03 00:04:00 +01:00
# include <LibWeb/CSS/StyleValues/EdgeStyleValue.h>
2023-03-24 14:48:19 +00:00
# include <LibWeb/CSS/StyleValues/GridAreaShorthandStyleValue.h>
2023-03-24 14:50:50 +00:00
# include <LibWeb/CSS/StyleValues/GridTrackPlacementShorthandStyleValue.h>
2023-03-24 14:53:08 +00:00
# include <LibWeb/CSS/StyleValues/GridTrackPlacementStyleValue.h>
2023-04-29 19:32:56 +02:00
# include <LibWeb/CSS/StyleValues/GridTrackSizeListShorthandStyleValue.h>
2023-04-29 17:59:07 +02:00
# include <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h>
2023-03-24 15:04:24 +00:00
# include <LibWeb/CSS/StyleValues/IdentifierStyleValue.h>
2023-03-24 16:55:44 +00:00
# include <LibWeb/CSS/StyleValues/InitialStyleValue.h>
2023-03-24 17:04:04 +00:00
# include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
2023-03-24 17:16:07 +00:00
# include <LibWeb/CSS/StyleValues/NumericStyleValue.h>
2023-03-24 17:28:43 +00:00
# include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
2023-03-24 17:35:31 +00:00
# include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
2023-03-25 00:02:50 +00:00
# include <LibWeb/CSS/StyleValues/RectStyleValue.h>
2023-03-24 17:45:25 +00:00
# include <LibWeb/CSS/StyleValues/ShadowStyleValue.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-09-12 20:05:29 +02:00
# include <LibWeb/DOM/Document.h>
# include <LibWeb/DOM/Element.h>
2023-02-25 11:04:29 +01:00
# include <LibWeb/Layout/Viewport.h>
2022-07-19 16:44:24 +01:00
# include <LibWeb/Painting/PaintableBox.h>
# include <LibWeb/Painting/StackingContext.h>
2021-09-12 20:05:29 +02:00
namespace Web : : CSS {
2023-02-14 20:39:13 +01:00
WebIDL : : ExceptionOr < JS : : NonnullGCPtr < ResolvedCSSStyleDeclaration > > ResolvedCSSStyleDeclaration : : create ( DOM : : Element & element )
2022-08-07 16:21:26 +02:00
{
2023-02-14 20:39:13 +01:00
return MUST_OR_THROW_OOM ( element . realm ( ) . heap ( ) . allocate < ResolvedCSSStyleDeclaration > ( element . realm ( ) , element ) ) ;
2022-08-07 16:21:26 +02:00
}
2021-09-23 12:35:56 +02:00
ResolvedCSSStyleDeclaration : : ResolvedCSSStyleDeclaration ( DOM : : Element & element )
2022-09-24 16:34:04 -06:00
: CSSStyleDeclaration ( element . realm ( ) )
2022-08-07 16:21:26 +02:00
, m_element ( element )
2021-09-12 20:05:29 +02:00
{
}
2022-08-28 13:42:07 +02:00
void ResolvedCSSStyleDeclaration : : visit_edges ( Cell : : Visitor & visitor )
{
Base : : visit_edges ( visitor ) ;
visitor . visit ( m_element . ptr ( ) ) ;
}
2021-09-23 12:35:56 +02:00
size_t ResolvedCSSStyleDeclaration : : length ( ) const
2021-09-12 20:05:29 +02:00
{
return 0 ;
}
2022-12-04 18:02:33 +00:00
DeprecatedString ResolvedCSSStyleDeclaration : : item ( size_t index ) const
2021-09-12 20:05:29 +02:00
{
( void ) index ;
return { } ;
}
2023-05-02 14:52:31 +01:00
static ErrorOr < NonnullRefPtr < StyleValue const > > style_value_for_background_property ( Layout : : NodeWithStyle const & layout_node , Function < ErrorOr < NonnullRefPtr < StyleValue const > > ( BackgroundLayerData const & ) > callback , Function < ErrorOr < NonnullRefPtr < StyleValue const > > ( ) > default_value )
2023-03-30 23:26:28 +02:00
{
auto const & background_layers = layout_node . background_layers ( ) ;
if ( background_layers . is_empty ( ) )
return default_value ( ) ;
if ( background_layers . size ( ) = = 1 )
return callback ( background_layers . first ( ) ) ;
StyleValueVector values ;
2023-05-02 14:52:31 +01:00
TRY ( values . try_ensure_capacity ( background_layers . size ( ) ) ) ;
2023-03-30 23:26:28 +02:00
for ( auto const & layer : background_layers )
2023-05-02 14:52:31 +01:00
values . unchecked_append ( TRY ( callback ( layer ) ) ) ;
return StyleValueList : : create ( move ( values ) , StyleValueList : : Separator : : Comma ) ;
2023-03-30 23:26:28 +02:00
}
2023-05-27 15:52:49 +01:00
static ErrorOr < RefPtr < StyleValue > > style_value_for_display ( Display display )
2021-09-12 20:05:29 +02:00
{
2021-10-06 17:57:44 +02:00
if ( display . is_none ( ) )
2023-05-27 15:52:49 +01:00
return IdentifierStyleValue : : create ( ValueID : : None ) ;
2021-10-06 17:57:44 +02:00
2022-04-13 01:03:40 +02:00
if ( display . is_outside_and_inside ( ) ) {
2023-05-27 13:19:49 +02:00
// NOTE: Following the precedence rules of “most backwards-compatible, then shortest”,
// serialization of equivalent display values uses the “Short display” column.
2023-05-27 15:52:49 +01:00
if ( display = = Display : : from_short ( Display : : Short : : Block ) )
return IdentifierStyleValue : : create ( ValueID : : Block ) ;
if ( display = = Display : : from_short ( Display : : Short : : FlowRoot ) )
return IdentifierStyleValue : : create ( ValueID : : FlowRoot ) ;
if ( display = = Display : : from_short ( Display : : Short : : Inline ) )
return IdentifierStyleValue : : create ( ValueID : : Inline ) ;
if ( display = = Display : : from_short ( Display : : Short : : InlineBlock ) )
return IdentifierStyleValue : : create ( ValueID : : InlineBlock ) ;
if ( display = = Display : : from_short ( Display : : Short : : RunIn ) )
return IdentifierStyleValue : : create ( ValueID : : RunIn ) ;
if ( display = = Display : : from_short ( Display : : Short : : ListItem ) )
return IdentifierStyleValue : : create ( ValueID : : ListItem ) ;
if ( display = = Display : : from_short ( Display : : Short : : Flex ) )
return IdentifierStyleValue : : create ( ValueID : : Flex ) ;
if ( display = = Display : : from_short ( Display : : Short : : InlineFlex ) )
return IdentifierStyleValue : : create ( ValueID : : InlineFlex ) ;
if ( display = = Display : : from_short ( Display : : Short : : Grid ) )
return IdentifierStyleValue : : create ( ValueID : : Grid ) ;
if ( display = = Display : : from_short ( Display : : Short : : InlineGrid ) )
return IdentifierStyleValue : : create ( ValueID : : InlineGrid ) ;
if ( display = = Display : : from_short ( Display : : Short : : Ruby ) )
return IdentifierStyleValue : : create ( ValueID : : Ruby ) ;
if ( display = = Display : : from_short ( Display : : Short : : Table ) )
return IdentifierStyleValue : : create ( ValueID : : Table ) ;
if ( display = = Display : : from_short ( Display : : Short : : InlineTable ) )
return IdentifierStyleValue : : create ( ValueID : : InlineTable ) ;
2023-05-27 13:19:49 +02:00
2023-02-20 00:41:51 +00:00
StyleValueVector values ;
2021-10-06 17:57:44 +02:00
switch ( display . outside ( ) ) {
2023-05-27 15:52:49 +01:00
case Display : : Outside : : Inline :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Inline ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Outside : : Block :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Block ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Outside : : RunIn :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : RunIn ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
}
switch ( display . inside ( ) ) {
2023-05-27 15:52:49 +01:00
case Display : : Inside : : Flow :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Flow ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Inside : : FlowRoot :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : FlowRoot ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Inside : : Table :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Table ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Inside : : Flex :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Flex ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Inside : : Grid :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Grid ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
2023-05-27 15:52:49 +01:00
case Display : : Inside : : Ruby :
TRY ( values . try_append ( TRY ( IdentifierStyleValue : : create ( ValueID : : Ruby ) ) ) ) ;
2021-10-06 17:57:44 +02:00
break ;
}
2023-05-02 14:52:31 +01:00
return StyleValueList : : create ( move ( values ) , StyleValueList : : Separator : : Space ) ;
2021-09-12 20:05:29 +02:00
}
2021-10-06 17:57:44 +02:00
if ( display . is_internal ( ) ) {
switch ( display . internal ( ) ) {
2023-05-27 15:52:49 +01:00
case Display : : Internal : : TableRowGroup :
return IdentifierStyleValue : : create ( ValueID : : TableRowGroup ) ;
case Display : : Internal : : TableHeaderGroup :
return IdentifierStyleValue : : create ( ValueID : : TableHeaderGroup ) ;
case Display : : Internal : : TableFooterGroup :
return IdentifierStyleValue : : create ( ValueID : : TableFooterGroup ) ;
case Display : : Internal : : TableRow :
return IdentifierStyleValue : : create ( ValueID : : TableRow ) ;
case Display : : Internal : : TableCell :
return IdentifierStyleValue : : create ( ValueID : : TableCell ) ;
case Display : : Internal : : TableColumnGroup :
return IdentifierStyleValue : : create ( ValueID : : TableColumnGroup ) ;
case Display : : Internal : : TableColumn :
return IdentifierStyleValue : : create ( ValueID : : TableColumn ) ;
case Display : : Internal : : TableCaption :
return IdentifierStyleValue : : create ( ValueID : : TableCaption ) ;
case Display : : Internal : : RubyBase :
return IdentifierStyleValue : : create ( ValueID : : RubyBase ) ;
case Display : : Internal : : RubyText :
return IdentifierStyleValue : : create ( ValueID : : RubyText ) ;
case Display : : Internal : : RubyBaseContainer :
return IdentifierStyleValue : : create ( ValueID : : RubyBaseContainer ) ;
case Display : : Internal : : RubyTextContainer :
return IdentifierStyleValue : : create ( ValueID : : RubyTextContainer ) ;
2021-10-06 17:57:44 +02:00
}
}
TODO ( ) ;
2021-09-12 20:05:29 +02:00
}
2023-02-20 18:56:08 +01:00
static NonnullRefPtr < StyleValue const > value_or_default ( Optional < StyleProperty > property , NonnullRefPtr < StyleValue > default_style )
2021-09-14 00:38:46 +02:00
{
if ( property . has_value ( ) )
return property . value ( ) . value ;
return default_style ;
}
2023-05-02 14:52:31 +01:00
static ErrorOr < NonnullRefPtr < StyleValue const > > style_value_for_length_percentage ( LengthPercentage const & length_percentage )
2022-01-19 11:52:01 +00:00
{
2023-04-19 11:20:50 +01:00
if ( length_percentage . is_auto ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : Auto ) ;
2022-01-19 11:52:01 +00:00
if ( length_percentage . is_percentage ( ) )
2023-05-02 14:52:31 +01:00
return PercentageStyleValue : : create ( length_percentage . percentage ( ) ) ;
2022-04-03 22:05:03 +02:00
if ( length_percentage . is_length ( ) )
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( length_percentage . length ( ) ) ;
2022-04-03 22:05:03 +02:00
return length_percentage . calculated ( ) ;
2022-01-19 11:52:01 +00:00
}
2023-05-27 15:52:49 +01:00
static ErrorOr < NonnullRefPtr < StyleValue const > > style_value_for_size ( Size const & size )
2022-09-25 15:48:23 +02:00
{
if ( size . is_none ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : None ) ;
2022-09-25 15:48:23 +02:00
if ( size . is_percentage ( ) )
2023-05-02 14:52:31 +01:00
return PercentageStyleValue : : create ( size . percentage ( ) ) ;
2022-09-25 15:48:23 +02:00
if ( size . is_length ( ) )
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( size . length ( ) ) ;
2022-09-25 15:48:23 +02:00
if ( size . is_auto ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : Auto ) ;
2023-03-30 10:50:40 +01:00
if ( size . is_calculated ( ) )
return size . calculated ( ) ;
2022-09-25 15:48:23 +02:00
if ( size . is_min_content ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : MinContent ) ;
2022-09-25 15:48:23 +02:00
if ( size . is_max_content ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : MaxContent ) ;
2022-09-25 15:48:23 +02:00
// FIXME: Support fit-content(<length>)
TODO ( ) ;
}
2023-05-02 14:52:31 +01:00
ErrorOr < RefPtr < StyleValue const > > ResolvedCSSStyleDeclaration : : style_value_for_property ( Layout : : NodeWithStyle const & layout_node , PropertyID property_id ) const
2021-09-12 20:05:29 +02:00
{
switch ( property_id ) {
2023-05-27 13:16:18 +01:00
case PropertyID : : AccentColor : {
auto accent_color = layout_node . computed_values ( ) . accent_color ( ) ;
if ( accent_color . has_value ( ) )
return TRY ( ColorStyleValue : : create ( accent_color . value ( ) ) ) ;
return TRY ( IdentifierStyleValue : : create ( ValueID : : Auto ) ) ;
}
2023-05-27 13:20:50 +01:00
case PropertyID : : AlignContent :
return TRY ( IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . align_content ( ) ) ) ) ;
case PropertyID : : AlignItems :
return TRY ( IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . align_items ( ) ) ) ) ;
case PropertyID : : AlignSelf :
return TRY ( IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . align_self ( ) ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Background : {
auto maybe_background_color = property ( PropertyID : : BackgroundColor ) ;
auto maybe_background_image = property ( PropertyID : : BackgroundImage ) ;
auto maybe_background_position = property ( PropertyID : : BackgroundPosition ) ;
auto maybe_background_size = property ( PropertyID : : BackgroundSize ) ;
auto maybe_background_repeat = property ( PropertyID : : BackgroundRepeat ) ;
auto maybe_background_attachment = property ( PropertyID : : BackgroundAttachment ) ;
auto maybe_background_origin = property ( PropertyID : : BackgroundOrigin ) ;
auto maybe_background_clip = property ( PropertyID : : BackgroundClip ) ;
2022-07-14 17:04:03 +01:00
return BackgroundStyleValue : : create (
2023-05-02 14:52:31 +01:00
value_or_default ( maybe_background_color , TRY ( InitialStyleValue : : the ( ) ) ) ,
2023-05-27 15:52:49 +01:00
value_or_default ( maybe_background_image , TRY ( IdentifierStyleValue : : create ( ValueID : : None ) ) ) ,
2023-05-02 14:52:31 +01:00
value_or_default ( maybe_background_position , TRY ( PositionStyleValue : : create ( TRY ( EdgeStyleValue : : create ( PositionEdge : : Left , Length : : make_px ( 0 ) ) ) , TRY ( EdgeStyleValue : : create ( PositionEdge : : Top , Length : : make_px ( 0 ) ) ) ) ) ) ,
2023-05-27 15:52:49 +01:00
value_or_default ( maybe_background_size , TRY ( IdentifierStyleValue : : create ( ValueID : : Auto ) ) ) ,
value_or_default ( maybe_background_repeat , TRY ( BackgroundRepeatStyleValue : : create ( Repeat : : Repeat , Repeat : : Repeat ) ) ) ,
value_or_default ( maybe_background_attachment , TRY ( IdentifierStyleValue : : create ( ValueID : : Scroll ) ) ) ,
value_or_default ( maybe_background_origin , TRY ( IdentifierStyleValue : : create ( ValueID : : PaddingBox ) ) ) ,
value_or_default ( maybe_background_clip , TRY ( IdentifierStyleValue : : create ( ValueID : : BorderBox ) ) ) ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BackgroundAttachment :
2023-03-30 23:26:28 +02:00
return style_value_for_background_property (
layout_node ,
2023-05-02 14:52:31 +01:00
[ ] ( auto & layer ) { return IdentifierStyleValue : : create ( to_value_id ( layer . attachment ) ) ; } ,
2023-05-27 15:52:49 +01:00
[ ] { return IdentifierStyleValue : : create ( ValueID : : Scroll ) ; } ) ;
case PropertyID : : BackgroundClip :
2023-03-30 23:26:28 +02:00
return style_value_for_background_property (
layout_node ,
2023-05-02 14:52:31 +01:00
[ ] ( auto & layer ) { return IdentifierStyleValue : : create ( to_value_id ( layer . clip ) ) ; } ,
2023-05-27 15:52:49 +01:00
[ ] { return IdentifierStyleValue : : create ( ValueID : : BorderBox ) ; } ) ;
2022-07-14 17:04:03 +01:00
case PropertyID : : BackgroundColor :
2023-05-02 14:52:31 +01:00
return ColorStyleValue : : create ( layout_node . computed_values ( ) . background_color ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BackgroundImage :
2023-03-30 23:26:28 +02:00
return style_value_for_background_property (
layout_node ,
2023-05-02 14:52:31 +01:00
[ ] ( auto & layer ) - > ErrorOr < NonnullRefPtr < StyleValue const > > {
2023-03-30 23:26:28 +02:00
if ( layer . background_image )
return * layer . background_image ;
2023-05-27 15:52:49 +01:00
return IdentifierStyleValue : : create ( ValueID : : None ) ;
2023-03-30 23:26:28 +02:00
} ,
2023-05-27 15:52:49 +01:00
[ ] { return IdentifierStyleValue : : create ( ValueID : : None ) ; } ) ;
case PropertyID : : BackgroundOrigin :
2023-03-30 23:26:28 +02:00
return style_value_for_background_property (
layout_node ,
2023-05-02 14:52:31 +01:00
[ ] ( auto & layer ) { return IdentifierStyleValue : : create ( to_value_id ( layer . origin ) ) ; } ,
2023-05-27 15:52:49 +01:00
[ ] { return IdentifierStyleValue : : create ( ValueID : : PaddingBox ) ; } ) ;
case PropertyID : : BackgroundRepeat :
2023-03-30 23:26:28 +02:00
return style_value_for_background_property (
layout_node ,
2023-05-02 14:52:31 +01:00
[ ] ( auto & layer ) - > ErrorOr < NonnullRefPtr < StyleValue const > > {
2023-03-30 23:26:28 +02:00
StyleValueVector repeat {
2023-05-02 14:52:31 +01:00
TRY ( IdentifierStyleValue : : create ( to_value_id ( layer . repeat_x ) ) ) ,
TRY ( IdentifierStyleValue : : create ( to_value_id ( layer . repeat_y ) ) ) ,
2023-03-30 23:26:28 +02:00
} ;
2023-05-02 14:52:31 +01:00
return StyleValueList : : create ( move ( repeat ) , StyleValueList : : Separator : : Space ) ;
2023-03-30 23:26:28 +02:00
} ,
2023-05-27 15:52:49 +01:00
[ ] { return BackgroundRepeatStyleValue : : create ( Repeat : : Repeat , Repeat : : Repeat ) ; } ) ;
case PropertyID : : BorderBottom : {
2022-07-14 17:04:03 +01:00
auto border = layout_node . computed_values ( ) . border_bottom ( ) ;
2023-05-02 14:52:31 +01:00
auto width = TRY ( LengthStyleValue : : create ( Length : : make_px ( border . width ) ) ) ;
auto style = TRY ( IdentifierStyleValue : : create ( to_value_id ( border . line_style ) ) ) ;
auto color = TRY ( ColorStyleValue : : create ( border . color ) ) ;
return BorderStyleValue : : create ( width , style , color ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderBottomColor :
2023-05-02 14:52:31 +01:00
return ColorStyleValue : : create ( layout_node . computed_values ( ) . border_bottom ( ) . color ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderBottomLeftRadius : {
2022-07-14 17:04:03 +01:00
auto const & border_radius = layout_node . computed_values ( ) . border_bottom_left_radius ( ) ;
2023-05-02 14:52:31 +01:00
return BorderRadiusStyleValue : : create ( border_radius . horizontal_radius , border_radius . vertical_radius ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderBottomRightRadius : {
2022-07-14 17:04:03 +01:00
auto const & border_radius = layout_node . computed_values ( ) . border_bottom_right_radius ( ) ;
2023-05-02 14:52:31 +01:00
return BorderRadiusStyleValue : : create ( border_radius . horizontal_radius , border_radius . vertical_radius ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderBottomStyle :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . border_bottom ( ) . line_style ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderBottomWidth :
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( Length : : make_px ( layout_node . computed_values ( ) . border_bottom ( ) . width ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderCollapse :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . border_collapse ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderLeft : {
2022-07-14 17:04:03 +01:00
auto border = layout_node . computed_values ( ) . border_left ( ) ;
2023-05-02 14:52:31 +01:00
auto width = TRY ( LengthStyleValue : : create ( Length : : make_px ( border . width ) ) ) ;
auto style = TRY ( IdentifierStyleValue : : create ( to_value_id ( border . line_style ) ) ) ;
auto color = TRY ( ColorStyleValue : : create ( border . color ) ) ;
return BorderStyleValue : : create ( width , style , color ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderLeftColor :
2023-05-02 14:52:31 +01:00
return ColorStyleValue : : create ( layout_node . computed_values ( ) . border_left ( ) . color ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderLeftStyle :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . border_left ( ) . line_style ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderLeftWidth :
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( Length : : make_px ( layout_node . computed_values ( ) . border_left ( ) . width ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderRadius : {
auto maybe_top_left_radius = property ( PropertyID : : BorderTopLeftRadius ) ;
auto maybe_top_right_radius = property ( PropertyID : : BorderTopRightRadius ) ;
auto maybe_bottom_left_radius = property ( PropertyID : : BorderBottomLeftRadius ) ;
auto maybe_bottom_right_radius = property ( PropertyID : : BorderBottomRightRadius ) ;
2023-02-20 18:56:08 +01:00
RefPtr < BorderRadiusStyleValue const > top_left_radius , top_right_radius , bottom_left_radius , bottom_right_radius ;
2022-07-14 17:04:03 +01:00
if ( maybe_top_left_radius . has_value ( ) ) {
VERIFY ( maybe_top_left_radius . value ( ) . value - > is_border_radius ( ) ) ;
top_left_radius = maybe_top_left_radius . value ( ) . value - > as_border_radius ( ) ;
}
if ( maybe_top_right_radius . has_value ( ) ) {
VERIFY ( maybe_top_right_radius . value ( ) . value - > is_border_radius ( ) ) ;
top_right_radius = maybe_top_right_radius . value ( ) . value - > as_border_radius ( ) ;
}
if ( maybe_bottom_left_radius . has_value ( ) ) {
VERIFY ( maybe_bottom_left_radius . value ( ) . value - > is_border_radius ( ) ) ;
bottom_left_radius = maybe_bottom_left_radius . value ( ) . value - > as_border_radius ( ) ;
}
if ( maybe_bottom_right_radius . has_value ( ) ) {
VERIFY ( maybe_bottom_right_radius . value ( ) . value - > is_border_radius ( ) ) ;
bottom_right_radius = maybe_bottom_right_radius . value ( ) . value - > as_border_radius ( ) ;
}
2023-05-02 14:52:31 +01:00
return BorderRadiusShorthandStyleValue : : create ( top_left_radius . release_nonnull ( ) , top_right_radius . release_nonnull ( ) , bottom_right_radius . release_nonnull ( ) , bottom_left_radius . release_nonnull ( ) ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderRight : {
2022-07-14 17:04:03 +01:00
auto border = layout_node . computed_values ( ) . border_right ( ) ;
2023-05-02 14:52:31 +01:00
auto width = TRY ( LengthStyleValue : : create ( Length : : make_px ( border . width ) ) ) ;
auto style = TRY ( IdentifierStyleValue : : create ( to_value_id ( border . line_style ) ) ) ;
auto color = TRY ( ColorStyleValue : : create ( border . color ) ) ;
return BorderStyleValue : : create ( width , style , color ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderRightColor :
2023-05-02 14:52:31 +01:00
return ColorStyleValue : : create ( layout_node . computed_values ( ) . border_right ( ) . color ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderRightStyle :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . border_right ( ) . line_style ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderRightWidth :
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( Length : : make_px ( layout_node . computed_values ( ) . border_right ( ) . width ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderTop : {
2022-07-14 17:04:03 +01:00
auto border = layout_node . computed_values ( ) . border_top ( ) ;
2023-05-02 14:52:31 +01:00
auto width = TRY ( LengthStyleValue : : create ( Length : : make_px ( border . width ) ) ) ;
auto style = TRY ( IdentifierStyleValue : : create ( to_value_id ( border . line_style ) ) ) ;
auto color = TRY ( ColorStyleValue : : create ( border . color ) ) ;
return BorderStyleValue : : create ( width , style , color ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderTopColor :
2023-05-02 14:52:31 +01:00
return ColorStyleValue : : create ( layout_node . computed_values ( ) . border_top ( ) . color ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderTopLeftRadius : {
2022-07-14 17:04:03 +01:00
auto const & border_radius = layout_node . computed_values ( ) . border_top_left_radius ( ) ;
2023-05-02 14:52:31 +01:00
return BorderRadiusStyleValue : : create ( border_radius . horizontal_radius , border_radius . vertical_radius ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderTopRightRadius : {
2022-07-14 17:04:03 +01:00
auto const & border_radius = layout_node . computed_values ( ) . border_top_right_radius ( ) ;
2023-05-02 14:52:31 +01:00
return BorderRadiusStyleValue : : create ( border_radius . horizontal_radius , border_radius . vertical_radius ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderTopStyle :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . border_top ( ) . line_style ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BorderTopWidth :
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( Length : : make_px ( layout_node . computed_values ( ) . border_top ( ) . width ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : BoxShadow : {
2022-07-14 17:04:03 +01:00
auto box_shadow_layers = layout_node . computed_values ( ) . box_shadow ( ) ;
if ( box_shadow_layers . is_empty ( ) )
2023-05-02 14:52:31 +01:00
return nullptr ;
2022-07-14 17:04:03 +01:00
auto make_box_shadow_style_value = [ ] ( ShadowData const & data ) {
return ShadowStyleValue : : create ( data . color , data . offset_x , data . offset_y , data . blur_radius , data . spread_distance , data . placement ) ;
} ;
if ( box_shadow_layers . size ( ) = = 1 )
2023-05-02 14:52:31 +01:00
return make_box_shadow_style_value ( box_shadow_layers . first ( ) ) ;
2022-07-14 17:04:03 +01:00
2023-02-20 00:41:51 +00:00
StyleValueVector box_shadow ;
2023-05-02 14:52:31 +01:00
TRY ( box_shadow . try_ensure_capacity ( box_shadow_layers . size ( ) ) ) ;
2022-07-14 17:04:03 +01:00
for ( auto const & layer : box_shadow_layers )
2023-05-02 14:52:31 +01:00
box_shadow . unchecked_append ( TRY ( make_box_shadow_style_value ( layer ) ) ) ;
return StyleValueList : : create ( move ( box_shadow ) , StyleValueList : : Separator : : Comma ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : BoxSizing :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . box_sizing ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Bottom :
2022-11-14 21:18:52 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . inset ( ) . bottom ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Clear :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . clear ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Clip :
2023-05-02 14:52:31 +01:00
return RectStyleValue : : create ( layout_node . computed_values ( ) . clip ( ) . to_rect ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Color :
2023-05-02 14:52:31 +01:00
return ColorStyleValue : : create ( layout_node . computed_values ( ) . color ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : ColumnGap :
2022-11-06 12:42:22 +01:00
return style_value_for_size ( layout_node . computed_values ( ) . column_gap ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Cursor :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . cursor ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Display :
2022-10-06 16:02:53 +02:00
return style_value_for_display ( layout_node . display ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FlexBasis : {
2021-09-13 19:54:54 +02:00
switch ( layout_node . computed_values ( ) . flex_basis ( ) . type ) {
case FlexBasis : : Content :
2023-05-27 15:52:49 +01:00
return IdentifierStyleValue : : create ( ValueID : : Content ) ;
2022-01-19 11:52:01 +00:00
case FlexBasis : : LengthPercentage :
return style_value_for_length_percentage ( * layout_node . computed_values ( ) . flex_basis ( ) . length_percentage ) ;
2021-09-13 19:54:54 +02:00
case FlexBasis : : Auto :
2023-05-27 15:52:49 +01:00
return IdentifierStyleValue : : create ( ValueID : : Auto ) ;
2021-09-18 13:14:40 +02:00
default :
VERIFY_NOT_REACHED ( ) ;
2021-09-13 19:54:54 +02:00
}
2021-09-18 13:14:40 +02:00
break ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FlexDirection :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . flex_direction ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FlexGrow :
2023-05-02 14:52:31 +01:00
return NumericStyleValue : : create_float ( layout_node . computed_values ( ) . flex_grow ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FlexShrink :
2023-05-02 14:52:31 +01:00
return NumericStyleValue : : create_float ( layout_node . computed_values ( ) . flex_shrink ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FlexWrap :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . flex_wrap ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Float :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . float_ ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FontSize :
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( Length : : make_px ( layout_node . computed_values ( ) . font_size ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : FontVariant : {
2023-04-26 15:51:25 +01:00
auto font_variant = layout_node . computed_values ( ) . font_variant ( ) ;
switch ( font_variant ) {
case FontVariant : : Normal :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : Normal ) ;
2023-04-26 15:51:25 +01:00
case FontVariant : : SmallCaps :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : SmallCaps ) ;
2023-04-26 15:51:25 +01:00
}
VERIFY_NOT_REACHED ( ) ;
}
2023-05-27 15:52:49 +01:00
case PropertyID : : FontWeight :
2023-05-02 14:52:31 +01:00
return NumericStyleValue : : create_integer ( layout_node . computed_values ( ) . font_weight ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridArea : {
auto maybe_grid_row_start = property ( PropertyID : : GridRowStart ) ;
auto maybe_grid_column_start = property ( PropertyID : : GridColumnStart ) ;
auto maybe_grid_row_end = property ( PropertyID : : GridRowEnd ) ;
auto maybe_grid_column_end = property ( PropertyID : : GridColumnEnd ) ;
2023-02-20 18:56:08 +01:00
RefPtr < GridTrackPlacementStyleValue const > grid_row_start , grid_column_start , grid_row_end , grid_column_end ;
2023-01-16 19:02:39 +01:00
if ( maybe_grid_row_start . has_value ( ) ) {
VERIFY ( maybe_grid_row_start . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_row_start = maybe_grid_row_start . value ( ) . value - > as_grid_track_placement ( ) ;
}
if ( maybe_grid_column_start . has_value ( ) ) {
VERIFY ( maybe_grid_column_start . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_column_start = maybe_grid_column_start . value ( ) . value - > as_grid_track_placement ( ) ;
}
if ( maybe_grid_row_end . has_value ( ) ) {
VERIFY ( maybe_grid_row_end . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_row_end = maybe_grid_row_end . value ( ) . value - > as_grid_track_placement ( ) ;
}
if ( maybe_grid_column_end . has_value ( ) ) {
VERIFY ( maybe_grid_column_end . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_column_end = maybe_grid_column_end . value ( ) . value - > as_grid_track_placement ( ) ;
}
return GridAreaShorthandStyleValue : : create (
grid_row_start . release_nonnull ( ) ,
grid_column_start . release_nonnull ( ) ,
grid_row_end . release_nonnull ( ) ,
2023-05-02 14:52:31 +01:00
grid_column_end . release_nonnull ( ) ) ;
2023-01-16 19:02:39 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : GridColumn : {
auto maybe_grid_column_end = property ( PropertyID : : GridColumnEnd ) ;
auto maybe_grid_column_start = property ( PropertyID : : GridColumnStart ) ;
2023-02-20 18:56:08 +01:00
RefPtr < GridTrackPlacementStyleValue const > grid_column_start , grid_column_end ;
2022-08-23 20:00:16 +02:00
if ( maybe_grid_column_end . has_value ( ) ) {
VERIFY ( maybe_grid_column_end . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_column_end = maybe_grid_column_end . value ( ) . value - > as_grid_track_placement ( ) ;
}
if ( maybe_grid_column_start . has_value ( ) ) {
VERIFY ( maybe_grid_column_start . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_column_start = maybe_grid_column_start . value ( ) . value - > as_grid_track_placement ( ) ;
}
2023-05-02 14:52:31 +01:00
return GridTrackPlacementShorthandStyleValue : : create ( grid_column_end . release_nonnull ( ) , grid_column_start . release_nonnull ( ) ) ;
2022-08-23 20:00:16 +02:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : GridColumnEnd :
2023-05-02 14:52:31 +01:00
return GridTrackPlacementStyleValue : : create ( layout_node . computed_values ( ) . grid_column_end ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridColumnStart :
2023-05-02 14:52:31 +01:00
return GridTrackPlacementStyleValue : : create ( layout_node . computed_values ( ) . grid_column_start ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridRow : {
auto maybe_grid_row_end = property ( PropertyID : : GridRowEnd ) ;
auto maybe_grid_row_start = property ( PropertyID : : GridRowStart ) ;
2023-02-20 18:56:08 +01:00
RefPtr < GridTrackPlacementStyleValue const > grid_row_start , grid_row_end ;
2022-08-23 20:00:16 +02:00
if ( maybe_grid_row_end . has_value ( ) ) {
VERIFY ( maybe_grid_row_end . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_row_end = maybe_grid_row_end . value ( ) . value - > as_grid_track_placement ( ) ;
}
if ( maybe_grid_row_start . has_value ( ) ) {
VERIFY ( maybe_grid_row_start . value ( ) . value - > is_grid_track_placement ( ) ) ;
grid_row_start = maybe_grid_row_start . value ( ) . value - > as_grid_track_placement ( ) ;
}
2023-05-02 14:52:31 +01:00
return GridTrackPlacementShorthandStyleValue : : create ( grid_row_end . release_nonnull ( ) , grid_row_start . release_nonnull ( ) ) ;
2022-08-23 20:00:16 +02:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : GridRowEnd :
2023-05-02 14:52:31 +01:00
return GridTrackPlacementStyleValue : : create ( layout_node . computed_values ( ) . grid_row_end ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridRowStart :
2023-05-02 14:52:31 +01:00
return GridTrackPlacementStyleValue : : create ( layout_node . computed_values ( ) . grid_row_start ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridTemplate : {
auto maybe_grid_template_areas = property ( PropertyID : : GridTemplateAreas ) ;
auto maybe_grid_template_rows = property ( PropertyID : : GridTemplateRows ) ;
auto maybe_grid_template_columns = property ( PropertyID : : GridTemplateColumns ) ;
2023-04-29 19:32:56 +02:00
RefPtr < GridTemplateAreaStyleValue const > grid_template_areas ;
RefPtr < GridTrackSizeListStyleValue const > grid_template_rows , grid_template_columns ;
if ( maybe_grid_template_areas . has_value ( ) ) {
VERIFY ( maybe_grid_template_areas . value ( ) . value - > is_grid_template_area ( ) ) ;
grid_template_areas = maybe_grid_template_areas . value ( ) . value - > as_grid_template_area ( ) ;
}
if ( maybe_grid_template_rows . has_value ( ) ) {
VERIFY ( maybe_grid_template_rows . value ( ) . value - > is_grid_track_size_list ( ) ) ;
grid_template_rows = maybe_grid_template_rows . value ( ) . value - > as_grid_track_size_list ( ) ;
}
if ( maybe_grid_template_columns . has_value ( ) ) {
VERIFY ( maybe_grid_template_columns . value ( ) . value - > is_grid_track_size_list ( ) ) ;
grid_template_columns = maybe_grid_template_columns . value ( ) . value - > as_grid_track_size_list ( ) ;
}
2023-05-02 14:52:31 +01:00
return GridTrackSizeListShorthandStyleValue : : create ( grid_template_areas . release_nonnull ( ) , grid_template_rows . release_nonnull ( ) , grid_template_columns . release_nonnull ( ) ) ;
2023-04-29 19:32:56 +02:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : GridTemplateColumns :
2023-05-02 14:52:31 +01:00
return GridTrackSizeListStyleValue : : create ( layout_node . computed_values ( ) . grid_template_columns ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridTemplateRows :
2023-05-02 14:52:31 +01:00
return GridTrackSizeListStyleValue : : create ( layout_node . computed_values ( ) . grid_template_rows ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : GridTemplateAreas :
2023-05-02 14:52:31 +01:00
return GridTemplateAreaStyleValue : : create ( layout_node . computed_values ( ) . grid_template_areas ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Height :
2022-09-25 15:48:23 +02:00
return style_value_for_size ( layout_node . computed_values ( ) . height ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : ImageRendering :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . image_rendering ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : JustifyContent :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . justify_content ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Left :
2022-11-14 21:18:52 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . inset ( ) . left ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : LineHeight :
2023-05-02 14:52:31 +01:00
return LengthStyleValue : : create ( Length : : make_px ( layout_node . line_height ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : ListStyleType :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . list_style_type ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Margin : {
2021-10-05 17:11:38 +01:00
auto margin = layout_node . computed_values ( ) . margin ( ) ;
2023-02-20 00:41:51 +00:00
auto values = StyleValueVector { } ;
2023-05-02 14:52:31 +01:00
TRY ( values . try_ensure_capacity ( 4 ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( margin . top ( ) ) ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( margin . right ( ) ) ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( margin . bottom ( ) ) ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( margin . left ( ) ) ) ) ;
return StyleValueList : : create ( move ( values ) , StyleValueList : : Separator : : Space ) ;
2021-10-05 17:11:38 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : MarginBottom :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . margin ( ) . bottom ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MarginLeft :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . margin ( ) . left ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MarginRight :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . margin ( ) . right ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MarginTop :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . margin ( ) . top ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MaxHeight :
2022-09-25 15:48:23 +02:00
return style_value_for_size ( layout_node . computed_values ( ) . max_height ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MaxWidth :
2022-09-25 15:48:23 +02:00
return style_value_for_size ( layout_node . computed_values ( ) . max_width ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MinHeight :
2022-09-25 15:48:23 +02:00
return style_value_for_size ( layout_node . computed_values ( ) . min_height ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : MinWidth :
2022-09-25 15:48:23 +02:00
return style_value_for_size ( layout_node . computed_values ( ) . min_width ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Opacity :
2023-05-02 14:52:31 +01:00
return NumericStyleValue : : create_float ( layout_node . computed_values ( ) . opacity ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Order :
2023-05-02 14:52:31 +01:00
return NumericStyleValue : : create_integer ( layout_node . computed_values ( ) . order ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : OverflowX :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . overflow_x ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : OverflowY :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . overflow_y ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Padding : {
2021-10-05 17:11:38 +01:00
auto padding = layout_node . computed_values ( ) . padding ( ) ;
2023-02-20 00:41:51 +00:00
auto values = StyleValueVector { } ;
2023-05-02 14:52:31 +01:00
TRY ( values . try_ensure_capacity ( 4 ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( padding . top ( ) ) ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( padding . right ( ) ) ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( padding . bottom ( ) ) ) ) ;
values . unchecked_append ( TRY ( style_value_for_length_percentage ( padding . left ( ) ) ) ) ;
return StyleValueList : : create ( move ( values ) , StyleValueList : : Separator : : Space ) ;
2021-10-05 17:11:38 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : PaddingBottom :
2023-03-27 13:13:21 +01:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . padding ( ) . bottom ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : PaddingLeft :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . padding ( ) . left ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : PaddingRight :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . padding ( ) . right ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : PaddingTop :
2022-09-13 17:42:39 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . padding ( ) . top ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Position :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . position ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Right :
2022-11-14 21:18:52 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . inset ( ) . right ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : RowGap :
2022-11-06 12:42:22 +01:00
return style_value_for_size ( layout_node . computed_values ( ) . row_gap ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : TextAlign :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . text_align ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : TextDecorationLine : {
2022-07-14 17:04:03 +01:00
auto text_decoration_lines = layout_node . computed_values ( ) . text_decoration_line ( ) ;
if ( text_decoration_lines . is_empty ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : None ) ;
2023-02-20 00:41:51 +00:00
StyleValueVector style_values ;
2023-05-02 14:52:31 +01:00
TRY ( style_values . try_ensure_capacity ( text_decoration_lines . size ( ) ) ) ;
2022-07-14 17:04:03 +01:00
for ( auto const & line : text_decoration_lines ) {
2023-05-02 14:52:31 +01:00
style_values . unchecked_append ( TRY ( IdentifierStyleValue : : create ( to_value_id ( line ) ) ) ) ;
2021-09-14 00:38:46 +02:00
}
2023-05-02 14:52:31 +01:00
return StyleValueList : : create ( move ( style_values ) , StyleValueList : : Separator : : Space ) ;
2021-09-14 00:38:46 +02:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : TextDecorationStyle :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . text_decoration_style ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : TextTransform :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . text_transform ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Top :
2022-11-14 21:18:52 +02:00
return style_value_for_length_percentage ( layout_node . computed_values ( ) . inset ( ) . top ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Transform : {
2022-07-19 16:44:24 +01:00
// NOTE: The computed value for `transform` serializes as a single `matrix(...)` value, instead of
// the original list of transform functions. So, we produce a StyleValue for that.
// https://www.w3.org/TR/css-transforms-1/#serialization-of-the-computed-value
auto transformations = layout_node . computed_values ( ) . transformations ( ) ;
if ( transformations . is_empty ( ) )
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( ValueID : : None ) ;
2022-07-19 16:44:24 +01:00
// The transform matrix is held by the StackingContext, so we need to make sure we have one first.
2023-02-25 11:04:29 +01:00
auto const * viewport = layout_node . document ( ) . layout_node ( ) ;
VERIFY ( viewport ) ;
const_cast < Layout : : Viewport & > ( * viewport ) . build_stacking_context_tree_if_needed ( ) ;
2022-07-19 16:44:24 +01:00
VERIFY ( layout_node . paintable ( ) ) ;
auto const & paintable_box = verify_cast < Painting : : PaintableBox const > ( layout_node . paintable ( ) ) ;
VERIFY ( paintable_box - > stacking_context ( ) ) ;
2022-10-01 01:57:54 +01:00
// FIXME: This needs to serialize to matrix3d if the transformation matrix is a 3D matrix.
// https://w3c.github.io/csswg-drafts/css-transforms-2/#serialization-of-the-computed-value
2022-07-19 16:44:24 +01:00
auto affine_matrix = paintable_box - > stacking_context ( ) - > affine_transform_matrix ( ) ;
2023-02-20 00:41:51 +00:00
StyleValueVector parameters ;
2023-05-02 14:52:31 +01:00
TRY ( parameters . try_ensure_capacity ( 6 ) ) ;
parameters . unchecked_append ( TRY ( NumericStyleValue : : create_float ( affine_matrix . a ( ) ) ) ) ;
parameters . unchecked_append ( TRY ( NumericStyleValue : : create_float ( affine_matrix . b ( ) ) ) ) ;
parameters . unchecked_append ( TRY ( NumericStyleValue : : create_float ( affine_matrix . c ( ) ) ) ) ;
parameters . unchecked_append ( TRY ( NumericStyleValue : : create_float ( affine_matrix . d ( ) ) ) ) ;
parameters . unchecked_append ( TRY ( NumericStyleValue : : create_float ( affine_matrix . e ( ) ) ) ) ;
parameters . unchecked_append ( TRY ( NumericStyleValue : : create_float ( affine_matrix . f ( ) ) ) ) ;
NonnullRefPtr < StyleValue > matrix_function = TRY ( TransformationStyleValue : : create ( TransformFunction : : Matrix , move ( parameters ) ) ) ;
2022-07-19 16:44:24 +01:00
// Elsewhere we always store the transform property's value as a StyleValueList of TransformationStyleValues,
// so this is just for consistency.
2023-05-02 14:52:31 +01:00
StyleValueVector matrix_functions { matrix_function } ;
return StyleValueList : : create ( move ( matrix_functions ) , StyleValueList : : Separator : : Space ) ;
2022-07-19 16:44:24 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : VerticalAlign :
if ( auto const * length_percentage = layout_node . computed_values ( ) . vertical_align ( ) . get_pointer < LengthPercentage > ( ) ) {
2023-04-19 11:20:50 +01:00
return style_value_for_length_percentage ( * length_percentage ) ;
2022-02-26 01:34:07 +01:00
}
2023-05-27 15:52:49 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . vertical_align ( ) . get < VerticalAlign > ( ) ) ) ;
case PropertyID : : WhiteSpace :
2023-05-02 14:52:31 +01:00
return IdentifierStyleValue : : create ( to_value_id ( layout_node . computed_values ( ) . white_space ( ) ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : Width :
2022-09-25 15:48:23 +02:00
return style_value_for_size ( layout_node . computed_values ( ) . width ( ) ) ;
2023-05-27 15:52:49 +01:00
case PropertyID : : ZIndex : {
2022-07-14 17:04:03 +01:00
auto maybe_z_index = layout_node . computed_values ( ) . z_index ( ) ;
if ( ! maybe_z_index . has_value ( ) )
2023-05-02 14:52:31 +01:00
return nullptr ;
return NumericStyleValue : : create_integer ( maybe_z_index . release_value ( ) ) ;
2022-07-14 17:04:03 +01:00
}
2023-05-27 15:52:49 +01:00
case PropertyID : : Invalid :
return IdentifierStyleValue : : create ( ValueID : : Invalid ) ;
case PropertyID : : Custom :
2022-02-06 14:17:42 +01:00
dbgln_if ( LIBWEB_CSS_DEBUG , " Computed style for custom properties was requested (?) " ) ;
2023-05-02 14:52:31 +01:00
return nullptr ;
2021-09-12 20:05:29 +02:00
default :
2022-02-06 14:17:42 +01:00
dbgln_if ( LIBWEB_CSS_DEBUG , " FIXME: Computed style for the '{}' property was requested " , string_from_property_id ( property_id ) ) ;
2023-05-02 14:52:31 +01:00
return nullptr ;
2021-09-12 20:05:29 +02:00
}
2021-09-18 13:14:40 +02:00
}
}
2021-09-23 12:35:56 +02:00
Optional < StyleProperty > ResolvedCSSStyleDeclaration : : property ( PropertyID property_id ) const
2021-09-18 13:14:40 +02:00
{
2023-05-10 15:33:10 +02:00
// https://www.w3.org/TR/cssom-1/#dom-window-getcomputedstyle
// NOTE: This is a partial enforcement of step 5 ("If elt is connected, ...")
if ( ! m_element - > is_connected ( ) )
return { } ;
2023-05-27 15:52:49 +01:00
if ( property_affects_layout ( property_id ) ) {
2022-03-20 21:12:19 +01:00
const_cast < DOM : : Document & > ( m_element - > document ( ) ) . update_layout ( ) ;
} else {
// FIXME: If we had a way to update style for a single element, this would be a good place to use it.
const_cast < DOM : : Document & > ( m_element - > document ( ) ) . update_style ( ) ;
}
2021-09-18 13:14:40 +02:00
if ( ! m_element - > layout_node ( ) ) {
2022-12-06 03:08:20 -03:00
auto style_or_error = m_element - > document ( ) . style_computer ( ) . compute_style ( const_cast < DOM : : Element & > ( * m_element ) ) ;
if ( style_or_error . is_error ( ) ) {
dbgln ( " ResolvedCSSStyleDeclaration::property style computer failed " ) ;
return { } ;
}
auto style = style_or_error . release_value ( ) ;
2022-10-28 15:42:18 +01:00
// FIXME: This is a stopgap until we implement shorthand -> longhand conversion.
auto value = style - > maybe_null_property ( property_id ) ;
if ( ! value ) {
dbgln ( " FIXME: ResolvedCSSStyleDeclaration::property(property_id=0x{:x}) No value for property ID in newly computed style case. " , to_underlying ( property_id ) ) ;
return { } ;
}
2022-04-14 11:52:35 +01:00
return StyleProperty {
. property_id = property_id ,
2022-10-28 15:42:18 +01:00
. value = value . release_nonnull ( ) ,
2022-04-14 11:52:35 +01:00
} ;
2021-09-18 13:14:40 +02:00
}
auto & layout_node = * m_element - > layout_node ( ) ;
2023-05-02 14:52:31 +01:00
auto value = style_value_for_property ( layout_node , property_id ) . release_value_but_fixme_should_propagate_errors ( ) ;
2021-09-18 13:14:40 +02:00
if ( ! value )
return { } ;
return StyleProperty {
. property_id = property_id ,
. value = value . release_nonnull ( ) ,
} ;
2021-09-12 20:05:29 +02:00
}
2022-04-11 16:10:55 +02:00
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-setproperty
2022-09-25 17:03:42 +01:00
WebIDL : : ExceptionOr < void > ResolvedCSSStyleDeclaration : : set_property ( PropertyID , StringView , StringView )
2021-09-12 20:05:29 +02:00
{
2022-04-11 16:10:55 +02:00
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
2022-09-24 16:34:04 -06:00
return WebIDL : : NoModificationAllowedError : : create ( realm ( ) , " Cannot modify properties in result of getComputedStyle() " ) ;
2022-04-11 16:10:55 +02:00
}
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty
2022-12-04 18:02:33 +00:00
WebIDL : : ExceptionOr < DeprecatedString > ResolvedCSSStyleDeclaration : : remove_property ( PropertyID )
2022-04-11 16:10:55 +02:00
{
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
2022-09-24 16:34:04 -06:00
return WebIDL : : NoModificationAllowedError : : create ( realm ( ) , " Cannot remove properties from result of getComputedStyle() " ) ;
2021-09-12 20:05:29 +02:00
}
2021-10-01 19:57:45 +02:00
2022-12-04 18:02:33 +00:00
DeprecatedString ResolvedCSSStyleDeclaration : : serialized ( ) const
2021-10-01 19:57:45 +02:00
{
2021-10-15 19:38:39 +01:00
// https://www.w3.org/TR/cssom/#dom-cssstyledeclaration-csstext
2021-10-01 19:57:45 +02:00
// If the computed flag is set, then return the empty string.
// NOTE: ResolvedCSSStyleDeclaration is something you would only get from window.getComputedStyle(),
// which returns what the spec calls "resolved style". The "computed flag" is always set here.
2022-12-04 18:02:33 +00:00
return DeprecatedString : : empty ( ) ;
2021-10-01 19:57:45 +02:00
}
2022-11-05 04:51:05 +00:00
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
WebIDL : : ExceptionOr < void > ResolvedCSSStyleDeclaration : : set_css_text ( StringView )
{
// 1. If the computed flag is set, then throw a NoModificationAllowedError exception.
return WebIDL : : NoModificationAllowedError : : create ( realm ( ) , " Cannot modify properties in result of getComputedStyle() " ) ;
}
2021-09-12 20:05:29 +02:00
}