2025-08-08 08:57:23 -03:00
/*
* Copyright ( c ) 2025 , Sam Atkins < sam @ ladybird . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include "CSSStyleValue.h"
2026-04-18 05:54:06 -03:00
# include <LibWeb/Bindings/CSSStyleValue.h>
2025-08-08 08:57:23 -03:00
# include <LibWeb/Bindings/Intrinsics.h>
2025-08-14 09:55:45 -03:00
# include <LibWeb/CSS/Parser/Parser.h>
2025-09-26 08:44:56 -03:00
# include <LibWeb/CSS/PropertyNameAndID.h>
2025-09-19 10:54:23 -03:00
# include <LibWeb/CSS/StyleValues/StyleValue.h>
2025-11-03 14:13:58 -03:00
# include <LibWeb/CSS/StyleValues/StyleValueList.h>
2025-08-08 08:57:23 -03:00
# include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web : : CSS {
GC_DEFINE_ALLOCATOR ( CSSStyleValue ) ;
2026-06-08 15:31:27 -03:00
GC : : Ref < CSSStyleValue > CSSStyleValue : : create ( JS : : Realm & realm , Utf16FlyString associated_property , NonnullRefPtr < StyleValue const > source_value )
2025-08-08 08:57:23 -03:00
{
2025-09-19 10:54:23 -03:00
return realm . create < CSSStyleValue > ( realm , move ( associated_property ) , move ( source_value ) ) ;
2025-08-08 08:57:23 -03:00
}
2025-08-14 08:33:40 -03:00
CSSStyleValue : : CSSStyleValue ( JS : : Realm & realm )
: PlatformObject ( realm )
{
}
2025-09-19 10:54:23 -03:00
CSSStyleValue : : CSSStyleValue ( JS : : Realm & realm , NonnullRefPtr < StyleValue const > source_value )
: PlatformObject ( realm )
, m_source_value ( move ( source_value ) )
{
}
2026-06-08 15:31:27 -03:00
CSSStyleValue : : CSSStyleValue ( JS : : Realm & realm , Utf16FlyString associated_property , NonnullRefPtr < StyleValue const > source_value )
2025-08-08 08:57:23 -03:00
: PlatformObject ( realm )
, m_associated_property ( move ( associated_property ) )
2025-09-19 10:54:23 -03:00
, m_source_value ( move ( source_value ) )
2025-08-08 08:57:23 -03:00
{
}
void CSSStyleValue : : initialize ( JS : : Realm & realm )
{
WEB_SET_PROTOTYPE_FOR_INTERFACE ( CSSStyleValue ) ;
Base : : initialize ( realm ) ;
}
2025-09-19 10:54:23 -03:00
CSSStyleValue : : ~ CSSStyleValue ( ) = default ;
2025-08-14 09:55:45 -03:00
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssstylevalue-parse
2026-06-08 15:31:27 -03:00
WebIDL : : ExceptionOr < GC : : Ref < CSSStyleValue > > CSSStyleValue : : parse ( JS : : VM & vm , Utf16FlyString const & property , String css_text )
2025-08-14 09:55:45 -03:00
{
// The parse(property, cssText) method, when invoked, must parse a CSSStyleValue with property property, cssText
// cssText, and parseMultiple set to false, and return the result.
auto result = parse_a_css_style_value ( vm , property , css_text , ParseMultiple : : No ) ;
if ( result . is_exception ( ) )
return result . release_error ( ) ;
return result . value ( ) . get < GC : : Ref < CSSStyleValue > > ( ) ;
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssstylevalue-parseall
2026-06-08 15:31:27 -03:00
WebIDL : : ExceptionOr < GC : : RootVector < GC : : Ref < CSSStyleValue > > > CSSStyleValue : : parse_all ( JS : : VM & vm , Utf16FlyString const & property , String css_text )
2025-08-14 09:55:45 -03:00
{
// The parseAll(property, cssText) method, when invoked, must parse a CSSStyleValue with property property, cssText
// cssText, and parseMultiple set to true, and return the result.
auto result = parse_a_css_style_value ( vm , property , css_text , ParseMultiple : : Yes ) ;
if ( result . is_exception ( ) )
return result . release_error ( ) ;
return result . value ( ) . get < GC : : RootVector < GC : : Ref < CSSStyleValue > > > ( ) ;
}
// https://drafts.css-houdini.org/css-typed-om-1/#parse-a-cssstylevalue
2026-06-08 15:31:27 -03:00
WebIDL : : ExceptionOr < Variant < GC : : Ref < CSSStyleValue > , GC : : RootVector < GC : : Ref < CSSStyleValue > > > > CSSStyleValue : : parse_a_css_style_value ( JS : : VM & vm , Utf16FlyString property_name , String css_text , ParseMultiple parse_multiple )
2025-08-14 09:55:45 -03:00
{
// 1. If property is not a custom property name string, set property to property ASCII lowercased.
// 2. If property is not a valid CSS property, throw a TypeError.
2025-09-26 08:44:56 -03:00
auto property = PropertyNameAndID : : from_name ( property_name ) ;
if ( ! property . has_value ( ) )
return WebIDL : : SimpleException { WebIDL : : SimpleExceptionType : : TypeError , MUST ( String : : formatted ( " '{}' is not a valid CSS property " , property_name ) ) } ;
2025-08-14 09:55:45 -03:00
// 3. Attempt to parse cssText according to property’ s grammar.
// If this fails, throw a TypeError.
// Otherwise, let whole value be the parsed result.
2025-09-26 08:44:56 -03:00
auto whole_value = parse_css_value ( Parser : : ParsingParams { } , css_text , property - > id ( ) ) ;
2025-08-14 09:55:45 -03:00
if ( ! whole_value )
2025-09-26 08:44:56 -03:00
return WebIDL : : SimpleException { WebIDL : : SimpleExceptionType : : TypeError , MUST ( String : : formatted ( " Failed to parse '{}' as a value for '{}' property " , css_text , property - > name ( ) ) ) } ;
2025-08-14 09:55:45 -03:00
2025-11-03 14:13:58 -03:00
// 4. Subdivide into iterations whole value, according to property, and let values be the result.
auto values = whole_value - > subdivide_into_iterations ( property . value ( ) ) ;
2025-08-14 09:55:45 -03:00
// 5. For each value in values, replace it with the result of reifying value for property.
2026-05-19 15:40:15 -03:00
GC : : RootVector < GC : : Ref < CSSStyleValue > > reified_values ;
2025-11-03 14:13:58 -03:00
for ( auto const & value : values ) {
reified_values . append ( value - > reify ( * vm . current_realm ( ) , property - > name ( ) ) ) ;
}
2025-08-14 09:55:45 -03:00
// 6. If parseMultiple is false, return values[0]. Otherwise, return values.
2025-09-19 10:54:23 -03:00
// FIXME: We need to somehow store the source css_text on the returned CSSStyleValue.
// https://github.com/w3c/css-houdini-drafts/issues/1156
2025-08-14 09:55:45 -03:00
if ( parse_multiple = = ParseMultiple : : No )
return reified_values . take_first ( ) ;
return reified_values ;
}
2025-08-08 08:57:23 -03:00
// https://drafts.css-houdini.org/css-typed-om-1/#stylevalue-serialization
2026-06-22 09:15:11 -03:00
WebIDL : : ExceptionOr < Utf16String > CSSStyleValue : : to_string ( ) const
2025-08-08 08:57:23 -03:00
{
2025-09-19 10:54:23 -03:00
// FIXME: if the value was constructed from a USVString
// NB: Basically, if this was constructed with "parse a CSSStyleValue", regardless of what CSSStyleValue type it is now.
{
2025-08-08 08:57:23 -03:00
// the serialization is the USVString from which the value was constructed.
}
2025-08-14 08:33:40 -03:00
// otherwise, if the value was constructed using an IDL constructor
2025-08-08 08:57:23 -03:00
{
// the serialization is specified in the sections below.
2025-08-14 08:33:40 -03:00
// NB: This is handled by subclasses overriding this to_string() method.
2025-08-08 08:57:23 -03:00
}
// FIXME: otherwise, if the value was extracted from the CSSOM
2025-09-19 10:54:23 -03:00
// NB: For CSSStyleValue itself, we use the source value we were created from.
if ( m_source_value )
2026-06-22 09:15:11 -03:00
return Utf16String : : from_utf8_without_validation ( m_source_value - > to_string ( SerializationMode : : Normal ) ) ;
2025-08-08 08:57:23 -03:00
{
// the serialization is specified in §6.7 Serialization from CSSOM Values below.
}
2026-06-22 09:15:11 -03:00
return Utf16String : : from_utf8_without_validation ( " " sv ) ;
2025-08-08 08:57:23 -03:00
}
2025-10-02 10:30:55 -03:00
// https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation
2025-10-13 12:37:54 -03:00
WebIDL : : ExceptionOr < NonnullRefPtr < StyleValue const > > CSSStyleValue : : create_an_internal_representation ( PropertyNameAndID const & , PerformTypeCheck ) const
2025-10-02 10:30:55 -03:00
{
// If value is a direct CSSStyleValue,
// Return value’ s associated value.
if ( ! m_source_value )
return WebIDL : : SimpleException { WebIDL : : SimpleExceptionType : : TypeError , MUST ( String : : formatted ( " Missing {}::create_an_internal_representation() overload " , class_name ( ) ) ) } ;
return NonnullRefPtr { * m_source_value } ;
}
2025-08-08 08:57:23 -03:00
}