LibWeb: Implement CSSFontFeatureValuesMap
This will be used within `CSSFontFeatureValuesRule`
This commit is contained in:
parent
3f8da74e63
commit
fcdc05a4ee
8 changed files with 138 additions and 10 deletions
|
|
@ -112,6 +112,7 @@ set(SOURCES
|
|||
CSS/CSSDescriptors.cpp
|
||||
CSS/CSSFontFaceDescriptors.cpp
|
||||
CSS/CSSFontFaceRule.cpp
|
||||
CSS/CSSFontFeatureValuesMap.cpp
|
||||
CSS/CSSGroupingRule.cpp
|
||||
CSS/CSSImageValue.cpp
|
||||
CSS/CSSImportRule.cpp
|
||||
|
|
|
|||
80
Libraries/LibWeb/CSS/CSSFontFeatureValuesMap.cpp
Normal file
80
Libraries/LibWeb/CSS/CSSFontFeatureValuesMap.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Callum Law <callumlaw1709@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "CSSFontFeatureValuesMap.h"
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(CSSFontFeatureValuesMap);
|
||||
|
||||
GC::Ref<CSSFontFeatureValuesMap> CSSFontFeatureValuesMap::create(JS::Realm& realm, size_t max_value_count)
|
||||
{
|
||||
return realm.create<CSSFontFeatureValuesMap>(realm, max_value_count);
|
||||
}
|
||||
|
||||
CSSFontFeatureValuesMap::CSSFontFeatureValuesMap(JS::Realm& realm, size_t max_value_count)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_map_entries(JS::Map::create(realm))
|
||||
, m_max_value_count(max_value_count)
|
||||
{
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> CSSFontFeatureValuesMap::set(String const& feature_value_name, Variant<u32, Vector<u32>> const& values)
|
||||
{
|
||||
// https://drafts.csswg.org/css-fonts-4/#cssfontfeaturevaluesmap
|
||||
// The CSSFontFeatureValuesMap interface uses the default map class methods but the set method has different
|
||||
// behavior. It takes a sequence of unsigned integers and associates it with a given featureValueName. The method
|
||||
// behaves the same as the default map class method except that
|
||||
|
||||
// a single unsigned long value is treated as a sequence of a single value.
|
||||
Vector<u32> value_vector = values.visit(
|
||||
[](u32 single_value) { return Vector<u32> { single_value }; },
|
||||
[](Vector<u32> value_vector) { return value_vector; });
|
||||
|
||||
// The method throws an exception if an invalid number of values is passed in.
|
||||
if (value_vector.is_empty())
|
||||
return WebIDL::InvalidAccessError::create(realm(), "CSSFontFeatureValuesMap.set requires at least one value."_utf16);
|
||||
|
||||
// If the associated feature value block only allows a limited number of values, the set method throws an
|
||||
// InvalidAccessError exception when the input sequence to set contains more than the limited number of values. See
|
||||
// the description of multi-valued feature value definitions for details on the maximum number of values allowed for
|
||||
// a given type of feature value block.
|
||||
if (value_vector.size() > m_max_value_count)
|
||||
return WebIDL::InvalidAccessError::create(realm(), Utf16String::formatted("CSSFontFeatureValuesMap.set only allows a maximum of {} values for the associated feature", m_max_value_count));
|
||||
|
||||
Vector<JS::Value> wrapped_values;
|
||||
wrapped_values.ensure_capacity(value_vector.size());
|
||||
|
||||
for (auto const& value : value_vector)
|
||||
wrapped_values.append(JS::Value { value });
|
||||
|
||||
m_map_entries->map_set(JS::PrimitiveString::create(vm(), feature_value_name), JS::Array::create_from(realm(), wrapped_values.span()));
|
||||
// TODO: Clear the relevant caches
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void CSSFontFeatureValuesMap::on_map_modified_from_js(Badge<Bindings::CSSFontFeatureValuesMapPrototype>)
|
||||
{
|
||||
// TODO: Clear the relevant caches
|
||||
}
|
||||
|
||||
void CSSFontFeatureValuesMap::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSFontFeatureValuesMap);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void CSSFontFeatureValuesMap::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_map_entries);
|
||||
}
|
||||
|
||||
}
|
||||
39
Libraries/LibWeb/CSS/CSSFontFeatureValuesMap.h
Normal file
39
Libraries/LibWeb/CSS/CSSFontFeatureValuesMap.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Callum Law <callumlaw1709@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/MapIterator.h>
|
||||
#include <LibWeb/Bindings/CSSFontFeatureValuesMapPrototype.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
class CSSFontFeatureValuesMap final : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(CSSFontFeatureValuesMap, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(CSSFontFeatureValuesMap);
|
||||
|
||||
public:
|
||||
static GC::Ref<CSSFontFeatureValuesMap> create(JS::Realm&, size_t max_value_count);
|
||||
|
||||
virtual GC::Ref<JS::Map> map_entries() { return m_map_entries; }
|
||||
|
||||
WebIDL::ExceptionOr<void> set(String const& feature_value_name, Variant<u32, Vector<u32>> const& values);
|
||||
|
||||
void on_map_modified_from_js(Badge<Bindings::CSSFontFeatureValuesMapPrototype>);
|
||||
|
||||
private:
|
||||
CSSFontFeatureValuesMap(JS::Realm&, size_t max_value_count);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
GC::Ref<JS::Map> m_map_entries;
|
||||
size_t m_max_value_count;
|
||||
};
|
||||
|
||||
}
|
||||
5
Libraries/LibWeb/CSS/CSSFontFeatureValuesMap.idl
Normal file
5
Libraries/LibWeb/CSS/CSSFontFeatureValuesMap.idl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[Exposed=Window]
|
||||
interface CSSFontFeatureValuesMap {
|
||||
maplike<CSSOMString, sequence<unsigned long>>;
|
||||
undefined set(CSSOMString featureValueName, (unsigned long or sequence<unsigned long>) values);
|
||||
};
|
||||
|
|
@ -246,6 +246,7 @@ class CSSCounterStyleRule;
|
|||
class CSSDescriptors;
|
||||
class CSSFontFaceDescriptors;
|
||||
class CSSFontFaceRule;
|
||||
class CSSFontFeatureValuesMap;
|
||||
class CSSGroupingRule;
|
||||
class CSSImageValue;
|
||||
class CSSImportRule;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ libweb_js_bindings(CSS/CSSConditionRule)
|
|||
libweb_js_bindings(CSS/CSSCounterStyleRule)
|
||||
libweb_js_bindings(CSS/CSSFontFaceDescriptors)
|
||||
libweb_js_bindings(CSS/CSSFontFaceRule)
|
||||
libweb_js_bindings(CSS/CSSFontFeatureValuesMap)
|
||||
libweb_js_bindings(CSS/CSSGroupingRule)
|
||||
libweb_js_bindings(CSS/CSSImageValue)
|
||||
libweb_js_bindings(CSS/CSSImportRule)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ CSSConditionRule
|
|||
CSSCounterStyleRule
|
||||
CSSFontFaceDescriptors
|
||||
CSSFontFaceRule
|
||||
CSSFontFeatureValuesMap
|
||||
CSSGroupingRule
|
||||
CSSImageValue
|
||||
CSSImportRule
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
|||
|
||||
Found 97 tests
|
||||
|
||||
48 Pass
|
||||
49 Fail
|
||||
56 Pass
|
||||
41 Fail
|
||||
Pass idl_test setup
|
||||
Pass idl_test validation
|
||||
Pass Partial interface CSSRule: original interface defined
|
||||
|
|
@ -80,14 +80,14 @@ Fail CSSFontFeatureValuesRule interface: attribute swash
|
|||
Fail CSSFontFeatureValuesRule interface: attribute characterVariant
|
||||
Fail CSSFontFeatureValuesRule interface: attribute styleset
|
||||
Fail CSSFontFeatureValuesRule interface: attribute historicalForms
|
||||
Fail CSSFontFeatureValuesMap interface: existence and properties of interface object
|
||||
Fail CSSFontFeatureValuesMap interface object length
|
||||
Fail CSSFontFeatureValuesMap interface object name
|
||||
Fail CSSFontFeatureValuesMap interface: existence and properties of interface prototype object
|
||||
Fail CSSFontFeatureValuesMap interface: existence and properties of interface prototype object's "constructor" property
|
||||
Fail CSSFontFeatureValuesMap interface: existence and properties of interface prototype object's @@unscopables property
|
||||
Fail CSSFontFeatureValuesMap interface: maplike<CSSOMString, [object Object]>
|
||||
Fail CSSFontFeatureValuesMap interface: operation set(CSSOMString, (unsigned long or sequence<unsigned long>))
|
||||
Pass CSSFontFeatureValuesMap interface: existence and properties of interface object
|
||||
Pass CSSFontFeatureValuesMap interface object length
|
||||
Pass CSSFontFeatureValuesMap interface object name
|
||||
Pass CSSFontFeatureValuesMap interface: existence and properties of interface prototype object
|
||||
Pass CSSFontFeatureValuesMap interface: existence and properties of interface prototype object's "constructor" property
|
||||
Pass CSSFontFeatureValuesMap interface: existence and properties of interface prototype object's @@unscopables property
|
||||
Pass CSSFontFeatureValuesMap interface: maplike<CSSOMString, [object Object]>
|
||||
Pass CSSFontFeatureValuesMap interface: operation set(CSSOMString, (unsigned long or sequence<unsigned long>))
|
||||
Fail CSSFontPaletteValuesRule interface: existence and properties of interface object
|
||||
Fail CSSFontPaletteValuesRule interface object length
|
||||
Fail CSSFontPaletteValuesRule interface object name
|
||||
|
|
|
|||
Loading…
Reference in a new issue