Files
ladybird/Libraries/LibWeb/CSS/CascadedProperties.h
Tim Ledbetter d1fc4b4234 LibWeb: Route presentational hints through the CSS cascade
Previously, presentational hints bypassed the regular cascade pipeline
and wrote directly into `CascadedProperties` under
`CascadeOrigin::Author`. That meant `var()` substitution and the
invalid-at-computed-value-time fallback had to be duplicated in a
separate per-element pass, which in practice missed the IACVT step and
could leave a `GuaranteedInvalidStyleValue` in the cascaded
properties. This caused a crash in downstream code that assumed the
value had been resolved.

This introduces an `AuthorPresentationalHint` cascade origin and feeds
them through the cascade as normal declarations. This means that
`var()` resolution now happens in only one place.
2026-04-30 19:50:28 +01:00

58 lines
2.0 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 revert_property(PropertyID, Important, CascadeOrigin);
void revert_layer_property(PropertyID, Important, Optional<FlyString> layer_name);
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 };
};
}