LibWeb/CSS: Implement CSSUnparsedValue and CSSVariableReferenceValue

We don't serialize these the way WPT expects, because we don't implement
the comment-insertion rules from CSS-Syntax. We don't implement that
for regular serialization either, so it's something we can worry about
later.
This commit is contained in:
Sam Atkins 2025-08-14 16:43:12 +01:00
commit 6428c9990d
Notes: github-actions[bot] 2025-08-21 09:23:12 +00:00
21 changed files with 442 additions and 35 deletions

View file

@ -132,6 +132,8 @@ set(SOURCES
CSS/CSSStyleValue.cpp CSS/CSSStyleValue.cpp
CSS/CSSSupportsRule.cpp CSS/CSSSupportsRule.cpp
CSS/CSSTransition.cpp CSS/CSSTransition.cpp
CSS/CSSUnparsedValue.cpp
CSS/CSSVariableReferenceValue.cpp
CSS/Descriptor.cpp CSS/Descriptor.cpp
CSS/Display.cpp CSS/Display.cpp
CSS/EdgeRect.cpp CSS/EdgeRect.cpp

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "CSSUnparsedValue.h"
#include <LibWeb/Bindings/CSSUnparsedValuePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSVariableReferenceValue.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::CSS {
GC_DEFINE_ALLOCATOR(CSSUnparsedValue);
GC::Ref<CSSUnparsedValue> CSSUnparsedValue::create(JS::Realm& realm, Vector<GCRootCSSUnparsedSegment> value)
{
// NB: Convert our GC::Roots into GC::Refs.
Vector<CSSUnparsedSegment> converted_value;
for (auto const& variant : value) {
variant.visit(
[&](GC::Root<CSSVariableReferenceValue> const& it) { converted_value.append(GC::Ref { *it }); },
[&](String const& it) { converted_value.append(it); });
}
return realm.create<CSSUnparsedValue>(realm, move(converted_value));
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssunparsedvalue-cssunparsedvalue
WebIDL::ExceptionOr<GC::Ref<CSSUnparsedValue>> CSSUnparsedValue::construct_impl(JS::Realm& realm, Vector<GCRootCSSUnparsedSegment> value)
{
// AD-HOC: There is no spec for this, see https://github.com/w3c/css-houdini-drafts/issues/1146
return CSSUnparsedValue::create(realm, move(value));
}
CSSUnparsedValue::CSSUnparsedValue(JS::Realm& realm, Vector<CSSUnparsedSegment> value)
: CSSStyleValue(realm)
, m_tokens(move(value))
{
m_legacy_platform_object_flags = LegacyPlatformObjectFlags {
.supports_indexed_properties = true,
.has_indexed_property_setter = true,
};
}
CSSUnparsedValue::~CSSUnparsedValue() = default;
void CSSUnparsedValue::initialize(JS::Realm& realm)
{
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSUnparsedValue);
Base::initialize(realm);
}
void CSSUnparsedValue::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
for (auto const& token : m_tokens) {
if (auto* variable = token.get_pointer<GC::Ref<CSSVariableReferenceValue>>()) {
visitor.visit(*variable);
}
}
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssunparsedvalue-length
WebIDL::UnsignedLong CSSUnparsedValue::length() const
{
// The length attribute returns the size of the [[tokens]] internal slot.
return m_tokens.size();
}
// https://drafts.css-houdini.org/css-typed-om-1/#ref-for-dfn-determine-the-value-of-an-indexed-property
Optional<JS::Value> CSSUnparsedValue::item_value(size_t index) const
{
// To determine the value of an indexed property of a CSSUnparsedValue this and an index n, let tokens be thiss
// [[tokens]] internal slot, and return tokens[n].
if (index >= m_tokens.size())
return {};
auto value = m_tokens[index];
return value.visit(
[&](GC::Ref<CSSVariableReferenceValue> const& variable) -> JS::Value { return variable; },
[&](String const& string) -> JS::Value { return JS::PrimitiveString::create(vm(), string); });
}
static WebIDL::ExceptionOr<CSSUnparsedSegment> unparsed_segment_from_js_value(JS::VM& vm, JS::Value& value)
{
if (value.is_object()) {
if (auto* variable_reference = as_if<CSSVariableReferenceValue>(value.as_object())) {
return GC::Ref { *variable_reference };
}
}
return TRY(value.to_string(vm));
}
// https://drafts.css-houdini.org/css-typed-om-1/#ref-for-dfn-set-the-value-of-an-existing-indexed-property
WebIDL::ExceptionOr<void> CSSUnparsedValue::set_value_of_existing_indexed_property(u32 n, JS::Value value)
{
// To set the value of an existing indexed property of a CSSUnparsedValue this, an index n, and a value new value,
// let tokens be thiss [[tokens]] internal slot, and set tokens[n] to new value.
m_tokens[n] = TRY(unparsed_segment_from_js_value(vm(), value));
return {};
}
// https://drafts.css-houdini.org/css-typed-om-1/#ref-for-dfn-set-the-value-of-a-new-indexed-property
WebIDL::ExceptionOr<void> CSSUnparsedValue::set_value_of_new_indexed_property(u32 n, JS::Value value)
{
// To set the value of a new indexed property of a CSSUnparsedValue this, an index n, and a value new value,
// let tokens be thiss [[tokens]] internal slot. If n is not equal to the size of tokens, throw a RangeError.
// Otherwise, append new value to tokens.
if (n != m_tokens.size())
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Index out of range"sv };
m_tokens.append(TRY(unparsed_segment_from_js_value(vm(), value)));
return {};
}
// https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssunparsedvalue
String CSSUnparsedValue::to_string() const
{
// To serialize a CSSUnparsedValue this:
// 1. Let s initially be the empty string.
StringBuilder s;
// 2. For each item in thiss [[tokens]] internal slot:
for (auto const& item : m_tokens) {
// FIXME: In order to match the expected test behaviour, this should insert comments, with the same rules as
// serialize_a_series_of_component_values(). See https://github.com/w3c/css-houdini-drafts/issues/1148
item.visit(
// 1. If item is a USVString, append it to s.
[&](String const& string) {
s.append(string);
},
// 2. Otherwise, item is a CSSVariableReferenceValue. Serialize it, then append the result to s.
[&](GC::Ref<CSSVariableReferenceValue> const& variable) {
s.append(variable->to_string());
});
}
// 3. Return s.
return s.to_string_without_validation();
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/CSS/CSSStyleValue.h>
#include <LibWeb/WebIDL/Types.h>
namespace Web::CSS {
using CSSUnparsedSegment = Variant<String, GC::Ref<CSSVariableReferenceValue>>;
using GCRootCSSUnparsedSegment = Variant<String, GC::Root<CSSVariableReferenceValue>>;
// https://drafts.css-houdini.org/css-typed-om-1/#cssunparsedvalue
class CSSUnparsedValue : public CSSStyleValue {
WEB_PLATFORM_OBJECT(CSSUnparsedValue, CSSStyleValue);
GC_DECLARE_ALLOCATOR(CSSUnparsedValue);
public:
[[nodiscard]] static GC::Ref<CSSUnparsedValue> create(JS::Realm&, Vector<GCRootCSSUnparsedSegment>);
static WebIDL::ExceptionOr<GC::Ref<CSSUnparsedValue>> construct_impl(JS::Realm&, Vector<GCRootCSSUnparsedSegment>);
virtual ~CSSUnparsedValue() override;
WebIDL::UnsignedLong length() const;
virtual Optional<JS::Value> item_value(size_t index) const override;
virtual WebIDL::ExceptionOr<void> set_value_of_existing_indexed_property(u32, JS::Value) override;
virtual WebIDL::ExceptionOr<void> set_value_of_new_indexed_property(u32, JS::Value) override;
virtual String to_string() const override;
private:
explicit CSSUnparsedValue(JS::Realm&, Vector<CSSUnparsedSegment>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Visitor&) override;
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssunparsedvalue-tokens-slot
// They have a [[tokens]] internal slot, which is a list of USVStrings and CSSVariableReferenceValue objects.
// This list is the objects values to iterate over.
Vector<CSSUnparsedSegment> m_tokens;
};
}

View file

@ -0,0 +1,16 @@
#import <CSS/CSSStyleValue.idl>
#import <CSS/CSSVariableReferenceValue.idl>
// https://drafts.css-houdini.org/css-typed-om-1/#cssunparsedvalue
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
interface CSSUnparsedValue : CSSStyleValue {
constructor(sequence<CSSUnparsedSegment> members);
readonly attribute unsigned long length;
getter CSSUnparsedSegment (unsigned long index);
setter undefined (unsigned long index, CSSUnparsedSegment val);
// FIXME: Different order from the spec, because our IDL parser needs the indexed getter to be defined already.
iterable<CSSUnparsedSegment>;
};
// https://drafts.css-houdini.org/css-typed-om-1/#typedefdef-cssunparsedsegment
typedef (USVString or CSSVariableReferenceValue) CSSUnparsedSegment;

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "CSSVariableReferenceValue.h"
#include <LibWeb/Bindings/CSSVariableReferenceValuePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSUnparsedValue.h>
#include <LibWeb/CSS/PropertyName.h>
#include <LibWeb/HTML/CustomElements/CustomElementName.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::CSS {
GC_DEFINE_ALLOCATOR(CSSVariableReferenceValue);
GC::Ref<CSSVariableReferenceValue> CSSVariableReferenceValue::create(JS::Realm& realm, FlyString variable, GC::Ptr<CSSUnparsedValue> fallback)
{
return realm.create<CSSVariableReferenceValue>(realm, move(variable), move(fallback));
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssvariablereferencevalue-cssvariablereferencevalue
WebIDL::ExceptionOr<GC::Ref<CSSVariableReferenceValue>> CSSVariableReferenceValue::construct_impl(JS::Realm& realm, FlyString variable, GC::Ptr<CSSUnparsedValue> fallback)
{
// The CSSVariableReferenceValue(variable, fallback) constructor must, when called, perform the following steps:
// 1. If variable is not a custom property name string, throw a TypeError.
if (!is_a_custom_property_name_string(variable))
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("'{}' is not a valid CSS custom property name", variable)) };
// 2. Return a new CSSVariableReferenceValue with its variable internal slot set to variable and its fallback internal slot set to fallback.
return CSSVariableReferenceValue::create(realm, move(variable), move(fallback));
}
CSSVariableReferenceValue::CSSVariableReferenceValue(JS::Realm& realm, FlyString variable, GC::Ptr<CSSUnparsedValue> fallback)
: Bindings::PlatformObject(realm)
, m_variable(move(variable))
, m_fallback(move(fallback))
{
}
CSSVariableReferenceValue::~CSSVariableReferenceValue() = default;
void CSSVariableReferenceValue::initialize(JS::Realm& realm)
{
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSVariableReferenceValue);
Base::initialize(realm);
}
void CSSVariableReferenceValue::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_fallback);
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssvariablereferencevalue-variable
String CSSVariableReferenceValue::variable() const
{
// The getter for the variable attribute of a CSSVariableReferenceValue this must return its variable internal slot.
return m_variable.to_string();
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssvariablereferencevalue-variable
WebIDL::ExceptionOr<void> CSSVariableReferenceValue::set_variable(FlyString variable)
{
// The variable attribute of a CSSVariableReferenceValue this must, on setting a variable variable, perform the following steps:
// 1. If variable is not a custom property name string, throw a TypeError.
if (!is_a_custom_property_name_string(variable))
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("'{}' is not a valid CSS custom property name", variable)) };
// 2. Otherwise, set thiss variable internal slot to variable.
m_variable = move(variable);
return {};
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssvariablereferencevalue-fallback
GC::Ptr<CSSUnparsedValue> CSSVariableReferenceValue::fallback() const
{
// AD-HOC: No spec algorithm, see https://github.com/w3c/css-houdini-drafts/issues/1146#issuecomment-3188550133
return m_fallback;
}
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssvariablereferencevalue-fallback
WebIDL::ExceptionOr<void> CSSVariableReferenceValue::set_fallback(GC::Ptr<CSSUnparsedValue> fallback)
{
// AD-HOC: No spec algorithm, see https://github.com/w3c/css-houdini-drafts/issues/1146#issuecomment-3188550133
m_fallback = move(fallback);
return {};
}
// https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssvariablereferencevalue
String CSSVariableReferenceValue::to_string() const
{
// To serialize a CSSVariableReferenceValue this:
// 1. Let s initially be "var(".
StringBuilder s;
s.append("var("sv);
// 2. Append thiss variable internal slot to s.
s.append(m_variable);
// 3. If thiss fallback internal slot is not null, append ", " to s, then serialize the fallback internal slot and append it to s.
if (m_fallback) {
// AD-HOC: Tested behaviour requires we append "," without the space. https://github.com/w3c/css-houdini-drafts/issues/1148
s.append(","sv);
s.append(m_fallback->to_string());
}
// 4. Append ")" to s and return s.
s.append(")"sv);
return s.to_string_without_validation();
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/FlyString.h>
#include <LibWeb/Bindings/PlatformObject.h>
namespace Web::CSS {
class CSSVariableReferenceValue : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(CSSVariableReferenceValue, Bindings::PlatformObject);
GC_DECLARE_ALLOCATOR(CSSVariableReferenceValue);
public:
[[nodiscard]] static GC::Ref<CSSVariableReferenceValue> create(JS::Realm&, FlyString variable, GC::Ptr<CSSUnparsedValue> fallback = nullptr);
static WebIDL::ExceptionOr<GC::Ref<CSSVariableReferenceValue>> construct_impl(JS::Realm&, FlyString variable, GC::Ptr<CSSUnparsedValue> fallback);
virtual ~CSSVariableReferenceValue() override;
String variable() const;
WebIDL::ExceptionOr<void> set_variable(FlyString);
GC::Ptr<CSSUnparsedValue> fallback() const;
WebIDL::ExceptionOr<void> set_fallback(GC::Ptr<CSSUnparsedValue>);
String to_string() const;
private:
CSSVariableReferenceValue(JS::Realm&, FlyString variable, GC::Ptr<CSSUnparsedValue> fallback);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Visitor&) override;
FlyString m_variable;
GC::Ptr<CSSUnparsedValue> m_fallback;
};
}

View file

@ -0,0 +1,9 @@
#import <CSS/CSSUnparsedValue.idl>
// https://drafts.css-houdini.org/css-typed-om-1/#cssvariablereferencevalue
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
interface CSSVariableReferenceValue {
constructor(USVString variable, optional CSSUnparsedValue? fallback = null);
attribute USVString variable;
readonly attribute CSSUnparsedValue? fallback;
};

View file

@ -256,6 +256,8 @@ class CSSStyleRule;
class CSSStyleSheet; class CSSStyleSheet;
class CSSStyleValue; class CSSStyleValue;
class CSSSupportsRule; class CSSSupportsRule;
class CSSUnparsedValue;
class CSSVariableReferenceValue;
class CursorStyleValue; class CursorStyleValue;
class CustomIdentStyleValue; class CustomIdentStyleValue;
class DimensionStyleValue; class DimensionStyleValue;

View file

@ -52,6 +52,8 @@ libweb_js_bindings(CSS/CSSStyleSheet)
libweb_js_bindings(CSS/CSSStyleValue) libweb_js_bindings(CSS/CSSStyleValue)
libweb_js_bindings(CSS/CSSSupportsRule) libweb_js_bindings(CSS/CSSSupportsRule)
libweb_js_bindings(CSS/CSSTransition) libweb_js_bindings(CSS/CSSTransition)
libweb_js_bindings(CSS/CSSUnparsedValue)
libweb_js_bindings(CSS/CSSVariableReferenceValue)
libweb_js_bindings(CSS/FontFace) libweb_js_bindings(CSS/FontFace)
libweb_js_bindings(CSS/FontFaceSet) libweb_js_bindings(CSS/FontFaceSet)
libweb_js_bindings(CSS/MediaList) libweb_js_bindings(CSS/MediaList)

View file

@ -56,6 +56,8 @@ static bool is_platform_object(Type const& type)
"CryptoKey"sv, "CryptoKey"sv,
"CSSKeywordValue"sv, "CSSKeywordValue"sv,
"CSSStyleValue"sv, "CSSStyleValue"sv,
"CSSUnparsedValue"sv,
"CSSVariableReferenceValue"sv,
"CustomStateSet"sv, "CustomStateSet"sv,
"DataTransfer"sv, "DataTransfer"sv,
"Document"sv, "Document"sv,

View file

@ -64,6 +64,8 @@ CSSStyleSheet
CSSStyleValue CSSStyleValue
CSSSupportsRule CSSSupportsRule
CSSTransition CSSTransition
CSSUnparsedValue
CSSVariableReferenceValue
CacheStorage CacheStorage
CanvasGradient CanvasGradient
CanvasPattern CanvasPattern

View file

@ -1,3 +1,21 @@
Harness status: Error Harness status: OK
Found 0 tests Found 16 tests
16 Fail
Fail Normalizing "var(--A)" on a CSS property returns correct CSSUnparsedValue
Fail Normalizing "var(--A)" on a shorthand returns correct CSSUnparsedValue
Fail Normalizing "var(--A)" on a list-valued property returns correct CSSUnparsedValue
Fail Normalizing "var(--A)" on a custom property returns correct CSSUnparsedValue
Fail Normalizing "var(--A, 1em)" on a CSS property returns correct CSSUnparsedValue
Fail Normalizing "var(--A, 1em)" on a shorthand returns correct CSSUnparsedValue
Fail Normalizing "var(--A, 1em)" on a list-valued property returns correct CSSUnparsedValue
Fail Normalizing "var(--A, 1em)" on a custom property returns correct CSSUnparsedValue
Fail Normalizing "var(--A, var(--B))" on a CSS property returns correct CSSUnparsedValue
Fail Normalizing "var(--A, var(--B))" on a shorthand returns correct CSSUnparsedValue
Fail Normalizing "var(--A, var(--B))" on a list-valued property returns correct CSSUnparsedValue
Fail Normalizing "var(--A, var(--B))" on a custom property returns correct CSSUnparsedValue
Fail Normalizing "calc(42px + var(--foo, 15em) + var(--bar, var(--far) + 15px))" on a CSS property returns correct CSSUnparsedValue
Fail Normalizing "calc(42px + var(--foo, 15em) + var(--bar, var(--far) + 15px))" on a shorthand returns correct CSSUnparsedValue
Fail Normalizing "calc(42px + var(--foo, 15em) + var(--bar, var(--far) + 15px))" on a list-valued property returns correct CSSUnparsedValue
Fail Normalizing "calc(42px + var(--foo, 15em) + var(--bar, var(--far) + 15px))" on a custom property returns correct CSSUnparsedValue

View file

@ -2,9 +2,10 @@ Harness status: OK
Found 5 tests Found 5 tests
5 Fail 2 Pass
3 Fail
Fail CSSUnparsedValue containing strings serializes to its tokenized contents Fail CSSUnparsedValue containing strings serializes to its tokenized contents
Fail CSSUnparsedValue containing variable references serializes its tokenized contents Pass CSSUnparsedValue containing variable references serializes its tokenized contents
Fail CSSUnparsedValue containing mix of strings and variable references serializes to its tokenized contents Fail CSSUnparsedValue containing mix of strings and variable references serializes to its tokenized contents
Fail CSSUnparsedValue can hold same object in multiple places Pass CSSUnparsedValue can hold same object in multiple places
Fail attributeStyleMap round-trips correctly, though the comment is gone Fail attributeStyleMap round-trips correctly, though the comment is gone

View file

@ -2,5 +2,5 @@ Harness status: OK
Found 1 tests Found 1 tests
1 Fail 1 Pass
Fail Don't crash when serializing empty CSSUnparsedValue Pass Don't crash when serializing empty CSSUnparsedValue

View file

@ -2,10 +2,10 @@ Harness status: OK
Found 6 tests Found 6 tests
6 Fail 6 Pass
Fail Getting invalid index in CSSUnparsedValue returns undefined Pass Getting invalid index in CSSUnparsedValue returns undefined
Fail Can update fragment in CSSUnparsedValue to a String Pass Can update fragment in CSSUnparsedValue to a String
Fail Can update fragment in CSSUnparsedValue to a CSSVariableReference Pass Can update fragment in CSSUnparsedValue to a CSSVariableReference
Fail Setting one past the last fragment in a CSSUnparsedValue to a String appends the new fragment Pass Setting one past the last fragment in a CSSUnparsedValue to a String appends the new fragment
Fail Setting one past the last fragment in a CSSUnparsedValue to a CSSVariableReferenceValue appends the new fragment Pass Setting one past the last fragment in a CSSUnparsedValue to a CSSVariableReferenceValue appends the new fragment
Fail Setting out of range index in CSSUnparsedValue throws RangeError Pass Setting out of range index in CSSUnparsedValue throws RangeError

View file

@ -2,6 +2,6 @@ Harness status: OK
Found 2 tests Found 2 tests
2 Fail 2 Pass
Fail Iterating over an empty CSSUnparsedValue produces nothing Pass Iterating over an empty CSSUnparsedValue produces nothing
Fail Iterating over a CSSUnparsedValue produces all fragments Pass Iterating over a CSSUnparsedValue produces all fragments

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 4 tests Found 4 tests
4 Fail 4 Pass
Fail Length of CSSUnparsedValue with no fragments is zero Pass Length of CSSUnparsedValue with no fragments is zero
Fail Length of CSSUnparsedValue with multiple fragments is the number of fragments Pass Length of CSSUnparsedValue with multiple fragments is the number of fragments
Fail Length of CSSUnparsedValue updates when fragments are appended Pass Length of CSSUnparsedValue updates when fragments are appended
Fail Length of CSSUnparsedValue does not change when fragments are modified Pass Length of CSSUnparsedValue does not change when fragments are modified

View file

@ -1,3 +1,9 @@
Harness status: Error Harness status: OK
Found 0 tests Found 4 tests
4 Pass
Pass CSSUnparsedValue can be constructed from no arguments
Pass CSSUnparsedValue can be constructed from a single empty string
Pass CSSUnparsedValue can be constructed from a single CSSVariableReferenceValue
Pass CSSUnparsedValue can be constructed from a mix of strings and CSSVariableReferenceValues

View file

@ -2,6 +2,6 @@ Harness status: OK
Found 2 tests Found 2 tests
2 Fail 2 Pass
Fail Constructing a CSSVariableReferenceValue with an empty variable name throws a TypeError Pass Constructing a CSSVariableReferenceValue with an empty variable name throws a TypeError
Fail Constructing a CSSVariableReferenceValue with an invalid variable name throws SyntaxError Pass Constructing a CSSVariableReferenceValue with an invalid variable name throws SyntaxError

View file

@ -2,7 +2,7 @@ Harness status: OK
Found 3 tests Found 3 tests
3 Fail 3 Pass
Fail CSSVariableReferenceValue.variable can updated to a valid custom property name Pass CSSVariableReferenceValue.variable can updated to a valid custom property name
Fail Updating CSSVariableReferenceValue.variable to the empty string throws TypeError Pass Updating CSSVariableReferenceValue.variable to the empty string throws TypeError
Fail Updating CSSVariableReferenceValue.variable to an invalid custom property name throws TypeError Pass Updating CSSVariableReferenceValue.variable to an invalid custom property name throws TypeError

View file

@ -2,7 +2,7 @@ Harness status: OK
Found 3 tests Found 3 tests
3 Fail 3 Pass
Fail CSSVariableReferenceValue can be constructed with no fallback Pass CSSVariableReferenceValue can be constructed with no fallback
Fail CSSVariableReferenceValue can be constructed with null fallback Pass CSSVariableReferenceValue can be constructed with null fallback
Fail CSSVariableReferenceValue can be constructed with valid fallback Pass CSSVariableReferenceValue can be constructed with valid fallback