2025-08-08 12:57:23 +01:00
/*
* Copyright ( c ) 2025 , Sam Atkins < sam @ ladybird . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include "CSSStyleValue.h"
# include <LibWeb/Bindings/CSSStyleValuePrototype.h>
# include <LibWeb/Bindings/Intrinsics.h>
2025-08-14 13:55:45 +01:00
# include <LibWeb/CSS/Parser/Parser.h>
2025-09-26 12:44:56 +01:00
# include <LibWeb/CSS/PropertyNameAndID.h>
2025-09-19 14:54:23 +01:00
# include <LibWeb/CSS/StyleValues/StyleValue.h>
2025-08-08 12:57:23 +01:00
# include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web : : CSS {
GC_DEFINE_ALLOCATOR ( CSSStyleValue ) ;
2025-09-19 14:54:23 +01:00
GC : : Ref < CSSStyleValue > CSSStyleValue : : create ( JS : : Realm & realm , FlyString associated_property , NonnullRefPtr < StyleValue const > source_value )
2025-08-08 12:57:23 +01:00
{
2025-09-19 14:54:23 +01:00
return realm . create < CSSStyleValue > ( realm , move ( associated_property ) , move ( source_value ) ) ;
2025-08-08 12:57:23 +01:00
}
2025-08-14 12:33:40 +01:00
CSSStyleValue : : CSSStyleValue ( JS : : Realm & realm )
: PlatformObject ( realm )
{
}
2025-09-19 14:54:23 +01:00
CSSStyleValue : : CSSStyleValue ( JS : : Realm & realm , NonnullRefPtr < StyleValue const > source_value )
: PlatformObject ( realm )
, m_source_value ( move ( source_value ) )
{
}
CSSStyleValue : : CSSStyleValue ( JS : : Realm & realm , FlyString associated_property , NonnullRefPtr < StyleValue const > source_value )
2025-08-08 12:57:23 +01:00
: PlatformObject ( realm )
, m_associated_property ( move ( associated_property ) )
2025-09-19 14:54:23 +01:00
, m_source_value ( move ( source_value ) )
2025-08-08 12:57:23 +01:00
{
}
void CSSStyleValue : : initialize ( JS : : Realm & realm )
{
WEB_SET_PROTOTYPE_FOR_INTERFACE ( CSSStyleValue ) ;
Base : : initialize ( realm ) ;
}
2025-09-19 14:54:23 +01:00
CSSStyleValue : : ~ CSSStyleValue ( ) = default ;
2025-08-14 13:55:45 +01:00
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssstylevalue-parse
2025-09-25 13:00:43 +01:00
WebIDL : : ExceptionOr < GC : : Ref < CSSStyleValue > > CSSStyleValue : : parse ( JS : : VM & vm , FlyString const & property , String css_text )
2025-08-14 13:55:45 +01: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
2025-09-25 13:00:43 +01:00
WebIDL : : ExceptionOr < GC : : RootVector < GC : : Ref < CSSStyleValue > > > CSSStyleValue : : parse_all ( JS : : VM & vm , FlyString const & property , String css_text )
2025-08-14 13:55:45 +01: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
2025-09-26 12:44:56 +01:00
WebIDL : : ExceptionOr < Variant < GC : : Ref < CSSStyleValue > , GC : : RootVector < GC : : Ref < CSSStyleValue > > > > CSSStyleValue : : parse_a_css_style_value ( JS : : VM & vm , FlyString property_name , String css_text , ParseMultiple parse_multiple )
2025-08-14 13:55:45 +01: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 12:44:56 +01: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 13:55:45 +01: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 12:44:56 +01:00
auto whole_value = parse_css_value ( Parser : : ParsingParams { } , css_text , property - > id ( ) ) ;
2025-08-14 13:55:45 +01:00
if ( ! whole_value )
2025-09-26 12:44:56 +01: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 13:55:45 +01:00
// FIXME: 4. Subdivide into iterations whole value, according to property, and let values be the result.
// 5. For each value in values, replace it with the result of reifying value for property.
GC : : RootVector < GC : : Ref < CSSStyleValue > > reified_values { vm . heap ( ) } ;
2025-09-26 12:44:56 +01:00
reified_values . append ( whole_value - > reify ( * vm . current_realm ( ) , property - > name ( ) ) ) ;
2025-08-14 13:55:45 +01:00
// 6. If parseMultiple is false, return values[0]. Otherwise, return values.
2025-09-19 14:54:23 +01: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 13:55:45 +01:00
if ( parse_multiple = = ParseMultiple : : No )
return reified_values . take_first ( ) ;
return reified_values ;
}
2025-08-08 12:57:23 +01:00
// https://drafts.css-houdini.org/css-typed-om-1/#stylevalue-serialization
2025-09-16 15:06:38 +01:00
WebIDL : : ExceptionOr < String > CSSStyleValue : : to_string ( ) const
2025-08-08 12:57:23 +01:00
{
2025-09-19 14:54:23 +01: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 12:57:23 +01:00
// the serialization is the USVString from which the value was constructed.
}
2025-08-14 12:33:40 +01:00
// otherwise, if the value was constructed using an IDL constructor
2025-08-08 12:57:23 +01:00
{
// the serialization is specified in the sections below.
2025-08-14 12:33:40 +01:00
// NB: This is handled by subclasses overriding this to_string() method.
2025-08-08 12:57:23 +01:00
}
// FIXME: otherwise, if the value was extracted from the CSSOM
2025-09-19 14:54:23 +01:00
// NB: For CSSStyleValue itself, we use the source value we were created from.
if ( m_source_value )
return m_source_value - > to_string ( SerializationMode : : Normal ) ;
2025-08-08 12:57:23 +01:00
{
// the serialization is specified in §6.7 Serialization from CSSOM Values below.
}
2025-09-16 15:06:38 +01:00
return String { } ;
2025-08-08 12:57:23 +01:00
}
2025-10-02 14:30:55 +01:00
// https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation
2025-10-13 16:37:54 +01:00
WebIDL : : ExceptionOr < NonnullRefPtr < StyleValue const > > CSSStyleValue : : create_an_internal_representation ( PropertyNameAndID const & , PerformTypeCheck ) const
2025-10-02 14:30:55 +01: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 12:57:23 +01:00
}