mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
A @keyframes rule scoped to a shadow root was not reliably reached from an animated slotted light-DOM element: the keyframes lookup walked the element's own root first, then fell back to the document, but slotted elements can pick up animation-name from a ::slotted(...) rule that lives in an ancestor shadow root rather than in the element's own tree. Track the shadow-root scope that supplied each winning cascaded declaration, and use that scope to resolve the matching @keyframes when processing animation definitions. A shared constructable stylesheet can be adopted into several scopes at once, so the declaration object alone is too weak as a key; the per-entry shadow-root pointer disambiguates which adoption actually contributed. Also refresh running CSS animations' keyframe sets when style is recomputed. Previously only the first animation creation path set a keyframe set, so an existing animation never picked up newly inserted @keyframes rules.
61 lines
2.1 KiB
C++
61 lines
2.1 KiB
C++
/*
|
|
* Copyright (c) 2024, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/FixedBitmap.h>
|
|
#include <LibGC/CellAllocator.h>
|
|
#include <LibJS/Heap/Cell.h>
|
|
#include <LibWeb/CSS/CascadeOrigin.h>
|
|
#include <LibWeb/CSS/PropertyID.h>
|
|
#include <LibWeb/CSS/Selector.h>
|
|
#include <LibWeb/CSS/StyleProperty.h>
|
|
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
|
#include <LibWeb/Forward.h>
|
|
|
|
namespace Web::CSS {
|
|
|
|
class CascadedProperties final : public JS::Cell {
|
|
GC_CELL(CascadedProperties, JS::Cell);
|
|
GC_DECLARE_ALLOCATOR(CascadedProperties);
|
|
|
|
public:
|
|
virtual ~CascadedProperties() override;
|
|
|
|
[[nodiscard]] RefPtr<StyleValue const> property(PropertyID) const;
|
|
[[nodiscard]] PropertyID property_with_higher_priority(PropertyID, PropertyID) const;
|
|
[[nodiscard]] GC::Ptr<CSSStyleDeclaration const> property_source(PropertyID) const;
|
|
[[nodiscard]] GC::Ptr<DOM::ShadowRoot const> property_source_shadow_root(PropertyID) const;
|
|
[[nodiscard]] Optional<StyleProperty> style_property(PropertyID) const;
|
|
|
|
void set_property(PropertyID, NonnullRefPtr<StyleValue const>, Important, CascadeOrigin, Optional<FlyString> layer_name, GC::Ptr<CSS::CSSStyleDeclaration const> source, GC::Ptr<DOM::ShadowRoot const> source_shadow_root);
|
|
void set_property_from_presentational_hint(PropertyID, NonnullRefPtr<StyleValue const>);
|
|
|
|
void revert_property(PropertyID, Important, CascadeOrigin);
|
|
void revert_layer_property(PropertyID, Important, Optional<FlyString> layer_name);
|
|
|
|
void resolve_unresolved_properties(DOM::AbstractElement);
|
|
|
|
private:
|
|
CascadedProperties();
|
|
|
|
virtual void visit_edges(Visitor&) override;
|
|
|
|
struct Entry {
|
|
StyleProperty property;
|
|
size_t cascade_index { 0 };
|
|
CascadeOrigin origin;
|
|
Optional<FlyString> layer_name;
|
|
GC::Ptr<CSS::CSSStyleDeclaration const> source;
|
|
GC::Ptr<DOM::ShadowRoot const> source_shadow_root;
|
|
};
|
|
HashMap<PropertyID, Vector<Entry>> m_properties;
|
|
size_t m_next_cascade_index { 0 };
|
|
AK::FixedBitmap<to_underlying(last_longhand_property_id) + 1> m_contained_properties_cache { false };
|
|
};
|
|
|
|
}
|