mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 13:18:19 +00:00
LibWeb/CSS: Implement CSSKeywordValue
CSSStyleValue is adjusted to allow for subclasses. Serialization for CSSKeywordValue is implemented differently than the spec says because of a spec bug: https://github.com/w3c/csswg-drafts/issues/12545
This commit is contained in:
parent
030e670fcb
commit
a93c6a347f
Notes:
github-actions[bot]
2025-08-21 09:23:30 +00:00
Author: https://github.com/AtkinsSJ
Commit: a93c6a347f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5901
14 changed files with 150 additions and 21 deletions
|
@ -112,6 +112,7 @@ set(SOURCES
|
||||||
CSS/CSSImportRule.cpp
|
CSS/CSSImportRule.cpp
|
||||||
CSS/CSSKeyframeRule.cpp
|
CSS/CSSKeyframeRule.cpp
|
||||||
CSS/CSSKeyframesRule.cpp
|
CSS/CSSKeyframesRule.cpp
|
||||||
|
CSS/CSSKeywordValue.cpp
|
||||||
CSS/CSSLayerBlockRule.cpp
|
CSS/CSSLayerBlockRule.cpp
|
||||||
CSS/CSSLayerStatementRule.cpp
|
CSS/CSSLayerStatementRule.cpp
|
||||||
CSS/CSSMarginRule.cpp
|
CSS/CSSMarginRule.cpp
|
||||||
|
|
66
Libraries/LibWeb/CSS/CSSKeywordValue.cpp
Normal file
66
Libraries/LibWeb/CSS/CSSKeywordValue.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CSSKeywordValue.h"
|
||||||
|
#include <LibWeb/Bindings/CSSKeywordValuePrototype.h>
|
||||||
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/CSS/Serialize.h>
|
||||||
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
GC_DEFINE_ALLOCATOR(CSSKeywordValue);
|
||||||
|
|
||||||
|
GC::Ref<CSSKeywordValue> CSSKeywordValue::create(JS::Realm& realm, FlyString value)
|
||||||
|
{
|
||||||
|
return realm.create<CSSKeywordValue>(realm, move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#dom-csskeywordvalue-csskeywordvalue
|
||||||
|
WebIDL::ExceptionOr<GC::Ref<CSSKeywordValue>> CSSKeywordValue::construct_impl(JS::Realm& realm, FlyString value)
|
||||||
|
{
|
||||||
|
// 1. If value is an empty string, throw a TypeError.
|
||||||
|
if (value.is_empty())
|
||||||
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot create a CSSKeywordValue with an empty string as the value"sv };
|
||||||
|
|
||||||
|
// 2. Otherwise, return a new CSSKeywordValue with its value internal slot set to value.
|
||||||
|
return CSSKeywordValue::create(realm, move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
CSSKeywordValue::CSSKeywordValue(JS::Realm& realm, FlyString value)
|
||||||
|
: CSSStyleValue(realm)
|
||||||
|
, m_value(move(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSSKeywordValue::initialize(JS::Realm& realm)
|
||||||
|
{
|
||||||
|
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSKeywordValue);
|
||||||
|
Base::initialize(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#dom-csskeywordvalue-value
|
||||||
|
WebIDL::ExceptionOr<void> CSSKeywordValue::set_value(FlyString value)
|
||||||
|
{
|
||||||
|
// 1. If value is an empty string, throw a TypeError.
|
||||||
|
if (value.is_empty())
|
||||||
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot set CSSKeywordValue.value to an empty string"sv };
|
||||||
|
|
||||||
|
// 2. Otherwise, set this’s value internal slot, to value.
|
||||||
|
m_value = move(value);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#keywordvalue-serialization
|
||||||
|
String CSSKeywordValue::to_string() const
|
||||||
|
{
|
||||||
|
// To serialize a CSSKeywordValue this:
|
||||||
|
// 1. Return this’s value internal slot.
|
||||||
|
// AD-HOC: Serialize it as an identifier. Spec issue: https://github.com/w3c/csswg-drafts/issues/12545
|
||||||
|
return serialize_an_identifier(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
Libraries/LibWeb/CSS/CSSKeywordValue.h
Normal file
38
Libraries/LibWeb/CSS/CSSKeywordValue.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/FlyString.h>
|
||||||
|
#include <LibWeb/CSS/CSSStyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#csskeywordvalue
|
||||||
|
class CSSKeywordValue : public CSSStyleValue {
|
||||||
|
WEB_PLATFORM_OBJECT(CSSKeywordValue, CSSStyleValue);
|
||||||
|
GC_DECLARE_ALLOCATOR(CSSKeywordValue);
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] static GC::Ref<CSSKeywordValue> create(JS::Realm&, FlyString value);
|
||||||
|
static WebIDL::ExceptionOr<GC::Ref<CSSKeywordValue>> construct_impl(JS::Realm&, FlyString value);
|
||||||
|
|
||||||
|
virtual ~CSSKeywordValue() override = default;
|
||||||
|
|
||||||
|
FlyString const& value() const { return m_value; }
|
||||||
|
WebIDL::ExceptionOr<void> set_value(FlyString value);
|
||||||
|
|
||||||
|
virtual String to_string() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit CSSKeywordValue(JS::Realm&, FlyString value);
|
||||||
|
|
||||||
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
|
||||||
|
FlyString m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
10
Libraries/LibWeb/CSS/CSSKeywordValue.idl
Normal file
10
Libraries/LibWeb/CSS/CSSKeywordValue.idl
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#import <CSS/CSSStyleValue.idl>
|
||||||
|
|
||||||
|
// https://drafts.css-houdini.org/css-typed-om-1/#csskeywordvalue
|
||||||
|
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
|
||||||
|
interface CSSKeywordValue : CSSStyleValue {
|
||||||
|
constructor(USVString value);
|
||||||
|
attribute USVString value;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef (DOMString or CSSKeywordValue) CSSKeywordish;
|
|
@ -18,6 +18,11 @@ GC::Ref<CSSStyleValue> CSSStyleValue::create(JS::Realm& realm, String associated
|
||||||
return realm.create<CSSStyleValue>(realm, move(associated_property), move(constructed_from_string));
|
return realm.create<CSSStyleValue>(realm, move(associated_property), move(constructed_from_string));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSSStyleValue::CSSStyleValue(JS::Realm& realm)
|
||||||
|
: PlatformObject(realm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CSSStyleValue::CSSStyleValue(JS::Realm& realm, String associated_property, String constructed_from_string)
|
CSSStyleValue::CSSStyleValue(JS::Realm& realm, String associated_property, String constructed_from_string)
|
||||||
: PlatformObject(realm)
|
: PlatformObject(realm)
|
||||||
, m_associated_property(move(associated_property))
|
, m_associated_property(move(associated_property))
|
||||||
|
@ -39,9 +44,10 @@ String CSSStyleValue::to_string() const
|
||||||
// the serialization is the USVString from which the value was constructed.
|
// the serialization is the USVString from which the value was constructed.
|
||||||
return m_constructed_from_string.value();
|
return m_constructed_from_string.value();
|
||||||
}
|
}
|
||||||
// FIXME: otherwise, if the value was constructed using an IDL constructor
|
// otherwise, if the value was constructed using an IDL constructor
|
||||||
{
|
{
|
||||||
// the serialization is specified in the sections below.
|
// the serialization is specified in the sections below.
|
||||||
|
// NB: This is handled by subclasses overriding this to_string() method.
|
||||||
}
|
}
|
||||||
// FIXME: otherwise, if the value was extracted from the CSSOM
|
// FIXME: otherwise, if the value was extracted from the CSSOM
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,13 +20,16 @@ public:
|
||||||
|
|
||||||
virtual ~CSSStyleValue() override = default;
|
virtual ~CSSStyleValue() override = default;
|
||||||
|
|
||||||
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
|
||||||
virtual String to_string() const;
|
virtual String to_string() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit CSSStyleValue(JS::Realm&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit CSSStyleValue(JS::Realm&, String associated_property, String constructed_from_string);
|
explicit CSSStyleValue(JS::Realm&, String associated_property, String constructed_from_string);
|
||||||
|
|
||||||
virtual void initialize(JS::Realm&) override;
|
|
||||||
|
|
||||||
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssstylevalue-associatedproperty-slot
|
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssstylevalue-associatedproperty-slot
|
||||||
Optional<String> m_associated_property;
|
Optional<String> m_associated_property;
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,7 @@ class CSSGroupingRule;
|
||||||
class CSSImportRule;
|
class CSSImportRule;
|
||||||
class CSSKeyframeRule;
|
class CSSKeyframeRule;
|
||||||
class CSSKeyframesRule;
|
class CSSKeyframesRule;
|
||||||
|
class CSSKeywordValue;
|
||||||
class CSSLayerBlockRule;
|
class CSSLayerBlockRule;
|
||||||
class CSSLayerStatementRule;
|
class CSSLayerStatementRule;
|
||||||
class CSSMarginRule;
|
class CSSMarginRule;
|
||||||
|
|
|
@ -32,6 +32,7 @@ libweb_js_bindings(CSS/CSSGroupingRule)
|
||||||
libweb_js_bindings(CSS/CSSImportRule)
|
libweb_js_bindings(CSS/CSSImportRule)
|
||||||
libweb_js_bindings(CSS/CSSKeyframeRule)
|
libweb_js_bindings(CSS/CSSKeyframeRule)
|
||||||
libweb_js_bindings(CSS/CSSKeyframesRule)
|
libweb_js_bindings(CSS/CSSKeyframesRule)
|
||||||
|
libweb_js_bindings(CSS/CSSKeywordValue)
|
||||||
libweb_js_bindings(CSS/CSSLayerBlockRule)
|
libweb_js_bindings(CSS/CSSLayerBlockRule)
|
||||||
libweb_js_bindings(CSS/CSSLayerStatementRule)
|
libweb_js_bindings(CSS/CSSLayerStatementRule)
|
||||||
libweb_js_bindings(CSS/CSSMarginRule)
|
libweb_js_bindings(CSS/CSSMarginRule)
|
||||||
|
|
|
@ -54,6 +54,7 @@ static bool is_platform_object(Type const& type)
|
||||||
"Credential"sv,
|
"Credential"sv,
|
||||||
"CredentialsContainer"sv,
|
"CredentialsContainer"sv,
|
||||||
"CryptoKey"sv,
|
"CryptoKey"sv,
|
||||||
|
"CSSKeywordValue"sv,
|
||||||
"CSSStyleValue"sv,
|
"CSSStyleValue"sv,
|
||||||
"CustomStateSet"sv,
|
"CustomStateSet"sv,
|
||||||
"DataTransfer"sv,
|
"DataTransfer"sv,
|
||||||
|
|
|
@ -45,6 +45,7 @@ CSSGroupingRule
|
||||||
CSSImportRule
|
CSSImportRule
|
||||||
CSSKeyframeRule
|
CSSKeyframeRule
|
||||||
CSSKeyframesRule
|
CSSKeyframesRule
|
||||||
|
CSSKeywordValue
|
||||||
CSSLayerBlockRule
|
CSSLayerBlockRule
|
||||||
CSSLayerStatementRule
|
CSSLayerStatementRule
|
||||||
CSSMarginRule
|
CSSMarginRule
|
||||||
|
|
|
@ -2,8 +2,9 @@ Harness status: OK
|
||||||
|
|
||||||
Found 4 tests
|
Found 4 tests
|
||||||
|
|
||||||
4 Fail
|
2 Pass
|
||||||
Fail CSSKeywordValue constructed from IDL serializes correctly
|
2 Fail
|
||||||
Fail CSSKeywordValue constructed from IDL serializes to escaped strings
|
Pass CSSKeywordValue constructed from IDL serializes correctly
|
||||||
|
Pass CSSKeywordValue constructed from IDL serializes to escaped strings
|
||||||
Fail CSSKeywordValue from DOMString modified through "value" setter serializes correctly
|
Fail CSSKeywordValue from DOMString modified through "value" setter serializes correctly
|
||||||
Fail CSSKeywordValue from CSSOM modified through "value" setter serializes correctly
|
Fail CSSKeywordValue from CSSOM modified through "value" setter serializes correctly
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Constructing CSSKeywordValue with an empty string throws a TypeError
|
Pass Constructing CSSKeywordValue with an empty string throws a TypeError
|
|
@ -2,10 +2,10 @@ Harness status: OK
|
||||||
|
|
||||||
Found 6 tests
|
Found 6 tests
|
||||||
|
|
||||||
6 Fail
|
6 Pass
|
||||||
Fail CSSKeywordValue.value can be updated to a CSS wide keyword
|
Pass CSSKeywordValue.value can be updated to a CSS wide keyword
|
||||||
Fail CSSKeywordValue.value can be updated to a CSS keyword
|
Pass CSSKeywordValue.value can be updated to a CSS keyword
|
||||||
Fail CSSKeywordValue.value can be updated to an unsupported CSS keyword
|
Pass CSSKeywordValue.value can be updated to an unsupported CSS keyword
|
||||||
Fail CSSKeywordValue.value can be updated to a string containing multiple tokens
|
Pass CSSKeywordValue.value can be updated to a string containing multiple tokens
|
||||||
Fail CSSKeywordValue.value can be updated to a unicode string
|
Pass CSSKeywordValue.value can be updated to a unicode string
|
||||||
Fail Updating CSSKeywordValue.value with an empty string throws a TypeError
|
Pass Updating CSSKeywordValue.value with an empty string throws a TypeError
|
|
@ -2,9 +2,9 @@ Harness status: OK
|
||||||
|
|
||||||
Found 5 tests
|
Found 5 tests
|
||||||
|
|
||||||
5 Fail
|
5 Pass
|
||||||
Fail CSSKeywordValue can be constructed from a CSS wide keyword
|
Pass CSSKeywordValue can be constructed from a CSS wide keyword
|
||||||
Fail CSSKeywordValue can be constructed from a CSS keyword
|
Pass CSSKeywordValue can be constructed from a CSS keyword
|
||||||
Fail CSSKeywordValue can be constructed from an unsupported CSS keyword
|
Pass CSSKeywordValue can be constructed from an unsupported CSS keyword
|
||||||
Fail CSSKeywordValue can be constructed from a string containing multiple tokens
|
Pass CSSKeywordValue can be constructed from a string containing multiple tokens
|
||||||
Fail CSSKeywordValue can be constructed from a unicode string
|
Pass CSSKeywordValue can be constructed from a unicode string
|
Loading…
Add table
Add a link
Reference in a new issue