LibWeb: Make CSS::ComputedProperties GC-allocated

This commit is contained in:
Andreas Kling 2024-12-20 16:35:12 +01:00 committed by Andreas Kling
commit 74469a0c1f
Notes: github-actions[bot] 2024-12-22 09:13:42 +00:00
138 changed files with 337 additions and 339 deletions

View file

@ -8,6 +8,7 @@
#include <AK/NonnullRawPtr.h>
#include <AK/TypeCasts.h>
#include <LibCore/DirIterator.h>
#include <LibGC/CellAllocator.h>
#include <LibWeb/CSS/Clip.h>
#include <LibWeb/CSS/ComputedProperties.h>
#include <LibWeb/CSS/StyleValues/AngleStyleValue.h>
@ -42,91 +43,89 @@
namespace Web::CSS {
NonnullRefPtr<ComputedProperties::Data> ComputedProperties::Data::clone() const
GC_DEFINE_ALLOCATOR(ComputedProperties);
ComputedProperties::ComputedProperties() = default;
ComputedProperties::~ComputedProperties() = default;
void ComputedProperties::visit_edges(Visitor& visitor)
{
auto clone = adopt_ref(*new ComputedProperties::Data);
clone->m_animation_name_source = m_animation_name_source;
clone->m_transition_property_source = m_transition_property_source;
clone->m_property_values = m_property_values;
clone->m_property_important = m_property_important;
clone->m_property_inherited = m_property_inherited;
clone->m_animated_property_values = m_animated_property_values;
clone->m_math_depth = m_math_depth;
clone->m_font_list = m_font_list;
clone->m_line_height = m_line_height;
return clone;
Base::visit_edges(visitor);
visitor.visit(m_animation_name_source);
visitor.visit(m_transition_property_source);
}
bool ComputedProperties::is_property_important(CSS::PropertyID property_id) const
{
size_t n = to_underlying(property_id);
return m_data->m_property_important[n / 8] & (1 << (n % 8));
return m_property_important[n / 8] & (1 << (n % 8));
}
void ComputedProperties::set_property_important(CSS::PropertyID property_id, Important important)
{
size_t n = to_underlying(property_id);
if (important == Important::Yes)
m_data->m_property_important[n / 8] |= (1 << (n % 8));
m_property_important[n / 8] |= (1 << (n % 8));
else
m_data->m_property_important[n / 8] &= ~(1 << (n % 8));
m_property_important[n / 8] &= ~(1 << (n % 8));
}
bool ComputedProperties::is_property_inherited(CSS::PropertyID property_id) const
{
size_t n = to_underlying(property_id);
return m_data->m_property_inherited[n / 8] & (1 << (n % 8));
return m_property_inherited[n / 8] & (1 << (n % 8));
}
void ComputedProperties::set_property_inherited(CSS::PropertyID property_id, Inherited inherited)
{
size_t n = to_underlying(property_id);
if (inherited == Inherited::Yes)
m_data->m_property_inherited[n / 8] |= (1 << (n % 8));
m_property_inherited[n / 8] |= (1 << (n % 8));
else
m_data->m_property_inherited[n / 8] &= ~(1 << (n % 8));
m_property_inherited[n / 8] &= ~(1 << (n % 8));
}
void ComputedProperties::set_property(CSS::PropertyID id, NonnullRefPtr<CSSStyleValue const> value, Inherited inherited, Important important)
{
m_data->m_property_values[to_underlying(id)] = move(value);
m_property_values[to_underlying(id)] = move(value);
set_property_important(id, important);
set_property_inherited(id, inherited);
}
void ComputedProperties::revert_property(CSS::PropertyID id, ComputedProperties const& style_for_revert)
{
m_data->m_property_values[to_underlying(id)] = style_for_revert.m_data->m_property_values[to_underlying(id)];
m_property_values[to_underlying(id)] = style_for_revert.m_property_values[to_underlying(id)];
set_property_important(id, style_for_revert.is_property_important(id) ? Important::Yes : Important::No);
set_property_inherited(id, style_for_revert.is_property_inherited(id) ? Inherited::Yes : Inherited::No);
}
void ComputedProperties::set_animated_property(CSS::PropertyID id, NonnullRefPtr<CSSStyleValue const> value)
{
m_data->m_animated_property_values.set(id, move(value));
m_animated_property_values.set(id, move(value));
}
void ComputedProperties::reset_animated_properties()
{
m_data->m_animated_property_values.clear();
m_animated_property_values.clear();
}
CSSStyleValue const& ComputedProperties::property(CSS::PropertyID property_id, WithAnimationsApplied return_animated_value) const
{
if (return_animated_value == WithAnimationsApplied::Yes) {
if (auto animated_value = m_data->m_animated_property_values.get(property_id); animated_value.has_value())
if (auto animated_value = m_animated_property_values.get(property_id); animated_value.has_value())
return *animated_value.value();
}
// By the time we call this method, all properties have values assigned.
return *m_data->m_property_values[to_underlying(property_id)];
return *m_property_values[to_underlying(property_id)];
}
CSSStyleValue const* ComputedProperties::maybe_null_property(CSS::PropertyID property_id) const
{
if (auto animated_value = m_data->m_animated_property_values.get(property_id); animated_value.has_value())
if (auto animated_value = m_animated_property_values.get(property_id); animated_value.has_value())
return animated_value.value();
return m_data->m_property_values[to_underlying(property_id)];
return m_property_values[to_underlying(property_id)];
}
Variant<LengthPercentage, NormalGap> ComputedProperties::gap_value(CSS::PropertyID id) const
@ -270,7 +269,7 @@ CSSPixels ComputedProperties::compute_line_height(CSSPixelRect const& viewport_r
auto resolved = line_height.as_calculated().resolve_number();
if (!resolved.has_value()) {
dbgln("FIXME: Failed to resolve calc() line-height (number): {}", line_height.as_calculated().to_string(CSSStyleValue::SerializationMode::Normal));
return CSSPixels::nearest_value_for(m_data->m_font_list->first().pixel_metrics().line_spacing());
return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing());
}
return Length(resolved.value(), Length::Type::Em).to_px(viewport_rect, font_metrics, root_font_metrics);
}
@ -278,7 +277,7 @@ CSSPixels ComputedProperties::compute_line_height(CSSPixelRect const& viewport_r
auto resolved = line_height.as_calculated().resolve_length(Length::ResolutionContext { viewport_rect, font_metrics, root_font_metrics });
if (!resolved.has_value()) {
dbgln("FIXME: Failed to resolve calc() line-height: {}", line_height.as_calculated().to_string(CSSStyleValue::SerializationMode::Normal));
return CSSPixels::nearest_value_for(m_data->m_font_list->first().pixel_metrics().line_spacing());
return CSSPixels::nearest_value_for(m_font_list->first().pixel_metrics().line_spacing());
}
return resolved->to_px(viewport_rect, font_metrics, root_font_metrics);
}
@ -740,12 +739,12 @@ Optional<CSS::Positioning> ComputedProperties::position() const
bool ComputedProperties::operator==(ComputedProperties const& other) const
{
if (m_data->m_property_values.size() != other.m_data->m_property_values.size())
if (m_property_values.size() != other.m_property_values.size())
return false;
for (size_t i = 0; i < m_data->m_property_values.size(); ++i) {
auto const& my_style = m_data->m_property_values[i];
auto const& other_style = other.m_data->m_property_values[i];
for (size_t i = 0; i < m_property_values.size(); ++i) {
auto const& my_style = m_property_values[i];
auto const& other_style = other.m_property_values[i];
if (!my_style) {
if (other_style)
return false;
@ -1421,7 +1420,7 @@ Color ComputedProperties::stop_color() const
void ComputedProperties::set_math_depth(int math_depth)
{
m_data->m_math_depth = math_depth;
m_math_depth = math_depth;
// Make our children inherit our computed value, not our specified value.
set_property(PropertyID::MathDepth, MathDepthStyleValue::create_integer(IntegerStyleValue::create(math_depth)));
}

View file

@ -8,10 +8,12 @@
#include <AK/HashMap.h>
#include <AK/NonnullRefPtr.h>
#include <LibGC/CellAllocator.h>
#include <LibGC/Ptr.h>
#include <LibGfx/Font/Font.h>
#include <LibGfx/FontCascadeList.h>
#include <LibGfx/Forward.h>
#include <LibJS/Heap/Cell.h>
#include <LibWeb/CSS/ComputedValues.h>
#include <LibWeb/CSS/LengthBox.h>
#include <LibWeb/CSS/PropertyID.h>
@ -19,41 +21,21 @@
namespace Web::CSS {
class ComputedProperties {
class ComputedProperties final : public JS::Cell {
GC_CELL(ComputedProperties, JS::Cell);
GC_DECLARE_ALLOCATOR(ComputedProperties);
public:
static constexpr size_t number_of_properties = to_underlying(CSS::last_property_id) + 1;
private:
struct Data : public RefCounted<Data> {
friend class StyleComputer;
NonnullRefPtr<Data> clone() const;
// FIXME: These need protection from GC!
GC::Ptr<CSS::CSSStyleDeclaration const> m_animation_name_source;
GC::Ptr<CSS::CSSStyleDeclaration const> m_transition_property_source;
Array<RefPtr<CSSStyleValue const>, number_of_properties> m_property_values;
Array<u8, ceil_div(number_of_properties, 8uz)> m_property_important {};
Array<u8, ceil_div(number_of_properties, 8uz)> m_property_inherited {};
HashMap<CSS::PropertyID, NonnullRefPtr<CSSStyleValue const>> m_animated_property_values;
int m_math_depth { InitialValues::math_depth() };
mutable RefPtr<Gfx::FontCascadeList> m_font_list;
Optional<CSSPixels> m_line_height;
};
public:
ComputedProperties() = default;
virtual ~ComputedProperties() override;
template<typename Callback>
inline void for_each_property(Callback callback) const
{
for (size_t i = 0; i < m_data->m_property_values.size(); ++i) {
if (m_data->m_property_values[i])
callback((CSS::PropertyID)i, *m_data->m_property_values[i]);
for (size_t i = 0; i < m_property_values.size(); ++i) {
if (m_property_values[i])
callback((CSS::PropertyID)i, *m_property_values[i]);
}
}
@ -62,7 +44,7 @@ public:
Yes
};
HashMap<CSS::PropertyID, NonnullRefPtr<CSSStyleValue const>> const& animated_property_values() const { return m_data->m_animated_property_values; }
HashMap<CSS::PropertyID, NonnullRefPtr<CSSStyleValue const>> const& animated_property_values() const { return m_animated_property_values; }
void reset_animated_properties();
bool is_property_important(CSS::PropertyID property_id) const;
@ -80,11 +62,11 @@ public:
CSSStyleValue const* maybe_null_property(CSS::PropertyID) const;
void revert_property(CSS::PropertyID, ComputedProperties const& style_for_revert);
GC::Ptr<CSS::CSSStyleDeclaration const> animation_name_source() const { return m_data->m_animation_name_source; }
void set_animation_name_source(GC::Ptr<CSS::CSSStyleDeclaration const> declaration) { m_data->m_animation_name_source = declaration; }
GC::Ptr<CSS::CSSStyleDeclaration const> animation_name_source() const { return m_animation_name_source; }
void set_animation_name_source(GC::Ptr<CSS::CSSStyleDeclaration const> declaration) { m_animation_name_source = declaration; }
GC::Ptr<CSS::CSSStyleDeclaration const> transition_property_source() const { return m_data->m_transition_property_source; }
void set_transition_property_source(GC::Ptr<CSS::CSSStyleDeclaration const> declaration) { m_data->m_transition_property_source = declaration; }
GC::Ptr<CSS::CSSStyleDeclaration const> transition_property_source() const { return m_transition_property_source; }
void set_transition_property_source(GC::Ptr<CSS::CSSStyleDeclaration const> declaration) { m_transition_property_source = declaration; }
CSS::Size size_value(CSS::PropertyID) const;
[[nodiscard]] Variant<LengthPercentage, NormalGap> gap_value(CSS::PropertyID) const;
@ -196,23 +178,23 @@ public:
Optional<CSS::FillRule> fill_rule() const;
Optional<CSS::ClipRule> clip_rule() const;
Gfx::Font const& first_available_computed_font() const { return m_data->m_font_list->first(); }
Gfx::Font const& first_available_computed_font() const { return m_font_list->first(); }
Gfx::FontCascadeList const& computed_font_list() const
{
VERIFY(m_data->m_font_list);
return *m_data->m_font_list;
VERIFY(m_font_list);
return *m_font_list;
}
void set_computed_font_list(NonnullRefPtr<Gfx::FontCascadeList> font_list) const
{
m_data->m_font_list = move(font_list);
m_font_list = move(font_list);
}
[[nodiscard]] CSSPixels compute_line_height(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const;
[[nodiscard]] CSSPixels line_height() const { return *m_data->m_line_height; }
void set_line_height(Badge<StyleComputer> const&, CSSPixels line_height) { m_data->m_line_height = line_height; }
[[nodiscard]] CSSPixels line_height() const { return *m_line_height; }
void set_line_height(Badge<StyleComputer> const&, CSSPixels line_height) { m_line_height = line_height; }
bool operator==(ComputedProperties const&) const;
@ -220,7 +202,7 @@ public:
Optional<int> z_index() const;
void set_math_depth(int math_depth);
int math_depth() const { return m_data->m_math_depth; }
int math_depth() const { return m_math_depth; }
QuotesData quotes() const;
Vector<CounterData> counter_data(PropertyID) const;
@ -234,10 +216,26 @@ public:
private:
friend class StyleComputer;
ComputedProperties();
virtual void visit_edges(Visitor&) override;
Optional<CSS::Overflow> overflow(CSS::PropertyID) const;
Vector<CSS::ShadowData> shadow(CSS::PropertyID, Layout::Node const&) const;
AK::CopyOnWrite<ComputedProperties::Data> m_data;
GC::Ptr<CSS::CSSStyleDeclaration const> m_animation_name_source;
GC::Ptr<CSS::CSSStyleDeclaration const> m_transition_property_source;
Array<RefPtr<CSSStyleValue const>, number_of_properties> m_property_values;
Array<u8, ceil_div(number_of_properties, 8uz)> m_property_important {};
Array<u8, ceil_div(number_of_properties, 8uz)> m_property_inherited {};
HashMap<CSS::PropertyID, NonnullRefPtr<CSSStyleValue const>> m_animated_property_values;
int m_math_depth { InitialValues::math_depth() };
mutable RefPtr<Gfx::FontCascadeList> m_font_list;
Optional<CSSPixels> m_line_height;
};
}

View file

@ -196,8 +196,8 @@ RefPtr<CSSStyleValue const> ResolvedCSSStyleDeclaration::style_value_for_propert
auto get_computed_value = [this](PropertyID property_id) -> auto const& {
if (m_pseudo_element.has_value())
return m_element->pseudo_element_computed_css_values(m_pseudo_element.value())->property(property_id);
return m_element->computed_css_values()->property(property_id);
return m_element->pseudo_element_computed_properties(m_pseudo_element.value())->property(property_id);
return m_element->computed_properties()->property(property_id);
};
// A limited number of properties have special rules for producing their "resolved value".
@ -554,7 +554,7 @@ Optional<StyleProperty> ResolvedCSSStyleDeclaration::property(PropertyID propert
auto style = m_element->document().style_computer().compute_style(const_cast<DOM::Element&>(*m_element), m_pseudo_element);
// FIXME: This is a stopgap until we implement shorthand -> longhand conversion.
auto const* value = style.maybe_null_property(property_id);
auto const* value = style->maybe_null_property(property_id);
if (!value) {
dbgln("FIXME: ResolvedCSSStyleDeclaration::property(property_id={:#x}) No value for property ID in newly computed style case.", to_underlying(property_id));
return {};

View file

@ -1215,7 +1215,7 @@ static void compute_transitioned_properties(ComputedProperties const& style, DOM
auto const source_declaration = style.transition_property_source();
if (!source_declaration)
return;
if (!element.computed_css_values().has_value())
if (!element.computed_properties())
return;
if (source_declaration == element.cached_transition_property_source())
return;
@ -1590,16 +1590,16 @@ NonnullRefPtr<CSSStyleValue const> StyleComputer::get_inherit_value(CSS::Propert
{
auto* parent_element = element_to_inherit_style_from(element, pseudo_element);
if (!parent_element || !parent_element->computed_css_values().has_value())
if (!parent_element || !parent_element->computed_properties())
return property_initial_value(property_id);
return parent_element->computed_css_values()->property(property_id);
return parent_element->computed_properties()->property(property_id);
}
void StyleComputer::compute_defaulted_property_value(ComputedProperties& style, DOM::Element const* element, CSS::PropertyID property_id, Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
{
// FIXME: If we don't know the correct initial value for a property, we fall back to `initial`.
auto& value_slot = style.m_data->m_property_values[to_underlying(property_id)];
auto& value_slot = style.m_property_values[to_underlying(property_id)];
if (!value_slot) {
if (is_inherited_property(property_id)) {
style.set_property(
@ -1780,14 +1780,14 @@ RefPtr<Gfx::FontCascadeList const> StyleComputer::compute_font_for_style_values(
CSSPixels font_size_in_px = 16;
Gfx::FontPixelMetrics font_pixel_metrics;
if (parent_element && parent_element->computed_css_values().has_value())
font_pixel_metrics = parent_element->computed_css_values()->first_available_computed_font().pixel_metrics();
if (parent_element && parent_element->computed_properties())
font_pixel_metrics = parent_element->computed_properties()->first_available_computed_font().pixel_metrics();
else
font_pixel_metrics = Platform::FontPlugin::the().default_font().pixel_metrics();
auto parent_font_size = [&]() -> CSSPixels {
if (!parent_element || !parent_element->computed_css_values().has_value())
if (!parent_element || !parent_element->computed_properties())
return font_size_in_px;
auto const& value = parent_element->computed_css_values()->property(CSS::PropertyID::FontSize);
auto const& value = parent_element->computed_properties()->property(CSS::PropertyID::FontSize);
if (value.is_length()) {
auto length = value.as_length().length();
if (length.is_absolute() || length.is_relative()) {
@ -1836,8 +1836,8 @@ RefPtr<Gfx::FontCascadeList const> StyleComputer::compute_font_for_style_values(
// If the specified value font-size is math then the computed value of font-size is obtained by multiplying
// the inherited value of font-size by a nonzero scale factor calculated by the following procedure:
// 1. Let A be the inherited math-depth value, B the computed math-depth value, C be 0.71 and S be 1.0
int inherited_math_depth = parent_element && parent_element->computed_css_values().has_value()
? parent_element->computed_css_values()->math_depth()
int inherited_math_depth = parent_element && parent_element->computed_properties()
? parent_element->computed_properties()->math_depth()
: InitialValues::math_depth();
int computed_math_depth = math_depth;
auto size_ratio = 0.71;
@ -1876,8 +1876,8 @@ RefPtr<Gfx::FontCascadeList const> StyleComputer::compute_font_for_style_values(
// larger may compute the font size to the next entry in the table,
// and smaller may compute the font size to the previous entry in the table.
if (keyword == Keyword::Smaller || keyword == Keyword::Larger) {
if (parent_element && parent_element->computed_css_values().has_value()) {
font_size_in_px = CSSPixels::nearest_value_for(parent_element->computed_css_values()->first_available_computed_font().pixel_metrics().size);
if (parent_element && parent_element->computed_properties()) {
font_size_in_px = CSSPixels::nearest_value_for(parent_element->computed_properties()->first_available_computed_font().pixel_metrics().size);
}
}
font_size_in_px *= get_absolute_size_mapping(keyword);
@ -2077,7 +2077,7 @@ void StyleComputer::absolutize_values(ComputedProperties& style) const
// We have to resolve them right away, so that the *computed* line-height is ready for inheritance.
// We can't simply absolutize *all* percentage values against the font size,
// because most percentages are relative to containing block metrics.
auto& line_height_value_slot = style.m_data->m_property_values[to_underlying(CSS::PropertyID::LineHeight)];
auto& line_height_value_slot = style.m_property_values[to_underlying(CSS::PropertyID::LineHeight)];
if (line_height_value_slot && line_height_value_slot->is_percentage()) {
line_height_value_slot = LengthStyleValue::create(
Length::make_px(CSSPixels::nearest_value_for(font_size * static_cast<double>(line_height_value_slot->as_percentage().percentage().as_fraction()))));
@ -2090,8 +2090,8 @@ void StyleComputer::absolutize_values(ComputedProperties& style) const
if (line_height_value_slot && line_height_value_slot->is_length())
line_height_value_slot = LengthStyleValue::create(Length::make_px(line_height));
for (size_t i = 0; i < style.m_data->m_property_values.size(); ++i) {
auto& value_slot = style.m_data->m_property_values[i];
for (size_t i = 0; i < style.m_property_values.size(); ++i) {
auto& value_slot = style.m_property_values[i];
if (!value_slot)
continue;
value_slot = value_slot->absolutized(viewport_rect(), font_metrics, m_root_element_font_metrics);
@ -2145,8 +2145,8 @@ static BoxTypeTransformation required_box_type_transformation(ComputedProperties
auto const* parent = pseudo_element.has_value() ? &element : element.parent_element();
// A parent with a grid or flex display value blockifies the boxs display type. [CSS-GRID-1] [CSS-FLEXBOX-1]
if (parent && parent->computed_css_values().has_value()) {
auto const& parent_display = parent->computed_css_values()->display();
if (parent && parent->computed_properties()) {
auto const& parent_display = parent->computed_properties()->display();
if (parent_display.is_grid_inside() || parent_display.is_flex_inside())
return BoxTypeTransformation::Blockify;
}
@ -2244,30 +2244,30 @@ void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM:
style.set_property(CSS::PropertyID::Display, DisplayStyleValue::create(new_display));
}
ComputedProperties StyleComputer::create_document_style() const
GC::Ref<ComputedProperties> StyleComputer::create_document_style() const
{
ComputedProperties style = {};
auto style = document().heap().allocate<CSS::ComputedProperties>();
compute_math_depth(style, nullptr, {});
compute_font(style, nullptr, {});
compute_defaulted_values(style, nullptr, {});
absolutize_values(style);
style.set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().width())));
style.set_property(CSS::PropertyID::Height, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().height())));
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Block)));
style->set_property(CSS::PropertyID::Width, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().width())));
style->set_property(CSS::PropertyID::Height, CSS::LengthStyleValue::create(CSS::Length::make_px(viewport_rect().height())));
style->set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Block)));
return style;
}
ComputedProperties StyleComputer::compute_style(DOM::Element& element, Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
GC::Ref<ComputedProperties> StyleComputer::compute_style(DOM::Element& element, Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
{
return compute_style_impl(element, move(pseudo_element), ComputeStyleMode::Normal).release_value();
return *compute_style_impl(element, move(pseudo_element), ComputeStyleMode::Normal);
}
Optional<ComputedProperties> StyleComputer::compute_pseudo_element_style_if_needed(DOM::Element& element, Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
GC::Ptr<ComputedProperties> StyleComputer::compute_pseudo_element_style_if_needed(DOM::Element& element, Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
{
return compute_style_impl(element, move(pseudo_element), ComputeStyleMode::CreatePseudoElementStyleIfNeeded);
}
Optional<ComputedProperties> StyleComputer::compute_style_impl(DOM::Element& element, Optional<CSS::Selector::PseudoElement::Type> pseudo_element, ComputeStyleMode mode) const
GC::Ptr<ComputedProperties> StyleComputer::compute_style_impl(DOM::Element& element, Optional<CSS::Selector::PseudoElement::Type> pseudo_element, ComputeStyleMode mode) const
{
build_rule_cache_if_needed();
@ -2279,7 +2279,7 @@ Optional<ComputedProperties> StyleComputer::compute_style_impl(DOM::Element& ele
// Merge back inline styles
if (auto inline_style = element.inline_style()) {
for (auto const& property : inline_style->properties())
style.set_property(property.property_id, property.value);
style->set_property(property.property_id, property.value);
}
return style;
}
@ -2324,9 +2324,9 @@ Optional<ComputedProperties> StyleComputer::compute_style_impl(DOM::Element& ele
return compute_properties(element, pseudo_element, cascaded_properties);
}
ComputedProperties StyleComputer::compute_properties(DOM::Element& element, Optional<Selector::PseudoElement::Type> pseudo_element, CascadedProperties& cascaded_properties) const
GC::Ref<ComputedProperties> StyleComputer::compute_properties(DOM::Element& element, Optional<Selector::PseudoElement::Type> pseudo_element, CascadedProperties& cascaded_properties) const
{
ComputedProperties computed_style;
auto computed_style = document().heap().allocate<CSS::ComputedProperties>();
for (auto i = to_underlying(first_longhand_property_id); i <= to_underlying(last_longhand_property_id); ++i) {
auto property_id = static_cast<CSS::PropertyID>(i);
@ -2334,7 +2334,7 @@ ComputedProperties StyleComputer::compute_properties(DOM::Element& element, Opti
if ((!value && is_inherited_property(property_id))
|| (value && value->is_inherit())) {
if (auto inheritance_parent = element_to_inherit_style_from(&element, pseudo_element)) {
value = inheritance_parent->computed_css_values()->property(property_id);
value = inheritance_parent->computed_properties()->property(property_id);
} else {
value = property_initial_value(property_id);
}
@ -2350,19 +2350,19 @@ ComputedProperties StyleComputer::compute_properties(DOM::Element& element, Opti
value = CSSKeywordValue::create(Keyword::Initial);
}
computed_style.set_property(property_id, value.release_nonnull());
computed_style->set_property(property_id, value.release_nonnull());
if (property_id == PropertyID::AnimationName) {
computed_style.set_animation_name_source(cascaded_properties.property_source(property_id));
computed_style->set_animation_name_source(cascaded_properties.property_source(property_id));
}
if (property_id == PropertyID::TransitionProperty) {
computed_style.set_transition_property_source(cascaded_properties.property_source(property_id));
computed_style->set_transition_property_source(cascaded_properties.property_source(property_id));
}
}
// Animation declarations [css-animations-2]
auto animation_name = [&]() -> Optional<String> {
auto const animation_name = computed_style.maybe_null_property(PropertyID::AnimationName);
auto const animation_name = computed_style->maybe_null_property(PropertyID::AnimationName);
if (!animation_name)
return OptionalNone {};
if (animation_name->is_string())
@ -2371,7 +2371,7 @@ ComputedProperties StyleComputer::compute_properties(DOM::Element& element, Opti
}();
if (animation_name.has_value()) {
if (auto source_declaration = computed_style.animation_name_source()) {
if (auto source_declaration = computed_style->animation_name_source()) {
auto& realm = element.realm();
if (source_declaration != element.cached_animation_name_source(pseudo_element)) {
@ -2450,7 +2450,7 @@ ComputedProperties StyleComputer::compute_properties(DOM::Element& element, Opti
// 9. Transition declarations [css-transitions-1]
// Theoretically this should be part of the cascade, but it works with computed values, which we don't have until now.
compute_transitioned_properties(computed_style, element, pseudo_element);
if (auto previous_style = element.computed_css_values(); previous_style.has_value()) {
if (auto previous_style = element.computed_properties(); previous_style) {
start_needed_transitions(*previous_style, computed_style, element, pseudo_element);
}
@ -2912,7 +2912,7 @@ void StyleComputer::compute_math_depth(ComputedProperties& style, DOM::Element c
auto inherited_math_depth = [&]() {
if (!element || !element->parent_element())
return InitialValues::math_depth();
return element->parent_element()->computed_css_values()->math_depth();
return element->parent_element()->computed_properties()->math_depth();
};
auto const& value = style.property(CSS::PropertyID::MathDepth);

View file

@ -141,10 +141,10 @@ public:
void push_ancestor(DOM::Element const&);
void pop_ancestor(DOM::Element const&);
ComputedProperties create_document_style() const;
[[nodiscard]] GC::Ref<ComputedProperties> create_document_style() const;
ComputedProperties compute_style(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type> = {}) const;
Optional<ComputedProperties> compute_pseudo_element_style_if_needed(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>) const;
[[nodiscard]] GC::Ref<ComputedProperties> compute_style(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type> = {}) const;
[[nodiscard]] GC::Ptr<ComputedProperties> compute_pseudo_element_style_if_needed(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>) const;
Vector<MatchingRule> collect_matching_rules(DOM::Element const&, CascadeOrigin, Optional<CSS::Selector::PseudoElement::Type>, FlyString const& qualified_layer_name = {}) const;
@ -173,7 +173,7 @@ public:
size_t number_of_css_font_faces_with_loading_in_progress() const;
[[nodiscard]] ComputedProperties compute_properties(DOM::Element&, Optional<Selector::PseudoElement::Type>, CascadedProperties&) const;
[[nodiscard]] GC::Ref<ComputedProperties> compute_properties(DOM::Element&, Optional<Selector::PseudoElement::Type>, CascadedProperties&) const;
private:
enum class ComputeStyleMode {
@ -185,7 +185,7 @@ private:
[[nodiscard]] bool should_reject_with_ancestor_filter(Selector const&) const;
Optional<ComputedProperties> compute_style_impl(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>, ComputeStyleMode) const;
[[nodiscard]] GC::Ptr<ComputedProperties> compute_style_impl(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>, ComputeStyleMode) const;
[[nodiscard]] GC::Ref<CascadedProperties> compute_cascaded_values(DOM::Element&, Optional<CSS::Selector::PseudoElement::Type>, bool& did_match_any_pseudo_element_rules, ComputeStyleMode) const;
static RefPtr<Gfx::FontCascadeList const> find_matching_font_weight_ascending(Vector<MatchingFontCandidate> const& candidates, int target_weight, float font_size_in_pt, bool inclusive);
static RefPtr<Gfx::FontCascadeList const> find_matching_font_weight_descending(Vector<MatchingFontCandidate> const& candidates, int target_weight, float font_size_in_pt, bool inclusive);