mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb: Make CSS::ComputedProperties GC-allocated
This commit is contained in:
parent
c1cad8fa0e
commit
74469a0c1f
Notes:
github-actions[bot]
2024-12-22 09:13:42 +00:00
Author: https://github.com/awesomekling
Commit: 74469a0c1f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2995
138 changed files with 337 additions and 339 deletions
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {};
|
||||
|
|
|
@ -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 box’s 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue