LibWeb/CSS: Implement ElementCSSInlineStyle.attributeStyleMap

Again, this isn't yet very usable, but it does appease some tests.
This commit is contained in:
Sam Atkins 2025-08-11 16:27:42 +01:00
commit 911274a84d
Notes: github-actions[bot] 2025-08-13 09:15:44 +00:00
10 changed files with 43 additions and 21 deletions

View file

@ -1,6 +1,10 @@
#import <CSS/CSSStyleProperties.idl> #import <CSS/CSSStyleProperties.idl>
#import <CSS/StylePropertyMap.idl>
// https://w3c.github.io/csswg-drafts/cssom/#elementcssinlinestyle // https://w3c.github.io/csswg-drafts/cssom/#elementcssinlinestyle
interface mixin ElementCSSInlineStyle { interface mixin ElementCSSInlineStyle {
[SameObject, PutForwards=cssText, ImplementedAs=style_for_bindings] readonly attribute CSSStyleProperties style; [SameObject, PutForwards=cssText, ImplementedAs=style_for_bindings] readonly attribute CSSStyleProperties style;
// https://drafts.css-houdini.org/css-typed-om-1/#declared-stylepropertymap-objects
[SameObject] readonly attribute StylePropertyMap attributeStyleMap;
}; };

View file

@ -26,6 +26,7 @@
#include <LibWeb/CSS/PropertyID.h> #include <LibWeb/CSS/PropertyID.h>
#include <LibWeb/CSS/SelectorEngine.h> #include <LibWeb/CSS/SelectorEngine.h>
#include <LibWeb/CSS/StyleComputer.h> #include <LibWeb/CSS/StyleComputer.h>
#include <LibWeb/CSS/StylePropertyMap.h>
#include <LibWeb/CSS/StyleValues/DisplayStyleValue.h> #include <LibWeb/CSS/StyleValues/DisplayStyleValue.h>
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h> #include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h> #include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
@ -123,6 +124,7 @@ void Element::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_cascaded_properties); visitor.visit(m_cascaded_properties);
visitor.visit(m_computed_properties); visitor.visit(m_computed_properties);
visitor.visit(m_computed_style_map_cache); visitor.visit(m_computed_style_map_cache);
visitor.visit(m_attribute_style_map);
if (m_pseudo_element_data) { if (m_pseudo_element_data) {
for (auto& pseudo_element : *m_pseudo_element_data) { for (auto& pseudo_element : *m_pseudo_element_data) {
visitor.visit(pseudo_element.value); visitor.visit(pseudo_element.value);
@ -1109,9 +1111,18 @@ GC::Ref<CSS::CSSStyleProperties> Element::style_for_bindings()
return *m_inline_style; return *m_inline_style;
} }
GC::Ref<CSS::StylePropertyMap> Element::attribute_style_map()
{
if (!m_attribute_style_map)
m_attribute_style_map = CSS::StylePropertyMap::create(realm(), style_for_bindings());
return *m_attribute_style_map;
}
void Element::set_inline_style(GC::Ptr<CSS::CSSStyleProperties> style) void Element::set_inline_style(GC::Ptr<CSS::CSSStyleProperties> style)
{ {
m_inline_style = style; m_inline_style = style;
if (m_attribute_style_map)
m_attribute_style_map = nullptr;
set_needs_style_update(true); set_needs_style_update(true);
} }

View file

@ -226,6 +226,7 @@ public:
void set_inline_style(GC::Ptr<CSS::CSSStyleProperties>); void set_inline_style(GC::Ptr<CSS::CSSStyleProperties>);
GC::Ref<CSS::CSSStyleProperties> style_for_bindings(); GC::Ref<CSS::CSSStyleProperties> style_for_bindings();
GC::Ref<CSS::StylePropertyMap> attribute_style_map();
CSS::StyleSheetList& document_or_shadow_root_style_sheets(); CSS::StyleSheetList& document_or_shadow_root_style_sheets();
ElementByIdMap& document_or_shadow_root_element_by_id_map(); ElementByIdMap& document_or_shadow_root_element_by_id_map();
@ -566,6 +567,7 @@ private:
GC::Ptr<NamedNodeMap> m_attributes; GC::Ptr<NamedNodeMap> m_attributes;
GC::Ptr<CSS::CSSStyleProperties> m_inline_style; GC::Ptr<CSS::CSSStyleProperties> m_inline_style;
GC::Ptr<CSS::StylePropertyMap> m_attribute_style_map;
GC::Ptr<DOMTokenList> m_class_list; GC::Ptr<DOMTokenList> m_class_list;
GC::Ptr<ShadowRoot> m_shadow_root; GC::Ptr<ShadowRoot> m_shadow_root;

View file

@ -2,7 +2,8 @@ Harness status: OK
Found 3 tests Found 3 tests
3 Fail 1 Pass
Fail Deleting a shorthand property not in the inline style is a no-op 2 Fail
Pass Deleting a shorthand property not in the inline style is a no-op
Fail Deleting a shorthand property in the inline style removes both it and its longhands Fail Deleting a shorthand property in the inline style removes both it and its longhands
Fail Deleting a longhand property in the inline style removes both it and its shorthand Fail Deleting a longhand property in the inline style removes both it and its shorthand

View file

@ -2,8 +2,9 @@ Harness status: OK
Found 5 tests Found 5 tests
5 Fail 1 Pass
Fail Deleting a property not in the inline style is a no-op 4 Fail
Pass Deleting a property not in the inline style is a no-op
Fail Deleting a property in the inline style removes it from the inline style Fail Deleting a property in the inline style removes it from the inline style
Fail Deleting a custom property in the inline style removes it from the inline style Fail Deleting a custom property in the inline style removes it from the inline style
Fail Deleting a list-valued property in the inline style removes it from the inline style Fail Deleting a list-valued property in the inline style removes it from the inline style

View file

@ -2,7 +2,8 @@ Harness status: OK
Found 3 tests Found 3 tests
3 Fail 2 Pass
1 Fail
Fail Getting an shorthand property set explicitly in inline style returns a base CSSStyleValue Fail Getting an shorthand property set explicitly in inline style returns a base CSSStyleValue
Fail Getting a shorthand property that is partially set in inline style returns null Pass Getting a shorthand property that is partially set in inline style returns null
Fail Getting an attributeStyleMap shorthand property from an element without a style attribute Pass Getting an attributeStyleMap shorthand property from an element without a style attribute

View file

@ -2,9 +2,10 @@ Harness status: OK
Found 7 tests Found 7 tests
7 Fail 2 Pass
Fail Getting a custom property not in the inline style returns undefined 5 Fail
Fail Getting a valid property not in the inline style returns undefined Pass Getting a custom property not in the inline style returns undefined
Pass Getting a valid property not in the inline style returns undefined
Fail Getting a valid property from inline style returns the correct entry Fail Getting a valid property from inline style returns the correct entry
Fail Getting a valid custom property from inline style returns the correct entry Fail Getting a valid custom property from inline style returns the correct entry
Fail Getting a list-valued property from inline style returns only the first value Fail Getting a list-valued property from inline style returns only the first value

View file

@ -2,6 +2,7 @@ Harness status: OK
Found 2 tests Found 2 tests
2 Fail 1 Pass
1 Fail
Fail StylePropertyMap.getAll() with a shorthand property set explicitly in inline style returns a base CSSStyleValue Fail StylePropertyMap.getAll() with a shorthand property set explicitly in inline style returns a base CSSStyleValue
Fail StylePropertyMap.getAll() with a shorthand property that is partially in inline style returns empty list Pass StylePropertyMap.getAll() with a shorthand property that is partially in inline style returns empty list

View file

@ -2,11 +2,11 @@ Harness status: OK
Found 7 tests Found 7 tests
1 Pass 3 Pass
6 Fail 4 Fail
Pass Calling StylePropertyMap.getAll with an unsupported property throws a TypeError Pass Calling StylePropertyMap.getAll with an unsupported property throws a TypeError
Fail Calling StylePropertyMap.getAll with a property not in the property model returns an empty list Pass Calling StylePropertyMap.getAll with a property not in the property model returns an empty list
Fail Calling StylePropertyMap.getAll with a custom property not in the property model returns an empty list Pass Calling StylePropertyMap.getAll with a custom property not in the property model returns an empty list
Fail Calling StylePropertyMap.getAll with a valid property returns a single element list with the correct entry Fail Calling StylePropertyMap.getAll with a valid property returns a single element list with the correct entry
Fail StylePropertyMap.getAll is case-insensitive Fail StylePropertyMap.getAll is case-insensitive
Fail Calling StylePropertyMap.getAll with a valid custom property returns a single element list with the correct entry Fail Calling StylePropertyMap.getAll with a valid custom property returns a single element list with the correct entry

View file

@ -2,12 +2,12 @@ Harness status: OK
Found 8 tests Found 8 tests
1 Pass 4 Pass
7 Fail 4 Fail
Pass Calling StylePropertyMap.has with an unsupported property throws a TypeError Pass Calling StylePropertyMap.has with an unsupported property throws a TypeError
Fail Calling StylePropertyMap.has with a property not in the property model returns false Pass Calling StylePropertyMap.has with a property not in the property model returns false
Fail Calling StylePropertyMap.has with a custom property not in the property model returns false Pass Calling StylePropertyMap.has with a custom property not in the property model returns false
Fail Calling StylePropertyMap.has with a valid property in mixed case returns false Pass Calling StylePropertyMap.has with a valid property in mixed case returns false
Fail Calling StylePropertyMap.has with a valid property returns true Fail Calling StylePropertyMap.has with a valid property returns true
Fail Calling StylePropertyMap.has with a valid property in mixed case returns true Fail Calling StylePropertyMap.has with a valid property in mixed case returns true
Fail Calling StylePropertyMap.has with a valid custom property returns true Fail Calling StylePropertyMap.has with a valid custom property returns true